omap3530(Cortex-A8)硬件平台软件调试笔记
2019-07-13 16:52发布
生成海报
硬件环境:
采用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
联系邮箱 beswipe@yahoo.com.cn
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的区间。
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