Programming the poll mechanism in Linux drivers

Source: Internet
Author: User
Tags volatile

#include <linux/module.h>
#include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h > #include <asm/irq.h> #include <linux/interrupt.h> #include <asm/uaccess.h> #include <asm/ arch/regs-gpio.h> #include <asm/hardware.h> #include <linux/poll.h>
/ * After loading mode, execute "cat/proc/devices" command to see the device name */#define DEVICE_NAME "Key_poll"
/ * Automatically create device node class */struct Class *key_poll_dev_class = null;struct Class_device *key_poll_dev_class_dev = NULL;
/* Used to specify the external interrupt pin used by the key and the interrupt trigger mode, name */*name;}; static struct Button_irq_desc Button_irqs [] = {{irq_eint19, irqf_trigger_falling, ' key_poll1 '},/* K1 */{Irq_eint One, irqf_trigger_falling, "Key_poll2"},/* K2 */{irq_eint2, irqf_trigger_falling, "Key_poll3"},/* K3 */{Irq_eint 0, irqf_trigger_falling, "KEY_POLL4"},/* K4 */};
/* The number of times the key was pressed (to be exact, the number of interrupts) */static volatile int press_cnt [] = {0, 0, 0, 0};
/* Wait queue: * When no keystrokes are pressed, if a process calls the Key_poll_dev_read function, * It will hibernate */static declare_wait_queue_head (BUTTON_WAITQ);
/ * Interrupt event flag, interrupt service program 1,key_poll_dev_read it to clear 0 */static volatile int ev_press = 0;static irqreturn_t buttons_        Interrupt (int IRQ, void *dev_id) {volatile int *press_cnt = (volatile int *) dev_id; *press_cnt = *press_cnt + 1;                /* Key count plus 1 */ev_press = 1;   /* Indicates that the interrupt has occurred */wake_up_interruptible (&BUTTON_WAITQ); /* Wake Hibernate process */return Irq_retval (irq_handled);}
static int Key_poll_dev_open (struct inode *inode, struct file *file) {int i;        int err; for (i = 0; i < sizeof (BUTTON_IRQS)/sizeof (Button_irqs[0]); i++)
    { //register interrupt handling function Err = REQUEST_IRQ (BUTTON_IRQS[I].IRQ, Buttons_interrupt, Button_irqs[i].flags, button        _irqs[i].name, (void *) &press_cnt[i]);    if (err) break; } if (err)
    //Release the registered interrupt i--;        for (; I >= 0; i--) Free_irq (BUTTON_IRQS[I].IRQ, (void *) &press_cnt[i]);    Return-ebusy; } return 0;}
//Release the registered interrupt FREE_IRQ (BUTTON_IRQS[I].IRQ, (void *) &press_cnt[i]); } return 0;}
/* Application to the device file/dev/buttons execute read (...) ,  * The Key_poll_dev_read function is called * /*if ev_press equals 0, hibernation*/* Executes here, ev_press equals 1, it is 0 *   / ev_press = 0;    / * Copy the key state to the user * /err = Copy_to_user (buff, (const void *) press_cnt, min (sizeof (PRESS_CNT), count)); memset (void *) press_cnt, 0, sizeof (press_cnt));
    return err? -efault:0;}
