字符驱动之按键(四:poll机制)
1 采用之前的中断按键法,程序会一直在read函数中死循环。 2 使用了poll之后,在一段时间内如果有按键按下就会返回,如果没有按键按下等时间到再返回。 3 4 应用程序的open,read,write,poll分别对应了驱动程序的open,read,write和poll。 5 首先,增加fileoperation结构体。 6 7 static struct file_operations third_drv_fops = { 8 .owner = THIS_MODULE, 9 .open = third_drv_open, 10 .read = third_drv_read, 11 .write = third_drv_write, 12 .poll = third_drv_poll, 13 }; 14 15 copy的poll函数如下: 16 staitc unsigned mounts_poll(struct file *file,poll_table *wait) 17 { 18 struct proc_mounts *p = file->private_data; 19 struct mnt_namespace *ns = p->m.private; 20 unsigned res = 0; 21 22 poll_wait(file,&ns->poll,wait); 23 24 spin_lock(&vfsmount_lock); 25 if(p->event != ns->event) 26 { 27 p->event = ns->event; 28 res = POLLERR; 29 } 30 spin_unlock(&vfsmount_lock); 31 return res; 32 } 33 34 其中的核心部分为: 35 poll_wait(file,&ns->poll,wait); 36 37 38 static unsigned forth_drv_poll(struct file *file,poll_table *wait) 39 { 40 unsigned mask = 0; 41 poll_wait(file,&button_waitq,wait); //不会立刻进入休眠 42 43 if(ev_press) 44 mask |= POLLIN | POLLRDNORM; 45 } 46 47 系统调用poll时,它们对应的内核函数是sys_poll。 48 sys_poll核心是调用了do_sys_poll函数。 49 50 app: 调用poll函数 51 kernel: 调用sys_poll函数 52 do_sys_poll(ufds,nfds,&timeout_jiffies);//第三个参数是超时参数。 53 poll_initwait(&table); 54 do_poll(nfds,head,&table,timeout); 55 56 57 修改后的测试程序: 58 int main(int argc,char** argv) 59 { 60 int fd; 61 unsigned char key_val; 62 63 struct pollfd fds[1]; //需要检测的文件个数为一 64 65 fd = open("/dev/buttons",O_RDWR); 66 if(fd < 0) 67 printf("can't open buttons\n"); 68 //poll相关设置 69 fds[0].fd = fd; //打开的文件为fd 70 fds.[0].enents = POLLIN; //pollin表示有数据待读取 71 72 while(1) 73 { 74 ret = poll(fds,1,5000); //参数分别为fds(结构体),1为文件个数,5000为事件。 75 //返回值为0表示超时 76 if(ret == 0) 77 { 78 printf("timeout!\n"); 79 } 80 read(fd,&key_val,1); 81 printf("key_val = 0x%x\n",key_val); 82 } 83 }