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

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

时间:11-28 来源:互联网 点击:
经过前面的配置,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_ad

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

网站地图

Top