omap3530(Cortex-A8)硬件平台软件调试笔记

硬件环境:


采用TI omap3530的天漠科技开发板和公司的板卡。

软件环境:
天漠科技开发包:
* linux kernel: 2.6.29-sbc8100
* u-boot-1.3.3
* x-load-1.41

后续移植linux-omap:
* linux kernel: 2.6.38

作者:agan
成都莱得科技
联系邮箱 [email protected]
racer.blog.chinaunix.net

转载须注明出处!

内容简介:描述调试过程中所遇问题及其解决办法和过程,可作为新手的FAQ使用。



1. Issue: 不能从SD卡启动。
   Fixed: 自己疏忽造成,手册已经提到要先用"HP Disk Storage Format Tool"格式化SD卡。


2. Issue: 烧写的Xload不能启动。
   Fixed: ECC格式不对造成,xload需要使用HW Ecc, 其他全部使用SW ECC。列表如下:

   x-loader 'nand ecc hw'
   u-boot 'nand ecc sw'
   okernel 'nand ecc sw'
   rootfs 'nand ecc sw'
   spash 'not required', default sw without oob

3. Issue: 启动过程中打印错误信息"Ignoring unrecognised tag 0x54410008".
   Fixed: 屏蔽掉U-Boot中的函数'setup_videolfb_tag', 因为它传递了错误的参数给Kernel.


4. Issue: 启动过程中打印错误信息"dpll3_m2_clk rate change failed: -22".
   Fixed: 这个错误发生在初始化SDRAM的PLL时钟的时候。
     修改文件"arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h", 修改数组'mt46h32m32lf6_sdrc_params'的第3个指,把133333333改成133000000.
         SDRAM的默认时钟为266MHZ(LPDDR: Low Power Double Data Rate, so it running 133MHZ instead), 计算结果应该为 133000000, 而非预定义的133333333,所以报了错。

5. Issue: 启动过程中打印错误信息"omap-dss DISPC error: Requested pixel clock not possible with the current OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning the constraint off."
   Fixed: 修改文件'.config', 把变量 'CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK'的值从 4 改成 2.
         或者:'make menuconfig' -> System Type -> TI OMAP Implementations -> Minimum FCK/PCK ratio (for scaling)


6. Issue: 启动过程中,在打印"Freeing init memory: 164K"之后,打印"Kernel panic - not syncing: Attempted to kill init!",然后系统崩溃.偶然出现,频率不低。
   Fixed: 使用2.6.29的kernel一直没解决,移植到2.6.38后解决。怀疑Kernel处理UBIFS出了问题。


7. Issue: 使用网口芯片"smsc 9221",替换原来的"dm9000".
   Fixed: u-boot 1.3.3 的软件改动:
     修改源文件 "include/configs/sbc8100.h":
         * Disable the 'dm9000' relatives.
         * Add new line: '#define CONFIG_DRIVER_SMC911X 1' & '#define CONFIG_DRIVER_SMC911X_BASE 0x2c000000'.

 修改源文件 "board/sbc8100/mem.c":
         * Disable the '#ifdef CONFIG_DRIVER_DM9000' at the line 263th, for enable the GPMC configurations as that of 'dm9000'.

 修改源文件 "drivers/net/smc911x.c":
         * Add new line '#define CHIP_9221 0x9221'. Append new member '{CHIP_9221, "LAN9221"}' to the array 'chip_ids'.

 注意这里为什么选择地址0x2c000000. 这是因为我的硬件把网口挂在了CS6上,关于CS6的配置位于源文件"board/sbc8100/mem.c"函数"gpmc_init()"的末尾。
 这个虚拟地址,是在这一段配置中固定了的,具体请看TI手册关于CS_CONFIG(0-7)的描述。

 Linux-2.6.29的软件改动:
 * make menuconfig: disable dm9000, enable 'CONFIG_SMSC911X'.
 * 修改源文件 "arch/arm/mach-omap2/board-omap3sbc8100.c"(这个目录是我的硬件平台源文件):
              * Disable 'dmp9000' relatives.
            * Modify the structure 'smsc911x_config', change the member flags' value from 32BIT to 16 BIT.
 * 修改源文件"arch/arm/plat-omap/include/mach/board-omap3evm.h"
     * Change 'OMAP3EVM_ETHR_GPIO_IRQ' from 176 to 25(这是我的硬件配置)
     * Change 'OMAP3EVM_SMC911X_CS' from 5 to 6. (这个选项没用)

 就这样,比较简单,没有新的开发内容。

