<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM-Linux驅(qū)動(dòng)--ADC驅(qū)動(dòng)(中斷方式)

          ARM-Linux驅(qū)動(dòng)--ADC驅(qū)動(dòng)(中斷方式)

          作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò) 收藏
          硬件平臺(tái):FL2440

          內(nèi)核版本:2.6.28

          本文引用地址:http://www.ex-cimer.com/article/201611/318862.htm

          主機(jī)平臺(tái):Ubuntu 11.04

          內(nèi)核版本:2.6.39

          原創(chuàng)作品,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/yming0221/archive/2011/06/26/6568937.aspx

          這個(gè)驅(qū)動(dòng)寫(xiě)了好久,因?yàn)樵瓉?lái)的Linux內(nèi)核編譯的時(shí)候?qū)?strong>觸摸屏驅(qū)動(dòng)編譯進(jìn)內(nèi)核了,而觸摸屏驅(qū)動(dòng)里的ADC中斷在注冊(cè)的時(shí)候類(lèi)型選擇的是

          IRQF_SAMPLE_RANDOM,不是共享類(lèi)型,所以,自己寫(xiě)的ADC驅(qū)動(dòng)在每次open的時(shí)候,總提示ADC中斷注冊(cè)失敗。

          解決方案:

          重新配置內(nèi)核,選擇觸摸屏驅(qū)動(dòng)以模塊的形式編譯,而不是直接編譯進(jìn)內(nèi)核,這樣Linux在啟動(dòng)的時(shí)候不會(huì)自動(dòng)加載觸摸屏驅(qū)動(dòng),當(dāng)然,IRQ_ADC中斷號(hào)不會(huì)被占用。這樣可以測(cè)試自己寫(xiě)的ADC驅(qū)動(dòng)了。

          以下是驅(qū)動(dòng)源代碼:

          1. #include
          2. #include
          3. #include
          4. #include/*創(chuàng)建設(shè)備節(jié)點(diǎn)*/
          5. #include
          6. #include/*定義DECLARE_WAIT_QUEUE_HEAD*/
          7. #include/*定義了irqreturn_t等*/
          8. #includeinterrupt.h>/*request_irqdisable_irqenable_irq*/
          9. #include
          10. #include
          11. #include/*其中包含了#include"mach/irqs.h"*/
          12. #includeadc.h>
          13. #include
          14. #defineADC_MAJOR102
          15. #defineADC_NAME"my_adc"
          16. #defineSUCCESS0
          17. staticintadc_open(structinode*,structfile*);
          18. staticintadc_release(structinode*,structfile*);
          19. staticint__initadc_init(void);
          20. staticint__exitadc_exit(void);
          21. staticssize_tadc_read(structfile*,char*,size_t,loff_t*);
          22. volatileunsignedlongadc_con;
          23. unsignedlongadc_dat0;
          24. intflag;//等待任務(wù)完成標(biāo)志
          25. unsignedlongbuf;//存放轉(zhuǎn)換完成的數(shù)據(jù)
          26. //聲明等待隊(duì)列
          27. DECLARE_WAIT_QUEUE_HEAD(adc_wait);
          28. structclk*adc_clk;
          29. staticirqreturn_tadc_interrupt(intirq,void*dev_id)//中斷處理程序
          30. {
          31. if(flag==0)
          32. {
          33. buf=(readw(adc_dat0)&0x3ff);//讀取轉(zhuǎn)換完成的數(shù)據(jù)
          34. flag=1;
          35. wake_up_interruptible(&adc_wait);//喚醒等待其上的進(jìn)程
          36. printk("Readvalueis%ld/n",buf);
          37. }
          38. returnIRQ_HANDLED;
          39. }
          40. structfile_operationsadc_ops=
          41. {
          42. .owner=THIS_MODULE,
          43. .read=adc_read,
          44. .open=adc_open,
          45. .release=adc_release,
          46. };
          47. staticint__initadc_init(void)
          48. {
          49. intret;
          50. adc_clk=clk_get(NULL,"adc");//獲取時(shí)鐘
          51. clk_enable(adc_clk);//使能時(shí)鐘
          52. ret=register_chrdev(ADC_MAJOR,ADC_NAME,&adc_ops);//注冊(cè)設(shè)備
          53. if(ret<0)
          54. {
          55. printk("registerdevicefail/n");
          56. returnret;
          57. }
          58. adc_con=(unsignedlong)ioremap(0x58000000,4);
          59. adc_dat0=(volatileunsignedlong)ioremap(0x58000000+S3C2410_ADCDAT0,4);
          60. if(!(adc_con&adc_dat0))
          61. {
          62. printk("Failedtoioremap/n");
          63. gotohandle;
          64. }
          65. printk("Initialized.../n");
          66. returnSUCCESS;
          67. handle:
          68. unregister_chrdev(ADC_MAJOR,ADC_NAME);
          69. return-1;
          70. }
          71. staticintadc_open(structinode*inode,structfile*file)//打開(kāi)設(shè)備函數(shù)
          72. {
          73. //注冊(cè)中斷
          74. intret;
          75. //disable_irq(IRQ_ADC);
          76. //enable_irq(IRQ_ADC);
          77. ret=request_irq(IRQ_ADC,adc_interrupt,IRQF_SHARED,ADC_NAME,1);//注冊(cè)中斷IRQ_ADC在mach/irqs.h中定義
          78. if(ret<0)
          79. {
          80. printk("IRQ%dcannotrequest/n",IRQ_ADC);
          81. returnret;
          82. }
          83. returnSUCCESS;
          84. }
          85. staticintadc_release(structinode*inode,structfile*file)//關(guān)閉設(shè)備函數(shù)
          86. {
          87. free_irq(IRQ_ADC,1);//釋放中斷
          88. returnSUCCESS;
          89. }
          90. staticssize_tadc_read(structfile*file,
          91. char*buffer,
          92. size_tlength,
          93. loff_t*offset)//設(shè)備讀取函數(shù)
          94. {
          95. writew((1<<14)|(0x31<<6),adc_con);//設(shè)置ADCCON
          96. writew((readw(adc_con)|0x1),adc_con);//啟動(dòng)AD轉(zhuǎn)換
          97. wait_event_interruptible(adc_wait,flag);
          98. flag=0;
          99. }
          100. staticint__exitadc_exit(void)//驅(qū)動(dòng)卸載函數(shù)
          101. {
          102. iounmap(adc_con);
          103. iounmap(adc_dat0);
          104. unregister_chrdev(ADC_MAJOR,ADC_NAME);
          105. clk_disable(adc_clk);
          106. clk_put(adc_clk);
          107. printk("Theadcisunintialized/n");
          108. returnSUCCESS;
          109. }
          110. module_init(adc_init);
          111. module_exit(adc_exit);
          112. MODULE_LICENSE("GPL");

          Makefile文件:

          1. obj-m:=adc.o
          2. KERNELDIR?=/arm/linux-2.6.28.7-2440
          3. PWD:=$(shellpwd)
          4. default:
          5. $(MAKE)-C$(KERNELDIR)M=$(PWD)modules
          6. clean:
          7. rm-f*.o*.ko*.order*.symversread
          8. read:
          9. arm-linux-gcc-oreadread_adc.c

          以下是測(cè)試代碼:

          1. #include
          2. #include
          3. #include
          4. #defineADC_DEVICE"/dev/my_adc"
          5. intmain()
          6. {
          7. intret;
          8. unsignedintdata;
          9. ret=open(ADC_DEVICE,0);
          10. if(ret<0)
          11. {
          12. printf("Openadcfail/n");
          13. returnret;
          14. }
          15. for(;;)
          16. {
          17. //printf("cnt=%d/n",cnt);
          18. read(ret,&data,sizeof(data));
          19. //printf("Thevalueis%d/n",data);
          20. }
          21. close(ret);
          22. return0;
          23. }

          首先新建設(shè)備:

          mknod /dev/my_adc c 102 32

          然后插入驅(qū)動(dòng) insmod adc.ko

          運(yùn)行測(cè)試程序./read

          結(jié)果如下:

          可以看出,調(diào)節(jié)ad轉(zhuǎn)換器上的旋鈕,看到AD轉(zhuǎn)換值的變化,說(shuō)明驅(qū)動(dòng)工作正常。



          評(píng)論


          技術(shù)專(zhuān)區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();