一些点灯思路

烧录程序

没有系统之前可以通过判断:

  1. BROM提供的烧录程序是否工作,比如USB/网络/串口
  2. 接调试串口查看是否有内容输出

串口调通之前的bringup

最简单的方法就是点亮一个led来判断代码的状态:

汇编

如果怀疑启动的汇编代码有问题,则可以通过汇编进行以下操作:

  1. 读写寄存器来设置led所在引脚的pinmux
  2. 读写寄存器来设置led所在引脚的输入输出方向
  3. 读写寄存器来设置led所在引脚的电平
  4. 读写寄存器来设置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就很简单了:

  1. 打开调试信息,比如出错地方的backtrace,寄存器dump,以及代码内置的调试打印
  2. 在怀疑的地方打上printf来调试。

非法指令和段错误

代码问题

通过调试器或printf来诊断代码

编译器问题

检查编译器的优化参数,如果打开了CPU不支持的特性则会出现sigill和sigsev,通常出现在riscv平台。

DDR 问题

尝试更改DDR初始化参数,然后压力测试来确定出问题的参数范围。

内核电压问题

带有TPU核的SOC对内核电压要求很严格,有些大陆厂的SOC需要通过超频来达到宣传的性能,可以尝试:

  1. 调高一点内核电压,需要注意电压上限。
  2. 降低一点clk freq,需要注意分频范围。

然后进行压力测试

内存压力测试

普通的压力测试

将memtest程序运行在bootloader/linux系统

带有DMA的压力测试

可以进行压力测试的几个高速外设控制器:

  1. 显示控制器,压力测试时候将参数调高,控制器会持续DMA读取DDR中的内容
  2. 摄像头控制器,压力测试时可以将摄像头打开,控制器会持续DMA写入图像到DDR
  3. 网卡控制器,压力测试时候可以将网卡的dma ring调为合适的大小(当然,越大越好),然后进行网络收发压力测试
  4. 显卡控制器,压力测试时候可以将GPU的DMA开满,如果有条件可以调用GPU来编写一个内存测试程序,比如全志社区的lima-memtester
  5. USB控制器,可以接多个USB网卡进行压力测试,或找一个可以跑满带宽的板子进行echo测试。
  6. 内存到内存的DMA,可以在内存测试程序中写一个带dma的memcpy

Last updated: 2024-08-29