8. Issue: USB PHY 'isp1504'不能工作。
   Fixed: 两个问题:
第一,isp1504有个片选引脚,操作过程中需要拉底。
第二,关于isp1504的clk引脚,如果是HostController的PHY,clk由Controller提供,1504只输入;如果是DeviceController的PHY,clk由isp1504提供,controller输入,此时isp1504的clk来源于XTAL1输入的分频。在我们的硬件中,是把isp1504作为HostController的PHY来使用。用示波器打此clk引脚,发现在通讯的时候有两个时钟信号,所以确定需要关掉ISP1504的CLK输出。根据isp1504的手册,发现需要把isp1504的XTAL1&XTAL2两根引脚置成VCC/GND或者GND/GND,告知硬件人员问题随即被解决。
以上硬件描述来源于ISP1504的手册。


9. Issue: ST16C554 QuardUart芯片驱动调试。
   Fixed:
 四合一串口扩展芯片,在目标硬件上位于片选3上,驱动可沿用driver/8250.c,只是在以下地方有修改:
 * u-boot-1.3.3/board/sbc8100/mem.c, 在网口CS6地址的配置下面,添加了CS3的配置(CONFIG1-7: 用于配置当前片选的访问时序)。
 * platform_device,加入了ST16C554的四个串口描述,修改了8250的部分代码。注意我这边的uartclk取值3686400。

10. Issue: SJA1000T CAN芯片驱动调试。
    Fixed: 
      最重要的部分,是在调试CAN芯片的读写时许。参见SJA1000T手册 'AC timing diagrams'这章节的图,一次CAN寄存器的读写包括5个信号: AD(偏移地址),ALE,RD或者WR,CS。
  这4组信号在我的目标硬件上都有PIN复用,最终我是采取了一次写操作(AD+ALE),然后紧跟一次读或者写操作(RD/WR+CS)来完成一次寄存器的读或者写动作,两次操作连续且受信号量保护。
  具体应用到读者的硬件平台上,跟硬件平台的对应PIN脚设计相关。
 
  除了上面的时序外,还要做:
  * CPU端对应CS的访问时序配置,跟st16c554一样.
  * 移植Lincan或者SocketCan驱动。(linux-2.6.29 不带can驱动, linux-2.6.38自带socketcan)。

  
11. Issue: PIN脚复用配置。
    Fixed:
在前面的驱动中,很多地方都涉及PIN脚复用配置。
涉及源代码: 'u-boot-1.3.3/board/sbc8100/sbc8100.c'中的宏定义'MUX_DEFAULT_ES2',文档支撑"7.6.3.2 PADCONFS Register Description"
每个芯片的驱动开发之前,都应该先来此确定一下CPU对应的PIN脚设置是否正确。特别是在遇到以下情况后,首先应来此校验一下:
* PIN脚默认电平不对;
* PIN脚不能输出或不能接收输入;
* PIN脚不能唤醒睡眠状态;


12. Issue: 低功耗调试
    Detail:
客户要求最低功耗20MA(5V),使用linux-2.6.29最低功耗只能达到90MA,相差甚远。
原来的硬件+linux-2.6.29最低功耗太高的原因:
* 硬件设计没有考虑功耗问题,有些芯片即使断掉VDD输入仍在通过地址线数据线漏电。
* linux-2.6.29软件不完善,最小系统不能进入休眠模式,最小系统IDLE只能减小20MA功耗。