static int key_poll_dev_poll (struct file *file, poll_table *wait) {unsigned int mask = 0;/* void poll_wait (struct file *filp, wait_queue_head_t *queue, poll_table *wait);  typedef struct POLL_TABLE_STRUCT {  poll_queue_proc qproc;  unsigned long key;  } poll_table;  Poll_wait's role is to add the current process to the specified wait list wait (poll_table).  Note that this function is not to cause blocking, hehe, who gave it a name with wait, give us so much trouble. */Poll_wait (file, &AMP;BUTTON_WAITQ, wait);if (ev_press)Mask |= Pollin | Pollrdnorm;/*PollinNormal or priority with data-readablePollrdnormPlain Data readablePollrdbandPriority with data-readablePollpriHigh-priority data readablePolloutPlain data can be writtenPollwrnormPlain data can be writtenPollwrbandPriority with data writablePollerrError occurredPollhupOccurs pendingPollnvalThe description word is not an open file*/return mask;}/* This structure is the core of the character device driver * When an application operates a device file, the function called open, read, write, and so on, will eventually call the corresponding function in the structure.static struct File_operations Key_poll_dev_fops = {. Owner = This_module,/ * This is a macro that points to the __this_module variable created automatically when the module is compiled * /. open = Key_poll_dev_open,. Release = Key_poll_dev_close,. Read = Key_poll_dev_read,. Poll = Key_poll_dev_poll,};/ * * This function is called when the "insmod Key_poll_driver.ko" command is executed * /int key_poll_major = 0;int Key_poll_minor = 0;static int __init initialization_key_poll_dev (void) {/* Register character device driver * parameter main device number, device name, file_operations structure; * Thus, the main device number is associated with the specific file_operations structure, * operation of the main device is Key_poll_maj Or of a device file, the related member function in Key_poll_dev_fops is called * Key_poll_major can be set to 0, which indicates that the main device number is automatically assigned by the kernel * /PRINTK ("before register Major =%d\n", key_poll_major);if (key_poll_major)Register_chrdev (Key_poll_major, Device_name, &key_poll_dev_fops);ElseKey_poll_major = Register_chrdev (0, Device_name, &key_poll_dev_fops);PRINTK ("after register Major =%d\n", key_poll_major);/ * Automatically generate device node * /Key_poll_dev_class = Class_create (This_module, "key_poll_drv");Key_poll_dev_class_dev = class_device_create (Key_poll_dev_class, NULL, MKDEV (Key_poll_major, Key_poll_minor), NULL, " key_poll%d ", Key_poll_minor);PRINTK (device_name "initialized ok.\n");return 0;}/ * This function is called when the "rmmod Key_poll_dev.ko" command is executed * /static void __exit Cleanup_key_poll_dev (void) {/* Uninstall the driver */Unregister_chrdev (Key_poll_major, device_name);Class_device_unregister (Key_poll_dev_class_dev);Class_destroy (Key_poll_dev_class);PRINTK (device_name "cleanup ok.\n");}/* These two lines specify the driver's initialization function and unload function */Module_init (Initialization_key_poll_dev); Module_exit (Cleanup_key_poll_dev);/*insmod Pass * *Module_param (key_poll_major, int, s_irugo); Module_param (Key_poll_minor, int, s_irugo);/ * Some information that describes the driver is not required * /Module_author ("Lhbo");Driver author Module_description ("JZ2440 key_poll Driver");                          Some descriptive information module_license ("GPL"); Protocols to follow/*=========================== Asynchronous notification-driven test =========================*/#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include < poll.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main (int argc, char * *    argv) {int i;    int ret;    int FD;    int press_cnt[4]; struct POLLFD fds[1];FD = open ("/dev/key_poll", 0); Open the device if (FD < 0)
  {        printf ("Can ' t open/dev/key\n");      &N Bsp return-1;   }    FDS[0].FD = fd;< Span style= "White-space:pre" >  fds[0].events = pollin;      /*   this is an infinite loop, the process may hibernate in the Read function, and it returns   when a key is pressed     */   while (1)    
{int ret = poll (FDS, 1, 5000);  //5000ms 1 files  */  * After the above statement is executed, if there are no keystrokes within 5s, the process is blocked at poll in this 5s, and after 5s returns 0, otherwise poll immediately returns a non-0 value. *  /if (ret = = 0)
{printf ("Time out!\n"); }
Else
{/*   Read the number of times the button was pressed *  /
ret = Read (FD, press_cnt, sizeof (PRESS_CNT));  if (Ret < 0)
{printf ("Read err!\n");  continue;  }  / * Read successful print key count */for (i = 0; i < 4;  i++) printf ("k%d have been pressed%d Ti Mes!\n ", I+1, Press_cnt[i]); Close (FD);      return 0;  }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.