您的位置 首页 元件

ARM-Linux驱动–ADC驱动(中止方法)

硬件平台:FL2440内核版本:2.6.28主机平台:Ubuntu11.04内核版本:2.6.39原创作品,转载请标明出处:http://blog.csdn.net/yming0221/ar…

硬件渠道:FL2440

内核版别:2.6.28

主机渠道:Ubuntu 11.04

内核版别:2.6.39

原创著作,转载请标明出处:http://blog.csdn.net/yming0221/archive/2011/06/26/6568937.aspx

这个驱动写了良久,由于本来的Linux内核编译的时分将触摸屏驱动编译进内核了,而触摸屏驱动里的ADC中止在注册的时分类型挑选的是

IRQF_SAMPLE_RANDOM,不是同享类型,所以,自己写的ADC驱动在每次open的时分,总提示ADC中止注册失利。

解决方案:

重新配置内核,挑选触摸屏驱动以模块的方式编译,而不是直接编译进内核,这样Linux在发动的时分不会主动加载触摸屏驱动,当然,IRQ_ADC中止号不会被占用。这样能够测验自己写的ADC驱动了。

以下是驱动源代码:

  1. #include
  2. #include
  3. #include
  4. #include/*创立设备节点*/
  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;//等候使命完结标志
  25. unsignedlongbuf;//寄存转化完结的数据
  26. //声明等候行列
  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);//读取转化完结的数据
  34. flag=1;
  35. wake_up_interruptible(&adc_wait);//唤醒等候其上的进程
  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”);//获取时钟
  51. clk_enable(adc_clk);//使能时钟
  52. ret=register_chrdev(ADC_MAJOR,ADC_NAME,&adc_ops);//注册设备
  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)//翻开设备函数
  72. {
  73. //注册中止
  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);//注册中止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)//封闭设备函数
  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)//设备读取函数
  94. {
  95. writew((1<<14)|(0x31<<6),adc_con);//设置ADCCON
  96. writew((readw(adc_con)|0x1),adc_con);//发动AD转化
  97. wait_event_interruptible(adc_wait,flag);
  98. flag=0;
  99. }
  100. staticint__exitadc_exit(void)//驱动卸载函数
  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

以下是测验代码:

  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. }

首要新建设备:

mknod /dev/my_adc c 102 32

然后刺进驱动 insmod adc.ko

运转测验程序./read

成果如下:

能够看出,调理ad转化器上的旋钮,看到AD转化值的改变,阐明驱动作业正常。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/264303.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部