zoukankan      html  css  js  c++  java
  • 驱动调试方法小结

    1 . 调试输入子系统

         在调试输入子系统时,input_system,可以通过hexdump 来打开并且实时读取对于输入设备的值,数值关系如下图所示:

    image

        每一次按键事件上报后,都会有type为0的EV_SYN同步事件触发。value中的1表示按下,0表示松开,2代表重复类事件,设置按键中断为边沿触发,一次按键会触发两次中断。

        如果开启了图形界面,可以打开图形界面的记事本,按相应的按键,可以得到对于的数值

        如果没有图形界面,可以执行 cat /dev/tty1 ,然后按相应的按键,可以得到

        更改输入设备 exec 0 < /dev/tty1

    2.  操作一组寄存器

         在设置一些复杂设备的寄存器时,通常需要针对连续地址的多个寄存器进行设置,在Linux环境下,对于有关联关系的多个寄存器的操作,应该采取统一映射,结合将寄存器组合成结构体的方式来操作,这样,操作统一,简洁高效。

        例如:对于显示屏相关寄存器的操作,可以构造如下的结构体:

       1:  struct lcd_regs {
       2:      unsigned long    lcdcon1;        //start addrss : 0x4D00_0000
       3:      unsigned long    lcdcon2;
       4:      unsigned long    lcdcon3;
       5:      unsigned long    lcdcon4;
       6:      unsigned long    lcdcon5;
       7:      unsigned long    lcdsaddr1;
       8:      unsigned long    lcdsaddr2;
       9:      unsigned long    lcdsaddr3;
      10:      unsigned long    redlut;
      11:      unsigned long    greenlut;
      12:      unsigned long    bluelut;         //0x4D00_0028
      13:      unsigned long    reserved[9];    // addr( dithmode - bluelut) = 36 = 4 * 9
      14:      unsigned long    dithmode;        //0x4D00_004C
      15:      unsigned long    tpal;
      16:      unsigned long    lcdintpnd;
      17:      unsigned long    lcdsrcpnd;
      18:      unsigned long    lcdintmsk;
      19:      unsigned long    lpcsel;
      20:  };
      21:  static volatile struct lcd_regs* lcd_regs;
      22:  //    lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs));
      23:  //    lcd_regs->lcdcon1  = (4<<8) | (3<<5) | (0x0c<<1);
      24:  //    lcd_regs->lcdcon2  = (3<<24) | (319<<14) | (1<<6) | (0<<0);
      25:  //   ....
      26:  //   release operations : iounmap(lcd_regs);

       构造时,注意保留空间的设置,在后续操作时,采用同样的方式进行。

    3. 触摸屏优化设置

            在检测到触摸屏发生中断后,如果检测到按下,则设置touch screen XY坐标连续测量模式,并且启动adc,在adc转换完成中断中,读取对于XY轴的电压值,并且通过 input_report来上报事件。

            1. 在初始化adc,设置开始延迟寄存器为最大值,0xffff,稳定adc基准电压。

            2. 在adc转换结果中断中,再次判断触摸屏是否按下。

            3. 设定一个定时器,多次测量adc,求均值来减小误差

            4. 在求均值前,对所有检测到的数据进行基本的误差过滤,去掉偏差较大的读书

            5. 利用定时器来处理 长按和滑动事件

    4. 利用Uboot自带命令来测试硬件

         Uboot自带一些简单的命令,我们可以用它来测试一些硬件,这里以读取Nand Flash的Chip ID为例子。启动并且进入Uboot的命令行,因为Uboot是裸机程序,面对的是真实的物理地址,下面是命令示意:

          image

         .b w l 分别表示一次读取一个字节、两个字节和四个字节 后面的objects表示读取几次,寄存器长度为4字节。

         读取Nand Flash ID的操作顺序如下:

          选中 nand flash :    使能片选信号,操作设置 NFCONT寄存器的Reg_nCE为0

                                    image            

          发出Read ID命令:往命令寄存器中写入 READ ID命令(0x90)

                                    image

          发出地址数据: 往地址寄存器中写入 0x00地址数据

                                   image

          读取返回值: 连续读取五次,和对应芯片的Read ID读取命令结果,依次相符合,证明 这种Nand Flash 芯片的类型为 K9F2G08U0A 。

      image        退出读取ID的状态 : 向命令寄存器中写入 RESET命令(0xFF),复位设备。 image

    上述是读取NAN FLASH ID的例子,同样,可以用Uboot的单个命令行来一个字节一个字节的读取nand flash里面存储的内容,也可以用nand dump 0来显示flash中第一页的内容。

    5. 分析自带驱动的方法

         一般来讲,内核都自带有标准的驱动,分析的入口,我们可以从内核启动过程中,打印的相关日志信息来作为突破口来入手,在内核代码中搜索对于的字符串信息,从而开始分析。

         在进行内部设备的寄存器设置时,首先需要确保该模块的时钟使能,一般来说,内核在正常运行过程中,为了省电,会关掉一些外设的时钟,因此,在设置寄存器之间,必须要开启该模块的时钟,通用的方法如下:

       1:  struct clk *clk;                               //定义一个时钟结构
       2:  clk = clk_get(NULL,"nand");                    //通过设备id来查找时钟
       3:  clk_enable(clk);                               //实际调用的是 nand类型的时钟使能函数 s3c2410_clkcon_enable
       4:   
       5:  //arch/arm/mach-s3c2410 
       6:  static struct clk init_clocks_disable[] = {
       7:      {
       8:          .name        = "nand",
       9:          .id        = -1,
      10:          .parent        = &clk_h,
      11:          .enable        = s3c2410_clkcon_enable,
      12:          .ctrlbit    = S3C2410_CLKCON_NAND,
      13:      }, {

         先使能控制器的时钟,然后对其寄存器进行设置,最后,使能控制器本身,按照这样的操作顺序,一般是不会出错。

         注销设备时,释放相关资源的顺序和注册设备时,要保持相反的顺序,这样比较合理。   

         在设置片内外设控制器和片外设备的时序匹配时,要明确两点,时钟信号都是有主芯片主动发出的,时序有 读时序,写时序、等待时序等等,考虑到一致性,我们只需要对比两边读时序的部分,使得发出和接收两侧的时序保持兼容就行。不确定的寄存器值,保持默认值就行。

    6. 快速确定驱动所在内核配置脚本中的位置

         在需要确定内核驱动文件对于的menuconfig中的位置时,可以使用如下的方法来快速查找:

         例如:查找声卡驱动的对于配置选项在哪里?

         首先,我们肯定是可以找到声卡对于的驱动文件里面的Makefile,复制对应文件的CONFIG选项,例如,如果选项配置是 CONFIG_WM8976,那么就复制WM8976,然后进入内核的配置页面,按下“/”,出现如下搜索框:

         image

         粘贴选项,回车,就可以发现该选项在内核配置界面中的具体路径了,方便快速,值得一试。

    7. 移植madplayer播放器到JZ2440

         参考链接:http://blog.163.com/kang_6530/blog/static/7219155720090525649537/

         依次下载 zlib-1.2.3.tar.gz libid3tag-0.15.1b.tar.gz libad-0.15.1b.tar.gz madplay-0.15.2b.tar.gz 在其共有目录新建tmp文件夹。

         下面以  /home/hao/madplay/tmp目录为例子

         7.1 编译zlib

         ./configure --prefix=/home/hao/madplay/tmp

          然后修改生成的Makefile,修改CC,AR和RANLIB,加上交叉编译前缀arm-linux-

          然后make && make install ,

         7.2 编译libid3tag

          ./configure --prefix=/home/hao/madplay/tmp/ --host=arm-linux --disable-shared CC=arm-linux-gcc CPPFLAGS=-I/home/hao/madplay/tmp/include LDFLAGS=-L/home/hao/madplay/tmp/lib

          make && make install

         7.2 编译 libmad

          ./configure --prefix=/home/hao/madplay/tmp/ CC=arm-linux-gcc --host=arm-linux --disable-shared CPPFLAGS=-I/home/hao/madplay/tmp/include LDFLAGS=-L/home/hao/madplay/tmp/lib

          make && make install

          7.4 编译 madplay

          ./configure --prefix=/home/hao/madplay/tmp/ CC=arm-linux-gcc --host=arm-linux --disable-shared --enable-static CPPFLAGS=-I/home/hao/madplay/tmp/include LDFLAGS=-L/home/hao/madplay/tmp/lib

           make && make install

           注意事项,不要在linux与windows的共享目录中执行编译过程,有可能因为权限问题而失败。

           当出现madplay: error while loading shared libraries: cannot open shared object file: cannot load sharedobject file: No such file or directory,则是因为在编译时没有设置好静态链接和共享库,正确的配置就是在编译libid3tag、libmad 和madplay 时,加上disable-shared 选项,同时(只)在madplay 的配置语句上加上enable-static设置为静态。

    8. Windows安装,要求以数字签名的驱动程序

         在安装一些调试工具的驱动时,Windows自带的搜索驱动找不到,指定驱动安装路径也无法正常安装,弹出如下提示:

          image

        解决方法:用管理员身份进入命令行窗口,输入cmd,然后执行 bcdedit /set testsigning on ,然后重启电脑,这样,就打开Windows的测试模式,可以安装一些没有经过Windows驱动签名的驱动。

        如果需要取消测试模式,可以输入 bcdedit /set testsigning off ,然后重启,就可以。经过实际测试,是可以工作。

    9.ARM CACHE

        ARM体系结构的 DCACHE开启,需要事先使能MMU才能。而ICACHE无需其他限制条件,直接开启即可。

       1:  /* 启动ICACHE */
       2:      mrc p15, 0, r0, c1, c0, 0    @ read control reg
       3:      orr r0, r0, #(1<<12)
       4:      mcr    p15, 0, r0, c1, c0, 0   @ write it back
    Technorati 标签:
  • 相关阅读:
    if 语句运用
    c#语言基础
    关于条件运算符的应用
    Could not open Hibernate Session for transaction;
    node to traverse cannot be null!
    Struts2文件下载中文名乱码
    Spring MVC框架下的第一个Hello World程序
    strtus2中的defaultactionref无效的解决方法
    c 笔记
    工具系列1
  • 原文地址:https://www.cnblogs.com/cherishui/p/4404205.html
Copyright © 2011-2022 走看看