免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 23966 | 回复: 71

自己修改的ADC0809驱动,Godbach和版主请看看 [复制链接]

论坛徽章:
0
发表于 2008-11-18 11:08 |显示全部楼层
我根据自己的需要对之前发的那个adc0809的驱动进行了修改
目的:利用2410的timer0做一个定时中断,比如10ms中断一次,
获取数据并对一个阈值进行判读,最后置为0,1,再吧之前获取的数据和刚获取的对比 不同则加1
最后再read函数输出这个累加值

但是不解编译可以,安装insmod的时候会出现0oops错误  不解啊·~~~~~~
麻烦帮我看看啊 感激不及啊~~~~

  1. /* driver/char/adc0809.c
  2. *  this is a adc0809 char device driver.
  3. * Any problem pls contact [email]support@hhcn.com[/email]
  4. */

  5. #include <linux/module.h>
  6. #include <linux/kernel.h>
  7. #include <linux/init.h>

  8. #include <linux/signal.h>
  9. #include <linux/sched.h>
  10. #include <linux/timer.h>
  11. #include <linux/interrupt.h>
  12. #include <asm/irq.h>
  13. #include <asm/arch/hardware.h>
  14. #include <asm/arch/irqs.h>
  15. #include <asm/io.h>

  16. #include "adc0809_ioctl.h"

  17. MODULE_LICENSE("GPL");

  18. #define ADC0809_MAJOR 231
  19. /*define the adc0809 major node is 231*/


  20. #define adc0809_sle (*(volatile unsigned long *)ADC_GPACON)
  21. #define adc0809_sle_data (*(volatile unsigned long *)ADC_GPADATA)


  22. unsigned long ADC_GPACON, ADC_GPADATA;
  23. static unsigned long ADC_0, ADC_1, ADC_2, ADC_3, ADC_4, ADC_5, ADC_6, ADC_7;
  24. unsigned long ADC_DATA;
  25. static unsigned int r_TCFG0,r_TCFG1,r_TCNTB1,r_TCMPB1,r_TCON,r_GPCCON;

  26. //unsigned long adc_write_addr;
  27. //unsigned long adc_read_addr;
  28. int * adc_read_addr,* adc_write_addr;


  29. devfs_handle_t devfs_adc;

  30. void adc0809_interrupt(int,void *,struct pt_regs *);

  31. int  adc0809_open(struct inode *, struct file *);
  32. int  adc0809_release(struct inode *, struct file *);
  33. //int  adc0809_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
  34. ssize_t adc0809_read(struct file *, char * , size_t , loff_t *);
  35. ssize_t adc0809_write(struct file *, const char *, size_t , loff_t *);

  36. static struct file_operations adc0809_fops = {
  37.        // ioctl:          adc0809_ioctl,   //根据参数确定读取的引脚;
  38.         open:           adc0809_open,                //选中片选NGCS2(初始化ADC0809的管脚配置),初始化adc_read_addr;
  39.         read:           adc0809_read,
  40.         write:          adc0809_write,
  41.         release:        adc0809_release,
  42. };

  43. //struct timer_list timer_ForData;  // 定时器

  44. char data; //变量类型不同也会出错,之前使用unsigned long所得是一连串八位数字要么是-1
  45. unsigned long addr;

  46. int adc0809_sum=0;
  47. /*------------中断处理函数------------------*/
  48. void adc0809_interrupt(int irq,void *d,struct pt_regs *regs)
  49. {
  50.         char adc0809_v=0,adc0809_u=0;
  51. /*clear interrupt register for INT_TIMER0*/
  52.         SRCPND &= (~0x00000800);    //bit11
  53.         INTPND = INTPND;
  54. [b]/*---下面这一段使自己加的--------*/[/b]
  55.           data = (*(volatile unsigned long *) adc_read_addr);
  56.         if(data<200){adc0809_v=0;}
  57.                 else adc0809_v=1;
  58.         if(adc0809_v<adc0809_u){adc0809_sum=adc0809_sum+1;}
  59.                 else adc0809_sum=adc0809_sum;
  60.         adc0809_u=adc0809_v;
  61. printk("data:%d\n",data);
  62. printk("adc0809_u:%d\n",adc0809_u);
  63. printk("adc0809_v:%d\n",adc0809_v);
  64. printk("adc0809_sum:%d\n",adc0809_sum);
  65. }

  66. /*------- Open/close code for raw IO.-----*/
  67. int adc0809_open(struct inode *inode, struct file *filp)
  68. {
  69.           adc_read_addr = ADC_DATA;
  70.         adc_write_addr = ADC_1;     
  71.         (*(volatile unsigned char *) adc_write_addr) = (char) 0;       
  72.         printk("open ok\n");
  73.           return 0;
  74. }
  75. /*------------read()----------------*/
  76. ssize_t adc0809_read(struct file *filp, char * buf,
  77.                  size_t size, loff_t *offp)
  78. {       
  79.         char key;
  80.        
  81.        
  82.         key =adc0809_sum;
  83.         printk("key_driver:%d\n",key);
  84.         copy_to_user(buf,&key,1);//put_user(key,buf);
  85.         //printk("adc0809_read:adc_read_addr=0x%x\n",adc_read_addr);
  86.         return 1;
  87. }
  88. /*------------------write()-------------------------------*/
  89. ssize_t adc0809_write(struct file *filp, const char *buf,
  90.                   size_t size, loff_t *offp)
  91. {
  92.    char key;
  93.    if (get_user(key, buf))
  94.                return -EFAULT;
  95.    printk("adc0809_write:adc_write_addr=0x%x; key = %c\n",adc_write_addr,key);

  96.         (*(volatile unsigned char *) adc_write_addr) = key;
  97.    //put_user(key,buf);
  98.    return 1;
  99. }

  100. /*----------------release()---------------------*/
  101. int adc0809_release(struct inode *inode, struct file *filp)
  102. {
  103.         printk("release ok\n");
  104.         return 0;
  105. }

  106. [b]/*---这里我吧ioctl函数给删除了 就是不使用它,而是在初始化函数中来选着引脚并赋值[/b]
  107.   Deal with ioctls against the raw-device control interface, to bind
  108.   and unbind other raw devices.

  109. int adc0809_ioctl(struct inode *inode,          //octl选着待测的引脚 并触发中断
  110.                         struct file *flip,                //就是给 是0809的寄存器 一旦这个引角得到一个触发信号
  111.                         unsigned int command,        //那么相应的管脚就工作,然后才能输出ADC_DATA
  112.                         unsigned long arg)               
  113. {
  114.       int err = 0;
  115.       switch (command) {
  116.         case IOCTRL_ADC_0:
  117.           adc_write_addr = ADC_0;
  118.           //printk("adc0809_ioctl: adc addr: %x\n",adc_write_addr);
  119.           /* start collect and convert
  120.           (*(volatile unsigned char *) adc_write_addr) = (char) arg;
  121.          
  122.           return 0;
  123.         case IOCTRL_ADC_1:  //通道选择 因为ADC0809工作通道选择是由ADDC,ADDB,ADDA来实现的.
  124.           adc_write_addr = ADC_1;     
  125.           (*(volatile unsigned char *) adc_write_addr) = (char) arg;
  126.           return 0;
  127.         default:
  128.           err = -EINVAL;
  129.       }
  130.       // adc_read_addr = ADC_DATA;
  131.       //adc_write_addr = ADC_2;
  132.           //(*(volatile unsigned char *) adc_write_addr) = (char) arg;
  133.             
  134.       return err;               
  135. }

  136. /*-------------------iormap()--地址影射函数---*/
  137. static int address_map(void)
  138. {
  139.            r_TCFG0 = ioremap(0x51000000,4); //定时器配置寄存器0
  140.             r_TCFG1 = ioremap(0x51000004,4); //定时器配置寄存器1
  141.             r_TCNTB1 = ioremap(0x51000018,4);
  142.            r_TCMPB1 = ioremap(0x5100001C,4);
  143.             r_TCON = ioremap(0x51000008,4);
  144.             r_GPCCON = ioremap(0x56000020,4);

  145.         ADC_GPACON = (unsigned int)ioremap(0x56000000,4);  //物理寄存器的影射,个人认为这里都是指CPLD的物理寄存器
  146.           ADC_GPADATA = ioremap(0x56000004,4);
  147.           ADC_0 = ioremap(0x10000010,4);
  148.           ADC_1 = ioremap(0x10002010,4);
  149.           ADC_2 = ioremap(0x10004010,4);
  150.           ADC_3 = ioremap(0x10006010,4);
  151.           ADC_4 = ioremap(0x10008010,4);
  152.           ADC_5 = ioremap(0x1000a010,4);
  153.           ADC_6 = ioremap(0x1000c010,4);
  154.           ADC_7 = ioremap(0x1000e010,4);  
  155.           ADC_DATA = ioremap(0x10000020,4);
  156.             return 0;

  157. }
  158. /*--------------------------------------------------------------------------*/
  159. int __init adc0809_init(void)
  160. {
  161.   static int result;
  162. // unsigned long gpfup;
  163.   //volatile unsigned int bankcon2;       
  164.   address_map();
  165.   printk("*********************adc0809_init**************\n");
  166.                  adc_write_addr = ADC_0;              [b] //ioctl函数的功能放到初始化函数中[/b]
  167.          (*(volatile unsigned char *) adc_write_addr) = (char) arg;

  168.   

  169. // bankcon2=(volatile unsigned int)ioremap(0x4800000c,4);
  170. // *(volatile unsigned int*)bankcon2 |= 3<<13;  //
  171.   /* select NGCS2 */
  172.   adc0809_sle |= 0x2000;
  173.   adc0809_sle_data &= (~0x2000);


  174. [b]/*-----------初始化S3C2410的时钟timer0-------------原驱动没有的后来添加的-------------*/[/b]
  175.         (*(volatile unsigned int *)r_TCFG0) &= 0x11111100;//prescaler=0
  176.         (*(volatile unsigned int *)r_TCFG1) &= (~0x000000F0);//MUX1=1/2
  177. //        (*(volatile unsigned int *)r_TCFG1) &= (~0x000000D0);//MUX1=1/8  时间T=r_TCNTB1/625000(s)
  178.         (*(volatile unsigned int *)r_TCNTB1) = 25000;         //时间为10ms
  179.             (*(volatile unsigned int *)r_TCMPB1) = 0x00000000;
  180.             (*(volatile unsigned int *)r_TCON) |= 0x00000E00;
  181.            (*(volatile unsigned int *)r_TCON) &= (~0x00000200);
  182.            (*(volatile unsigned int *)r_TCON) |= 0x00000100;

  183.         disable_irq(IRQ_TIMER1);
  184.             enable_irq(IRQ_TIMER1);

  185.         result=request_irq(IRQ_TIMER1,&adc0809_interrupt,SA_INTERRUPT,"adc0809",NULL);
  186.         if (!result)
  187.         {
  188.                 printk("Get assigned irq %d,result=%d\n",IRQ_TIMER1,result);
  189. //                return result;
  190.         }

  191.         printk("***********Init ok!!***********\n");
  192.        

  193.         
  194.   devfs_adc =
  195.         devfs_register(NULL,"adc0809",DEVFS_FL_DEFAULT,
  196.                        ADC0809_MAJOR, 0,
  197.              S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
  198.                        &adc0809_fops,NULL);
  199.         return 0;
  200. }

  201. int __init adc0809_exit(void)
  202. {
  203.         (*(volatile unsigned int *)r_TCON) &= (~0x00000100);
  204.              disable_irq(IRQ_TIMER1);
  205.         free_irq(IRQ_TIMER1, adc0809_interrupt);
  206.              printk("exit ok\n");
  207. //free_irq(IRQ_EINT2, adc0809_interrupt);
  208.   devfs_unregister(devfs_adc);
  209.   return 0;
  210. }

  211. /*
  212. __initcall(adc0809_init);
  213. */
  214. module_init(adc0809_init);
  215. module_exit(adc0809_exit);

