新聞中心

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

        S5PV210(TQ210)學習筆記——按鍵驅動程序

        作者: 時間:2016-11-28 來源:網絡 收藏
        經過前面的配置,S5PV210開發已經可以成功進入Linux控制臺了,那么,有了這個環境就可以開始學習Linux驅動的編寫和測試了。學習Linux設備驅動,通常是從字符設備驅動開始。我寫的第一個驅動程序是Led的,其實也就是熟悉下字符設備驅動的基本結構,本文以中斷方式的按鍵驅動為例,簡單的介紹下字符設備驅動程序。

        一 按鍵驅動程序的簡單實現

        本文引用地址:http://www.104case.com/article/201611/322807.htm

        下面是基于中斷和消息的按鍵驅動程序,其工作原理是:當應用程序讀取鍵值時,會調用按鍵驅動程序的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. }
          上一頁 1 2 下一頁

        關鍵詞: S5PV210按鍵驅

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 蒙山县| 鄱阳县| 烟台市| 安塞县| 达孜县| 东方市| 香格里拉县| 成安县| 鄂尔多斯市| 万载县| 武宁县| 临朐县| 团风县| 肇庆市| 枣阳市| 泗阳县| 五大连池市| 关岭| 大竹县| 咸阳市| 民县| 神木县| 名山县| 开化县| 晋中市| 忻州市| 贡嘎县| 萝北县| 岳池县| 长治市| 广宁县| 道真| 漠河县| 阿坝县| 家居| 内丘县| 杭锦旗| 龙井市| 英山县| 新乡县| 珠海市|