解决办法及过程:
* 硬件:拿掉客户所不需要的芯片;
* 软件:尝试升级kernel。
Linux GIT有一分支叫linux-omap, 这个分支主要由TI自己的人负责omap系列芯片的模块驱动开发、BUG解决、kernel版本更新、迭代,由大量的OMAP芯片使用厂商开发对应硬件平台支撑代码(kernel/arch/arm/mach-omap2/board-XXX.c/h)。
如果读者感兴趣,可google这些关键词: linux-omap, beagleboard, linux-pm。

现在,以下链接可以使用:
"http://www.omappedia.org/wiki/Linux_OMAP_Kernel_Project" : 这个分支的介绍
"http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=summary" : GIT分支下载地址

第一个网页页面中,有个8mw的概念,我就是奔着这个8mw的目标才去移植新版本的kernel。
以下日志均产生于移植过程中。



21. Issue: 启动过程停止在 'Starting kernel ...' ,kernel不能被uncompress
    Fixed: 
      * 默认选择的平台是omap3evm,我更改为omap3_beagle,问题即被解决。
  * 原因见源代码"arch/arm/plat-omap/include/plat/uncompress.h", evm默认debug port是UART1,而我的硬件是UART3.
  * 而且我们的硬件很接近beagleboard.

22. Issue: 启动过程停止在以下打印以后:
      Starting kernel ...                                                                                                                             
        Uncompressing Linux... done, booting the kernel.                                                                                                

    Fixed: 
      最后原因确定是: 编译器版本造成。把编译器版本从 'arm-2007q3' 更新到 'arm-2009q1' 问题即被解决。
  寻找问题的过程很复杂。
  * 首先核对u-boot和kernel的magic_number发现是对的。
  * 其次让硬件飞了一个调试用的led(因为调试串口可能还没初始化),发现它是卡在'init/main.c: calibrate_delay()',非常底层,怀疑是timer没跑起来导致jiffes没有更新。
  * 遍历我们的硬件与beagleboard的所有区别,尝试合并timer相关代码(timer-gp.c/dmtimer.c/ex...)从2.6.29到2.6.38,尝试多个版本u-boot和kernel,结果一样,几近绝望!
  * 回过来往网上一搜,发现elinux/beagleboard的limitation一节有明显的说明,要求升级toolchain!
  
  升级toolchain以后,u-boot原来的编译选项 'armv7a' 要改成 'armv7-a', 源代码在这个位置'omap3/config.mk'。

23. Issue: 清理arch/arm/mach-omap2/board-omap3beagle.c源代码。
    Fixed:
  这是跟硬件平台beagleboard底层相关的源代码,因硬件有区别,所以需要改动,不然会出一些莫名错误。
  最好的办法是不要改之,而复制一个board-omap3XXX.c代码,到复制的源文件中改,再修改Kconfig和Makefile,为自己的硬件平台生成一个对应的配置选项。
  Beagleboard这一条线相关的其他代码都需要更改,改的最多的就是IO口。

