一些点灯思路
烧录程序
没有系统之前可以通过判断:
- BROM提供的烧录程序是否工作,比如USB/网络/串口
- 接调试串口查看是否有内容输出
串口调通之前的bringup
最简单的方法就是点亮一个led来判断代码的状态:
汇编
如果怀疑启动的汇编代码有问题,则可以通过汇编进行以下操作:
- 读写寄存器来设置led所在引脚的pinmux
- 读写寄存器来设置led所在引脚的输入输出方向
- 读写寄存器来设置led所在引脚的电平
- 读写寄存器来设置led所在引脚的驱动能力(可选,如果点不亮再尝试)
下面是一个wch ch58x的例子:
.equ R32_PB_DIR, 0x400010c0
.equ R32_PB_OUT, 0x400010c8
li t0, R32_PB_DIR
lw t1, 0(t0)
ori t1, t1, (1 << 4)
sw t1, 0(t0)
li t0, R32_PB_OUT
lw t1, 0(t0)
ori t1, t1, (1 << 4)
sw t1, 0(t0)
C
如果汇编阶段没有问题的话,就可以从C代码中点灯来判断哪里卡住了
思路和上面汇编一样,下面是一个wch ch58x的例子:
#define R32_PB_DIR 0x400010c0
#define R32_PB_OUT 0x400010c8
uint32_t val;
// led on
val = ioread32((void *)R32_PB_DIR);
val |= (1 << 4);
iowrite32(val, (void *)R32_PB_DIR);
val = ioread32((void *)R32_PB_OUT);
val |= (1 << 4);
iowrite32(val, (void *)R32_PB_OUT);
JTAG/SWD
如果条件允许的情况下可以使用带外的调试接口进行调试。
串口调通之后的bringup
串口调通之后的bringup就很简单了:
- 打开调试信息,比如出错地方的backtrace,寄存器dump,以及代码内置的调试打印
- 在怀疑的地方打上printf来调试。
非法指令和段错误
代码问题
通过调试器或printf来诊断代码
编译器问题
检查编译器的优化参数,如果打开了CPU不支持的特性则会出现sigill和sigsev,通常出现在riscv平台。
DDR 问题
尝试更改DDR初始化参数,然后压力测试来确定出问题的参数范围。
内核电压问题
带有TPU核的SOC对内核电压要求很严格,有些大陆厂的SOC需要通过超频来达到宣传的性能,可以尝试:
- 调高一点内核电压,需要注意电压上限。
- 降低一点clk freq,需要注意分频范围。
然后进行压力测试
内存压力测试
普通的压力测试
将memtest程序运行在bootloader/linux系统
带有DMA的压力测试
可以进行压力测试的几个高速外设控制器:
- 显示控制器,压力测试时候将参数调高,控制器会持续DMA读取DDR中的内容
- 摄像头控制器,压力测试时可以将摄像头打开,控制器会持续DMA写入图像到DDR
- 网卡控制器,压力测试时候可以将网卡的dma ring调为合适的大小(当然,越大越好),然后进行网络收发压力测试
- 显卡控制器,压力测试时候可以将GPU的DMA开满,如果有条件可以调用GPU来编写一个内存测试程序,比如全志社区的lima-memtester
- USB控制器,可以接多个USB网卡进行压力测试,或找一个可以跑满带宽的板子进行echo测试。
- 内存到内存的DMA,可以在内存测试程序中写一个带dma的memcpy