微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S5PV210(TQ210)学习笔记——按键驱动程序

S5PV210(TQ210)学习笔记——按键驱动程序

时间:11-28 来源:互联网 点击:

  1. d(&cdev,devno,1);
  2. if(ret){
  3. printk(KERN_ERR"addchardevicefaild!");
  4. gotoadd_error;
  5. }
  6. buttons_class=class_create(THIS_MODULE,"buttonsdrv");
  7. if(IS_ERR(buttons_class)){
  8. printk(KERN_ERR"createclasserror!");
  9. gotoclass_error;
  10. }
  11. buttons_device=device_create(buttons_class,NULL,devno,NULL,"buttons");
  12. if(IS_ERR(buttons_device)){
  13. printk(KERN_ERR"createbuttonsdeviceerror!");
  14. gotodevice_error;
  15. }
  16. init_waitqueue_head(&button_waitq);
  17. return0;
  18. device_error:
  19. class_destroy(buttons_class);
  20. class_error:
  21. cdev_del(&cdev);
  22. add_error:
  23. unregister_chrdev_region(devno,1);
  24. return-ENODEV;
  25. }
  26. voidbuttons_exit(void){
  27. device_destroy(buttons_class,devno);
  28. class_destroy(buttons_class);
  29. cdev_del(&cdev);
  30. unregister_chrdev_region(devno,1);
  31. }
  32. module_init(buttons_init);
  33. module_exit(buttons_exit);
  34. MODULE_LICENSE("GPL");

测试程序代码:

  1. #include
  2. #include
  3. intmain(){
  4. intfd=open("/dev/buttons",O_RDWR);
  5. if(fd<0){
  6. printf("openerror");;
  7. return0;
  8. }
  9. unsignedcharkey;
  10. while(1){
  11. read(fd,&key,1);
  12. printf("Thekey=%x",key);
  13. }
  14. close(fd);
  15. }

相比轮询方式的按键驱动程序,中断方式编写的按键驱动程序可以很大程度上节省CPU资源,因此,推荐使用中断方式。

二 支持POLL机制

上面这种方式实现的按键驱动程序有个弊端,如果我们不按键,应用程序将会永远阻塞在这里,幸运的是,linux内核提供了poll机制,可以设置超时等待时间,如果在这个时间内读取到键值则正常返回,反之则超时退出。使内核支持poll非常简单,为file_operations的poll成员提供poll处理函数即可。

使内核支持poll还需要以下几步:

添加poll头文件

  1. #include


编写poll处理函数:

  1. staticunsignedbuttons_poll(structfile*file,poll_table*wait){
  2. unsignedintmask=0;
  3. poll_wait(file,&button_waitq,wait);
  4. if(pressed)
  5. mask|=POLLIN|POLLRDNORM;
  6. returnmask;
  7. }

将poll处理函数添加给file_operations:

  1. .poll=buttons_poll,

这样,驱动程序就支持poll机制了。下面是poll方式的测试程序:

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. intmain(intargc,char**argv){
  7. intfd;
  8. unsignedcharkey_val;
  9. intret;
  10. structpollfdfds[1];
  11. fd=open("/dev/buttons",O_RDWR);
  12. if(fd<0){
  13. printf("cantopen!");
  14. }
  15. fds[0].fd=fd;
  16. fds[0].events=POLLIN;
  17. while(1){
  18. ret=poll(fds,1,5000);
  19. if(ret==0){
  20. printf("timeout");
  21. }
  22. else{
  23. read(fd,&key_val,1);
  24. printf("key_val=0x%x",key_val);
  25. }
  26. }
  27. return0;
  28. }

这样,应用程序可以限制时间,如果在一定时间内读取不到键值就可以做特殊处理,这种思想在网络通信中应用广泛。

三 支持异步机制

很多情况下,我们的程序在等待按键期间需要处理其它任务而不是在这里空等,这时,就需要采用异步模式了。所谓异步模式,实际上是采用消息机制(以本文的按键程序为例),即当驱动程序检测到按键后发送消息给应用程序,应用程序接收到消息后再去读取键值。与前面的两种模式相比,最大的不同在于异步方式是驱动告诉应用程序来读而不是应用程序主动去读。添加异步支持更加简单,首先是为file_operations注册fasync函数,函数内容如下:

  1. staticintbuttons_fasync(intfd,structfile*file,inton){
  2. returnfasync_helper(fd,file,on,&button_async);
  3. }

然后再buttons_read函数中添加一行代码,修改后的代码如下:

  1. staticssize_tbuttons_read(structfile*file,char__user*data,size_tcount,loff_t*loff){
  2. if(count!=1){
  3. printk(KERN_ERR"Thedrivercanonlygiveonekeyvalueonce!");
  4. return-ENOMEM;
  5. }
  6. wait_event_interruptible(button_waitq,pressed);
  7. pressed=0;
  8. if(copy_to_user(data,&key_val,1)){
  9. printk(KERN_ERR"Thedrivercannotcopythedatatouserarea!");
  10. return-ENOMEM;
  11. }
  12. return0;
  13. }

这样,驱动程序就支持异步获取键值了,为了测试效果,测试程序也需要修改,代码如下:

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. /*sixthdrvtest
  9. */
  10. intfd;
  11. voidmy_signal_fun(intsignum)
  12. {
  13. unsignedcharkey_val;
  14. read(fd,&key_val,1);
  15. printf("key_val:0x%x",key_val);
  16. }
  17. intmain(intargc,char**argv)
  18. {
  19. unsignedcharkey_val;
  20. intret;
  21. intOflags;
  22. signal(SIGIO,my_signal_fun);
  23. fd=open("/dev/buttons",O_RDWR|O_NONBLOCK);
  24. if(fd<0){
  25. printf("cantopen!");
  26. return-1;
  27. }
  28. fcntl(fd,F_SETOWN,getpid());
  29. Oflags=fcntl(fd,F_GETFL);
  30. fcntl(fd,F_SETFL,Oflags|FASYNC);
  31. intrest;
  32. while(1){
  33. printf("Hello");
  34. while(rest=sleep(50)){

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top