24. Issue: linux-omap-2.6.37不能加载UBIFS,打印以下错误信息:
      (2.6.38也可能有同样的问题)

   cmdlinepart partition parsing not available
   Creating 5 MTD partitions on "omap2-nand.0":
   0x000000000000-0x000000080000 : "X-Loader"
   0x000000080000-0x000000260000 : "U-Boot"
   0x000000260000-0x000000280000 : "U-Boot Env"
   0x000000280000-0x000000680000 : "Kernel"
   0x000000680000-0x000010000000 : "File System"
   agan>> Try attach 4, with VID_HDR_OFFS: 0
   UBI: attaching mtd4 to ubi0
   UBI: physical eraseblock size:   131072 bytes (128 KiB)
   UBI: logical eraseblock size:    129024 bytes
   UBI: smallest flash I/O unit:    2048
   UBI: sub-page size:              512
   UBI: VID header offset:          512 (aligned 512)
   UBI: data offset:                2048
   uncorrectable error : 
   UBI error: ubi_io_read: error -74 (ECC error) while reading 512 bytes from PEB 0:512, read 512 bytes
   uncorrectable error : 
   UBI error: ubi_io_read: error -74 (ECC error) while reading 512 bytes from PEB 4:512, read 512 bytes
   uncorrectable error : 
   UBI error: ubi_io_read: error -74 (ECC error) while reading 512 bytes from PEB 5:512, read 512 bytes
   uncorrectable error : 
   UBI error: ubi_io_read: error -74 (ECC error) while reading 512 bytes from PEB 6:512, read 512 bytes


    Fixed:    
         最后的解决办法:
     1. board-omap3beagle.c(或者board-omap3XXX.c: 使用你的平台源文件) -> omap3beagle_nand_data: 添加一个新选项 '.devsize=1'.
     
     发现原因:
     board-omap3beagle.c -> omap3beagle_nand_data.options=NAND_BUSWIDTH_16,的确配置了使用16位Flash,但是纵观后续代码这个options根本没有得到使用,上层一直在使用8Bits位宽配置。
     发现过程颇为复杂:
     * 在同一个GIT Server上,发现2.6.32的kernel可以加载UBIFS。
     * 调试两个版本的源代码:nand_ecc.c->calculate_ecc(),发现计算之前,从同一地址读出的数据就不一样,因此基本确定是Flash读写或者初始化参数有问题造成的。
     * 比较32/38两个版本的Flash配置,再核对38版本Flash的初始化过程,最后发现了问题。
     

     2. 16位配置生效以后,仍有报ECC错误或者偶然panic现象,这样解决:
* 移植代码 'nand_base.c',从 '2.6.32' 到 '2.6.37', 然后在UBI + NAND + swecc的配置下工作一切正常。
* 在源代码函数'omap2.c:omap_nand_probe()'中新添一行'info->nand.badblockbits = 8;'。感觉这里有BUG。
然后感觉一切正常,没有任何错误打印信息。

25. Issue: kernel-2.6.37的Suspend不能挂起最小系统。
    Fixed: 

      参照网页'OMAP_Power_Management.htm'里面列出的测试脚本,我自己写了一个pm.sh,运行后,通过'cat /debug/pm_debug/count'发现CORE从来没有进入过Sleep/Ret状态。
  最后解决办法:

  修改'arch/arm/mach-omap2/usb-musb.c', 加入以下函数:

  ////////////////
static void omap3_musb_reset(void)
{

#define OTG_SYSCONFIG      0x404
#define OTG_SYSC_SOFTRESET BIT(1)

       void __iomem *otg_base;

       if (!cpu_is_omap34xx())
               return;

       otg_base = ioremap(OMAP34XX_HSUSB_OTG_BASE, SZ_4K);
       if (WARN_ON(!otg_base))
               return;

       /* Reset OTG controller.  After reset, it will be in
        * force-idle, force-standby mode. */
       __raw_writel(OTG_SYSC_SOFTRESET, otg_base + OTG_SYSCONFIG);
       iounmap(otg_base);
}

void __init usb_musb_init(struct omap_musb_board_data *board_data)
{
return omap3_musb_reset();
}
  ////////////////
  这源于linux-omap邮件列表里面的一个补丁,原因是"USB-OTG"被Bootloader置成Awake状态,且在Kernel中这个状态没有被更改过,而CORE对OTG有依赖关系。
  问题的解决也颇为复杂,在应用这个补丁之前我还尝试升级过u-boot到'beagleboard-validation-u-boot-beagle-XXX'的多个版本,均无作用。

  应用补丁后,目标硬件在Suspend to Sleep/Off状态时,可以达到50MA的功耗,如果硬件改改应该可以进入20MA的区间。




以上文章是作者原创,如有错误请指出。

你可能感兴趣的:(omap3530(Cortex-A8)硬件平台软件调试笔记)