您的位置 首页 厂商

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

经过前面的配置,S5PV210开发已经可以成功进入Linux控制台了,那么,有了这个环境就可以开始学习Linux驱动的编写和测试了。学习Linux设备驱

经过前面的装备,S5PV210开发现已能够成功进入Linux控制台了,那么,有了这个环境就能够开端学习Linux驱动的编写和测试了。学习Linux设备驱动,通常是从字符设备驱动开端。我写的第一个驱动程序是Led的,其实也便是了解下字符设备驱动的根本结构,本文以中止方法的按键驱动为例,简略的介绍下字符设备驱动程序。

一 按键驱动程序的简略完成

下面是根据中止和音讯的按键驱动程序,其作业原理是:当应用程序读取键值时,会调用按键驱动程序的read函数,而咱们完成的read函数检测完读取长度后没有直接读取键值而是等候按键音讯,假如没有按键,程序会进入休眠状况,这样能够节约很多的CPU,而当咱们按键时硬件会发生中止,程序主动进入中止处理函数,在中止处理函数中,驱动程序读取键值存入全局变量并激活read函数中等候的音讯,应用程序被敏捷唤醒并经过read函数读取键值,如此,完成了获取键值的作业。下面是源码,比较简略,也就不多说了。

源码:

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12. staticdev_tdevno;
  13. staticstructcdevcdev;
  14. staticstructclass*buttons_class;
  15. staticstructdevice*buttons_device;
  16. staticwait_queue_head_tbutton_waitq;
  17. staticvolatileintpressed=0;
  18. staticunsignedcharkey_val;
  19. structkey_desc{
  20. unsignedintpin;
  21. unsignedcharvalue;
  22. };
  23. staticstructkey_desckey_descs[8]={
  24. [0]={
  25. .pin=S5PV210_GPH0(0),
  26. .value=0x00,
  27. },
  28. [1]={
  29. .pin=S5PV210_GPH0(1),
  30. .value=0x01,
  31. },
  32. [2]={
  33. .pin=S5PV210_GPH0(2),
  34. .value=0x02,
  35. },
  36. [3]={
  37. .pin=S5PV210_GPH0(3),
  38. .value=0x03,
  39. },
  40. [4]={
  41. .pin=S5PV210_GPH0(4),
  42. .value=0x04,
  43. },
  44. [5]={
  45. .pin=S5PV210_GPH0(5),
  46. .value=0x05,
  47. },
  48. [6]={
  49. .pin=S5PV210_GPH2(6),
  50. .value=0x06,
  51. },
  52. [7]={
  53. .pin=S5PV210_GPH2(7),
  54. .value=0x07,
  55. },
  56. };
  57. staticirqreturn_tbuttons_irq(intirq,void*dev_id){
  58. volatilestructkey_desc*key=(volatilestructkey_desc*)dev_id;
  59. if(gpio_get_value(key->pin)){
  60. key_val=key->value|0x80;
  61. }
  62. else{
  63. key_val=key->value;
  64. }
  65. pressed=1;
  66. wake_up_interruptible(&button_waitq);
  67. returnIRQ_RETVAL(IRQ_HANDLED);
  68. }
  69. staticintbuttons_open(structinode*inode,structfile*file){
  70. intret;
  71. ret=request_irq(IRQ_EINT(0),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key1″,&key_descs[0]);
  72. if(ret)
  73. returnret;
  74. ret=request_irq(IRQ_EINT(1),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key2″,&key_descs[1]);
  75. if(ret)
  76. returnret;
  77. ret=request_irq(IRQ_EINT(2),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key3″,&key_descs[2]);
  78. if(ret)
  79. returnret;
  80. ret=request_irq(IRQ_EINT(3),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key4″,&key_descs[3]);
  81. if(ret)
  82. returnret;
  83. ret=request_irq(IRQ_EINT(4),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key5″,&key_descs[4]);
  84. if(ret)
  85. returnret;
  86. ret=request_irq(IRQ_EINT(5),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key6″,&key_descs[5]);
  87. if(ret)
  88. returnret;
  89. ret=request_irq(IRQ_EINT(22),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key7″,&key_descs[6]);
  90. if(ret)
  91. returnret;
  92. ret=request_irq(IRQ_EINT(23),buttons_irq,IRQ_TYPE_EDGE_BOTH,”key8″,&key_descs[7]);
  93. if(ret)
  94. returnret;
  95. return0;
  96. }
  97. staticssize_tbuttons_read(structfile*file,char__user*data,size_tcount,loff_t*loff){
  98. if(count!=1){
  99. printk(KERN_ERR”Thedrivercanonlygiveonekeyvalueonce!”);
  100. return-ENOMEM;
  101. }
  102. wait_event_interruptible(button_waitq,pressed);
  103. pressed=0;
  104. if(copy_to_user(data,&key_val,1)){
  105. printk(KERN_ERR”Thedrivercannotcopythedatatouserarea!”);
  106. return-ENOMEM;
  107. }
  108. return0;
  109. }
  110. staticintbuttons_close(structinode*inode,structfile*file){
  111. free_irq(IRQ_EINT(0),&key_descs[0]);
  112. free_irq(IRQ_EINT(1),&key_descs[1]);
  113. free_irq(IRQ_EINT(2),&key_descs[2]);
  114. free_irq(IRQ_EINT(3),&key_descs[3]);
  115. free_irq(IRQ_EINT(4),&key_descs[4]);
  116. free_irq(IRQ_EINT(5),&key_descs[5]);
  117. free_irq(IRQ_EINT(22),&key_descs[6]);
  118. free_irq(IRQ_EINT(23),&key_descs[7]);
  119. return0;
  120. }
  121. structfile_operationsbuttons_ops={
  122. .open=buttons_open,
  123. .read=buttons_read,
  124. .release=buttons_close,
  125. };
  126. intbuttons_init(void){
  127. intret;
  128. cdev_init(&cdev,&buttons_ops);
  129. cdev.owner=THIS_MODULE;
  130. ret=alloc_chrdev_region(&devno,0,1,”buttons”);
  131. if(ret){
  132. printk(KERN_ERR”allocchardeviceregionfaild!”);
  133. returnret;
  134. }
  135. ret=cdev_add(&cdev,devno,1);
  136. if(ret){
  137. printk(KERN_ERR”addchardevicefaild!”);
  138. gotoadd_error;
  139. }
  140. buttons_class=class_create(THIS_MODULE,”buttonsdrv”);
  141. if(IS_ERR(buttons_class)){
  142. printk(KERN_ERR”createclasserror!”);
  143. gotoclass_error;
  144. }
  145. buttons_device=device_create(buttons_class,NULL,devno,NULL,”buttons”);
  146. if(IS_ERR(buttons_device)){
  147. printk(KERN_ERR”createbuttonsdeviceerror!”);
  148. gotodevice_error;
  149. }
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/256198.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部