复制代码

[ 本帖最后由 ady2002 于 2008-11-18 11:34 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-11-18 11:22 |显示全部楼层
版主让你用code括起来,是发帖的时候那个有个工具是插入代码,而不是手写上这个,而且括号还是中文字符的。

OOPS一般都是你操作了非法指针。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-11-18 11:22 |显示全部楼层
把你对原先程序修改过的地方有比较明显的字体和颜色标示出来。

论坛徽章:
0
发表于 2008-11-18 11:33 |显示全部楼层
哦 误解了
主要就是删了ioctl函数 和在中断以及初始化函数中有些改动 其他都没有动
下班了 先去吃饭

期待中。。。。。。

论坛徽章:
0
发表于 2008-11-18 12:14 |显示全部楼层
我也知道说是  非法指针的问题哦
但是 我不解的是驱动中就那么几个指针
我都检查了 还是不知道问题在哪哦
郁闷啊?~~
所以想求助大家的力量帮我看看

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
发表于 2008-11-18 12:53 |显示全部楼层

回复 #5 ady2002 的帖子

说句实在话,你这个程序和昨天贴那个程序,没有实质性的改进。我建议你还是在昨天那个驱动上面下一番功夫,理解清楚点,加以修改一下。

论坛徽章:
0
发表于 2008-11-18 13:03 |显示全部楼层
原帖由 dreamice 于 2008-11-18 12:53 发表
说句实在话,你这个程序和昨天贴那个程序,没有实质性的改进。我建议你还是在昨天那个驱动上面下一番功夫,理解清楚点,加以修改一下。

我现在就是对昨天那个驱动 里面那几个问题不是很清楚哦。
就是ioctl到底是怎么触发中断函数的,wirter作用是什么一直高不明白哦
郁闷

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-11-18 13:06 |显示全部楼层
原帖由 ady2002 于 2008-11-18 13:03 发表

我现在就是对昨天那个驱动 里面那几个问题不是很清楚哦。
就是ioctl到底是怎么触发中断函数的,wirter作用是什么一直高不明白哦
郁闷


如果你对ioctl里面如果出发中断不理解的话,你可以把这函数加一些调试信息看一下

论坛徽章:
0
发表于 2008-11-18 13:08 |显示全部楼层
恩  加那些呢??
现在是 这个驱动不知道问题到底在哪?
god能不能仔细我帮我瞧瞧??????

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
发表于 2008-11-18 13:13 |显示全部楼层
原帖由 ady2002 于 2008-11-18 13:08 发表
恩  加那些呢??
现在是 这个驱动不知道问题到底在哪?
god能不能仔细我帮我瞧瞧??????


呵呵,这个因为具体和你的硬件相关。我没法具体帮你看。如果原先的程序是可以触发中断的,那你就根据程序来判断一下中断在哪里触发了。加一些printk打印出相关信息即可。
你知道中断的对应的地址线,关注这个地址的值是么时候变为触发中断的值了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP