新聞中心

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

S5PV210(TQ210)學(xué)習(xí)筆記——按鍵驅(qū)動(dòng)程序

作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
經(jīng)過(guò)前面的配置,S5PV210開發(fā)已經(jīng)可以成功進(jìn)入Linux控制臺(tái)了,那么,有了這個(gè)環(huán)境就可以開始學(xué)習(xí)Linux驅(qū)動(dòng)的編寫和測(cè)試了。學(xué)習(xí)Linux設(shè)備驅(qū)動(dòng),通常是從字符設(shè)備驅(qū)動(dòng)開始。我寫的第一個(gè)驅(qū)動(dòng)程序是Led的,其實(shí)也就是熟悉下字符設(shè)備驅(qū)動(dòng)的基本結(jié)構(gòu),本文以中斷方式的按鍵驅(qū)動(dòng)為例,簡(jiǎn)單的介紹下字符設(shè)備驅(qū)動(dòng)程序。

一 按鍵驅(qū)動(dòng)程序的簡(jiǎn)單實(shí)現(xiàn)

本文引用地址:http://m.butianyuan.cn/article/201611/322807.htm

下面是基于中斷和消息的按鍵驅(qū)動(dòng)程序,其工作原理是:當(dāng)應(yīng)用程序讀取鍵值時(shí),會(huì)調(diào)用按鍵驅(qū)動(dòng)程序的read函數(shù),而我們實(shí)現(xiàn)的read函數(shù)檢測(cè)完讀取長(zhǎng)度后沒有直接讀取鍵值而是等待按鍵消息,如果沒有按鍵,程序會(huì)進(jìn)入休眠狀態(tài),這樣可以節(jié)省大量的CPU,而當(dāng)我們按鍵時(shí)硬件會(huì)產(chǎn)生中斷,程序自動(dòng)進(jìn)入中斷處理函數(shù),在中斷處理函數(shù)中,驅(qū)動(dòng)程序讀取鍵值存入全局變量并激活read函數(shù)中等待的消息,應(yīng)用程序被迅速喚醒并通過(guò)read函數(shù)讀取鍵值,如此,完成了獲取鍵值的工作。下面是源碼,比較簡(jiǎn)單,也就不多說(shuō)了。

源碼:

  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. }
    上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: S5PV210按鍵驅(qū)

評(píng)論


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

關(guān)閉