新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S5PV210(TQ210)學(xué)習(xí)筆記——輸入子系統(tǒng)驅(qū)動(dòng)

S5PV210(TQ210)學(xué)習(xí)筆記——輸入子系統(tǒng)驅(qū)動(dòng)

作者: 時(shí)間:2016-11-28 來源:網(wǎng)絡(luò) 收藏
前面的文章簡單的講述了字符設(shè)備驅(qū)動(dòng)程序的編寫,用字符設(shè)備驅(qū)動(dòng)的方式實(shí)現(xiàn)了按鍵驅(qū)動(dòng),但是,出了我們的自己編寫的針對我們的這個(gè)驅(qū)動(dòng)程序的應(yīng)用程序之外,其他應(yīng)用程序都無法接收我們這個(gè)驅(qū)動(dòng)的鍵值輸入,為了讓所有應(yīng)用程序都可以接收我們的按鍵驅(qū)動(dòng)解析的鍵值,Linux內(nèi)核定義了“輸入子系統(tǒng)”的概念,也就是說,只要我們按照這個(gè)模型進(jìn)行驅(qū)動(dòng)開發(fā),并為其提供必須的接口函數(shù),那么,Linux內(nèi)核就可以正常來獲取我們的鍵盤值了。

輸入子系統(tǒng)的原理分析強(qiáng)烈推薦觀看韋東山老師的視頻講座,講的非常清楚,我這里是按照輸入子系統(tǒng)的方式實(shí)現(xiàn)的按鍵驅(qū)動(dòng),下面是源碼,放在這里做個(gè)備份:

本文引用地址:http://m.butianyuan.cn/article/201611/322808.htm
  1. #include
  2. #include
  3. #include
  4. #include
  5. #includeinterrupt.h>
  6. #include
  7. staticstructinput_dev*buttons_dev;
  8. staticstructtimer_listtimer;
  9. structbutton_desc*button_desc=NULL;
  10. structbutton_desc{
  11. char*name;
  12. unsignedintpin;
  13. unsignedintirq;
  14. unsignedintval;
  15. };
  16. staticstructbutton_descbuttons_desc[8]={
  17. [0]={
  18. .name="S1",
  19. .pin=S5PV210_GPH0(0),
  20. .irq=IRQ_EINT(0),
  21. .val=KEY_L,
  22. },
  23. [1]={
  24. .name="S2",
  25. .pin=S5PV210_GPH0(1),
  26. .irq=IRQ_EINT(1),
  27. .val=KEY_S,
  28. },
  29. [2]={
  30. .name="S3",
  31. .pin=S5PV210_GPH0(2),
  32. .irq=IRQ_EINT(2),
  33. .val=KEY_C,
  34. },
  35. [3]={
  36. .name="S4",
  37. .pin=S5PV210_GPH0(3),
  38. .irq=IRQ_EINT(3),
  39. .val=KEY_ENTER,
  40. },
  41. [4]={
  42. .name="S5",
  43. .pin=S5PV210_GPH0(4),
  44. .irq=IRQ_EINT(4),
  45. .val=KEY_LEFTCTRL,
  46. },
  47. [5]={
  48. .name="S6",
  49. .pin=S5PV210_GPH0(5),
  50. .irq=IRQ_EINT(5),
  51. .val=KEY_MINUS,
  52. },
  53. [6]={
  54. .name="S7",
  55. .pin=S5PV210_GPH2(6),
  56. .irq=IRQ_EINT(22),
  57. .val=KEY_CAPSLOCK,
  58. },
  59. [7]={
  60. .name="S8",
  61. .pin=S5PV210_GPH2(7),
  62. .irq=IRQ_EINT(23),
  63. .val=KEY_SPACE,
  64. },
  65. };
  66. staticvoidtimer_function(unsignedlongdata){
  67. if(button_desc==NULL)
  68. return;
  69. if(gpio_get_value(button_desc->pin)){
  70. input_event(buttons_dev,EV_KEY,button_desc->val,0);
  71. }
  72. else{
  73. input_event(buttons_dev,EV_KEY,button_desc->val,1);
  74. }
  75. input_sync(buttons_dev);
  76. }
  77. staticirqreturn_tirq_handler(intirq,void*devid){
  78. button_desc=(structbutton_desc*)devid;
  79. mod_timer(&timer,jiffies+HZ/100);
  80. returnIRQ_RETVAL(IRQ_HANDLED);
  81. }
  82. staticintbuttons_init(void){
  83. inti;
  84. buttons_dev=input_allocate_device();
  85. if(buttons_dev==NULL){
  86. printk(KERN_ERR"Error:allocateinputdevicefailed!");
  87. return-ENOMEM;
  88. }
  89. __set_bit(EV_KEY,buttons_dev->evbit);
  90. __set_bit(EV_REP,buttons_dev->evbit);
  91. __set_bit(KEY_L,buttons_dev->keybit);
  92. __set_bit(KEY_S,buttons_dev->keybit);
  93. __set_bit(KEY_C,buttons_dev->keybit);
  94. __set_bit(KEY_SPACE,buttons_dev->keybit);
  95. __set_bit(KEY_MINUS,buttons_dev->keybit);
  96. __set_bit(KEY_ENTER,buttons_dev->keybit);
  97. __set_bit(KEY_LEFTCTRL,buttons_dev->keybit);
  98. __set_bit(KEY_CAPSLOCK,buttons_dev->keybit);
  99. printk("1");
  100. if(input_register_device(buttons_dev)){
  101. gotoerror_1;
  102. }
  103. printk("2");
  104. init_timer(&timer);
  105. timer.function=timer_function;
  106. add_timer(&timer);
  107. printk("3");
  108. for(i=0;i!=8;++i){
  109. if(request_irq(buttons_desc[i].irq,irq_handler,
  110. IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,buttons_desc[i].name,&buttons_desc[i])){
  111. gotoerror_2;
  112. }
  113. }
  114. printk("4");
  115. return0;
  116. error_2:
  117. for(--i;i>=0;--i){
  118. free_irq(buttons_desc[i].irq,&buttons_desc[i]);
  119. }
  120. input_unregister_device(buttons_dev);
  121. error_1:
  122. input_free_device(buttons_dev);
  123. return-EBUSY;
  124. }
  125. staticvoidbuttons_exit(void){
  126. inti;
  127. for(i=0;i!=8;++i){
  128. free_irq(buttons_desc[i].irq,&buttons_desc[i]);
  129. }
  130. input_unregister_device(buttons_dev);
  131. input_free_device(buttons_dev);
  132. }
  133. module_init(buttons_init);
  134. module_exit(buttons_exit);
  135. MODULE_LICENSE("GPL");

很顯然,基于輸入子系統(tǒng)的按鍵驅(qū)動(dòng)比起直接編寫的字符驅(qū)動(dòng)設(shè)備要簡單的多,不過按鍵消抖還是要加的,上面的代碼加上了按鍵消抖。如果在開發(fā)過程中遇到了什么問題,還是歡迎留言討論。



關(guān)鍵詞: S5PV210輸入子系

評論


技術(shù)專區(qū)

關(guān)閉