分类: 嵌入式
2010-10-09 10:21:46
问题:
这是一个困扰我好些天的问题了,当然,我也只是linux驱动的初学者,把字符设备驱动的理论看完后,就开始调试自己的PW2440板子,先是打印出信息,然后是定时器,然后是GPIO,矩阵键盘,后来想写ADC和TOUCHSCREEN的,但是在测试ADC的时候,很奇怪,给ADCCON寄存器写任何数据都没反应,读出的ADCCON值一直是0x3FC4,这个值是该寄存器复位后的默认值,再打印ADC的其他寄存器,也都只是默认值。
初分析:
1.难道是ADC的寄存器在某种状态下只能读不能写?查看手册,没有这么说的呀
2.ADC模块换掉了?这个是有可能的
3.ADC被linux系统的其他模块占用了?谁然我已经在配置内核的时候把一些关于ADC配置取消掉了,但是不能保证全部取消了,想想也是有可能的
验证分析:
1.因为我做linux开发现在是在ubuntu的物理系统上,所以我想在linux系统上源码级跟踪调试驱动的方法,这样比较方便调试(之前用的都是printk打印信息),网上介绍的好像只有用kgdb,但是这个只是对内核调试,要调试自己的驱动估计还得把驱动加进内核的code里面,如果真这样的话,要达到源码跟踪调试,那么每次修改驱动就得编译和下载一次内核(当然,可以用NFS方式挂载),虽然感觉实用性不大,但还是想尝试一下,可是在搭建KGDB调试环境的过程中也是困难重重,最终还是没用上KGDB
2.来到windows,用MDK+H-JTAG实现源码级跟踪调试变得很容易(缺点:不是linux环境),用MDK自带的S3C2440.S启动文件,配置好rom和ram分区(因为是调试,所以都分在SDRAM上),还需要添加一个.ini的配置文件,用于初始化arm处理器(便于下载.axf文件到RAM)和下载.AXF文件。在main函数里面,通过初始化ADCCON,然后分别采样各个通道,发现ADC完全工作正常,这一下子就把分析出来的 1、2 都给排除了。难道是分析出来的第3条?
3.再次仔细查看kernel的配置文件,ADC真没有被配置,分析的第3条我在心里把它排除了;那到底什么原因呢
再分析:
1.仔细查看ADC的寄存器,感觉好像是16位的,难道要用写16位数据的方式给它写值?
2.好像以前看有的ADC驱动修改用一个函数初始化ADC时钟,可是ADC的寄存器里面没有配置时钟的呀,难道是ADC没有时钟,它根本就没有工作?我的天啦,要真这样就太荒唐了
再验证分析:
1.改用iowrite16(v,p)给ADC寄存器写值,结果还是令人失望,排除再分析1
2.既然ADC寄存器里面没有配置时钟的,那么去看看时钟、电源管理那边,在CLKCON寄存器的第15位还真有控制ADC时钟使能的,难道linux系统默认没有开启吗!!后来把ADC的时钟使能(CLKCON[15]=1)后,linux下的ADC也工作正常了,好多天没找到的问题就出在这,我很无语
总结:
对使用芯片的硬件结构不熟悉是导致这个问题很大原因,当然,如果不编程,不使用该芯片,没有出现问题和解决问题的这个过程,也就没法熟悉它。通过解决一个小问题的这个过程学到很多芯片的其他知识和解决问题的方法,这是一个很有意义的过程