The implementation of the function is to read the key information, if the key is not generated, the program sleep in the Read function, using the poll mechanism, you can not exit the program automatically quit.
The following program is to read the key information, if there is no key information in the 5000ms, you exit.
First the application executes the poll function
The Sys_poll in kernel
Do_sys_poll
Init_poll_funcptr-->do_poll
Do_poll
for (;;)
{
if (DO_POLLFD (PFD,PT))
{
count++; If the driver's poll returns a value other than 0, then count++
To suspend a process to sleep in a queue
Pt=null;}
if (count | |!*timeout | | signal_pending (current))
Break If count is not 0 timeout, there is a signal waiting to be processed
}
__timeout = Schedule_timeout (__time_out); Hibernate the next time it executes to the above judgment, it will time out
Driver Code:
#include <linux/sched.h>#include<linux/signal.h>#include<linux/spinlock.h>#include<linux/errno.h>#include<linux/random.h>#include<linux/poll.h>#include<linux/init.h>#include<linux/slab.h>#include<linux/module.h>#include<linux/wait.h>#include<linux/mutex.h>#include<linux/io.h>#include<asm/irq.h>#include<linux/irq.h>#include<linux/fs.h>#include<asm/arch/regs-gpio.h>#include<linux/interrupt.h>#include<linux/poll.h>Static struct class*key_class;//Create ClassStatic structClass_device *key_class_devs;//Create a device for a classstructpin_desc{unsignedintpin; unsignedintKey_val;};structPin_desc pins_desc[4] ={{s3c2410_gpf0,0x01}, {S3C2410_GPF2,0X02}, {s3c2410_gpg3,0X03}, {s3c2410_gpg11,0x04},};unsignedCharkeyvals=0;Static volatile intEv_press =0;StaticDeclare_wait_queue_head (BUTTON_WAITQ);StaticIrqreturn_t KEYS_IRQ (intIrqvoid*dev_id) { structPin_desc *pindesc = (structPIN_DESC *) dev_id; unsignedintPinval; Pinval= S3c2410_gpio_getpin (pindesc->pin); if(pinval) {keyvals= pindesc->key_val|0x80; } Else{keyvals= pindesc->Key_val; } ev_press=1; Wake_up_interruptible (&BUTTON_WAITQ); returnirq_handled;}intKey_open (structInode *inode,structFile *FP) {REQUEST_IRQ (irq_eint0, KEYS_IRQ, Irqt_bothedge,"Key2", &pins_desc[0]); REQUEST_IRQ (Irq_eint2, KEYS_IRQ, Irqt_bothedge,"Key3", &pins_desc[1]); REQUEST_IRQ (irq_eint11, KEYS_IRQ, Irqt_bothedge,"Key4", &pins_desc[2]); REQUEST_IRQ (irq_eint19, KEYS_IRQ, Irqt_bothedge,"Key5", &pins_desc[3]); return 0;} ssize_t Key_read (structFile *FP,Char__user *buff, size_t count, loff_t *OFFP) { if(Count! =1) { return-EINVAL; } wait_event_interruptible (button_waitq,ev_press); Copy_to_user (Buff,&keyvals,1); Ev_press=0; return 0;} ssize_t Key_write (structFile *FP,Const Char__user *buf, size_t count, loff_t *PPOs) {}intKey_close (structInode *inode,structFile *file) {FREE_IRQ (irq_eint0,&pins_desc[0]); FREE_IRQ (Irq_eint2,&pins_desc[1]); FREE_IRQ (irq_eint11,&pins_desc[2]); FREE_IRQ (irq_eint19,&pins_desc[3]);}StaticUnsignedintKey_poll (structFile *file,structPoll_table_struct *wait) {unsignedintMask =0; Poll_wait (file,&button_waitq,wait); if(ev_press) Mask|= pollin|Pollrdnorm; returnMask;}structFile_operations led_fops={. Owner=this_module,. Open=Key_open,. Write=key_write,. Read=key_read,. Release=Key_close,. Poll=Key_poll,};intMajor;Static intKey_init (void) {Major= Register_chrdev (0,"Key_drv", &led_fops); Key_class= Class_create (This_module,"Key_class"); Key_class_devs= Class_device_create (Key_class,null,mkdev (Major,0), NULL,"My_keys"); PRINTK ("Key Install module\n"); return 0;}Static voidKey_exit (void) {Unregister_chrdev (major,"Key_drv" ); Class_device_unregister (Key_class_devs); Class_destroy (Key_class); PRINTK ("Key Module exit\n");} Module_init (Key_init); Module_exit (Key_exit); Module_license ("GPL");
To apply the test code:
#include <stdio.h>#include<fcntl.h>#include<poll.h>intMain () {intFD; intret; structPOLLFD pfd[1]; unsignedCharKey_val; FD= Open ("/dev/my_keys", O_RDWR); if(fd<0) {printf ("Open failed\n"); return 0; } pfd[0].FD =FD; pfd[0].events =Pollin; while(1) {ret= Poll (PFD,1, the); //If the button is not pressed within 5000ms, this automatically exits //Read (fd, &key_val,1); if(ret==0) printf ("Time out\n"); Else{Read (FD,&key_val,1); printf ("key:%x\n", Key_val); } }}
Sd
Linux Embedded Drive Learning Path (12) key-driven-poll mechanism