固件下下去,板子没反应,我也很绝望啊

2020-01-13 15:46:47 浏览数 (1)

前端时间回来了一块板子,于是各个团队都进入了紧张的 Bringup 工作中。

这块板子上的主芯片是一颗 Arm Cortex M3 DSP 的异构芯片,结构大概是这样的:

CM3 和 DSP 的固件独立存储在 Flash 中,上电后 CM3 先启动,然后 CM3 再把 DSP 的固件从 Flash 中加载到 Sram 中,最后再从 Sram 中拷贝到 DSP 的 ITCM 中,至于为什么不绕过 Sram 直接把 DSP 的固件从 Flash 中读到 DSP 的 ITCM 中,我们这里先不讨论。

Bringup 进行到第二天的时候,负责 DSP 的同学反馈说,DSP 的程序加载上去后,始终不能正常运行 —— 观察不到任何正常启动的现象。其实在 Bringup 刚开始阶段,这种情况是经常遇到的,我第一反应就是,让这位同学连上 DSP 的 JTAG 去单步调试,看到底发生了什么。

第三天的时候,我又找这位同学问了下,现在是什么情况了,这位同学一脸茫然的说:好奇怪,如果用 DSP 的 JTAG 直接下载固件到 ITCM,就能正常运行,通过 Cortex M3 去加载,就不能正常运行。听到这个差别,我潜意识的问他:有没有确认过 CM3 加载到 ITCM 中的固件是否正常?这位同学说应该不会有问题,这套流程他们之前在其他平台上都验证过。他们还有一些其他的坏一点,准备优先就他们的怀疑点做一些实验排查,比如 DSP 的cache 啊,复位控制啊,PLL 频率啊什么的。

因为 Bringup 阶段事情比较多,我也就没在追究去忙其他的事情了。

第四天,说所有怀疑的实验都做完了,还是没进展。我说确认下 CM3 拷贝到 ITCM 里面的固件是否正常吧 —— CM3 把固件拷贝到 ITCM 后,在用 JTAG 读出来,然后对比。

实验做完,这位同学蔫蔫的说,从 ITCM 中读出来的固件数据和编译出来的固件数据有一小部分对不上。而且这部分对上的数据位于固件尾巴上。

固件加载出错,程序肯定无法正常运行!那就直接排查数据在哪个环节出错的吧!

固件从 Flash 中加载到 Sram 中后,也用 JTAG 读出来和原始数据对比,结果正常!

那就是从 Sram 到 ITCM 的这个环节处了问题!

查看这段拷贝的代码,原来就是一个 rt_memcpy —— 我们在 Cortex M3 上运行的是 RT-Thread。

这位同学用 JLink 单步跟踪这段代码发现,每次程序运行到第二部分的时候,拷贝就异常了,能看到程序执行了,但是数据就是没拷贝过去!而第一段的拷贝都是正常的。

事出异常必有妖,我决定反汇编看看这段代码后面藏了什么玄机。

果真有猫腻,第一段代码,对于大块的 4 字节对齐的数据,CPU 是以 STR 这样的指令超 ITCM 写数据,即以 Word 为单位访问 ITCM,对于第二段,也就是一段数据的尾巴,剩下的那些零零散的不够四字节的数据,CPU 是以 STRB 这样的指令超 ITCM 写数据,即以字节为单位访问 ITCM。

memcpy 这样写是为了提高数据搬运的效率。对于按照 Word 对齐的数据,以 Word 的模式搬运,对于剩下的非Word 对齐的数据,以 Byte 模式搬运,一次搬运四字节肯定比一次搬运一字节要快。

但是我们这里踩了什么坑呢?以 Word 方式访问 ITCM 就正常,以 Byte 的方式访问就不成功?

为了进一步确认这个结论,我写了一段测试代码:

这段测试代码构造了一个 memcpy 命令,我可以在命令行通过 memcpy cnt value 来控制每次超 ITCM 搬运不同长度的数据,下面就开始测试:

一次写 16 字节的 1 到 ITCM,然后通过 Jlink 可以看到 ITCM 这片区域被成功的写入了 16 字节的 1。因为 16 是 4 个 4 字节,所以这次的 memcpy 是通过 STR 指令进行的。

一次 copy 17 字节的 2 到 ITCM, 通过 JLink 观察右下角的 ITCM,发现只写进去了 16 字节。根据 memcpy 算法,前 16 字节 是以 Word 的形式通过 STR 指令写入 ITCM 的,剩下的 一 字节 是以 STRB 的形式写入 ITCM 的。

一次 Copy 18 字节,同样发现只写进去了 16 字节。

一次 Copy 19 字节,还是只写进去了 16 字节!

一次 Copy 20 字节,全部写入成功了!按照 memcpy 算法,20 字节是以 五次 STR 指令,以 Word 模式拷贝过去的。

一次 Copy 21 字节,发现还是只写入了 20 字节!

一次 Copy 24 字节,全部拷贝成功!

到这里,我基本确认 Cortex M3 以 Byte 模式访问 ITCM 会失败!

然后联系 IC 设计方,确认是什么原因。IC 设计方回复说:Cortex M3 确实无法以 Byte 模式访问 ITCM,这是总线设计上限制的!

艾玛呀!忽然有种想打人的冲动,你文档上根本没提有这个限制啊!

后来想想,在无数次的 Bringup 过程中,类似这种固件拷贝不完整的情况,似乎坑过我好几次,有一次 Linux 内核起来后,很多驱动都加载失败,我一路从 Linux Kernel 查找到 U-Boot,再查到下载,最后确认是固件下载工具有问题,DTB 没有下载完整,而且这尼玛也是因为 flash 扇区对齐的问题导致的!还有一次从 U-Boot SPL 跳到 Arm turst firmware 后,总是卡死固定的位置,然后 Dump 发现 ATF 固件加载不完整,最后确认是 CLK 驱动问题引起 eMMC 工作异常导致的。

0 人点赞