新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S5PV210(TQ210)學習筆記——輸入子系統驅動

        S5PV210(TQ210)學習筆記——輸入子系統驅動

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

        輸入子系統的原理分析強烈推薦觀看韋東山老師的視頻講座,講的非常清楚,我這里是按照輸入子系統的方式實現的按鍵驅動,下面是源碼,放在這里做個備份:

        本文引用地址:http://www.104case.com/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");

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



        關鍵詞: S5PV210輸入子系

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 永泰县| 海原县| 西贡区| 项城市| 许昌县| 吉木乃县| 斗六市| 浙江省| 安远县| 辰溪县| 色达县| 雷波县| 孝昌县| 宾阳县| 灌阳县| 会东县| 青岛市| 穆棱市| 阳泉市| 尚志市| 滦南县| 留坝县| 阿拉尔市| 邵东县| 柳江县| 沧州市| 武宣县| 金门县| 司法| 南阳市| 德保县| 大埔区| 平谷区| 巍山| 金寨县| 齐河县| 北川| 峨山| 博客| 台东市| 德化县|