3. 启动日志来源与形态

做芯片启动调试这些年,我见过太多工程师对着BootROM日志一脸茫然。说白了,日志就是芯片在说人话——它告诉你它现在在干嘛,卡在哪了,为什么卡住。今天我们就来聊聊,这些日志到底是怎么出来的,又该怎么看。

3.1 日志输出原理:UART与SEMI

BootROM的日志输出,主要有两条路:UART和SEMI。我刚开始接触时也纳闷,为什么要有两套?后来踩过坑才明白,各有各的用武之地。

3.1.1 UART输出

UART是最传统的串口输出方式。芯片上电后,BootROM初始化UART控制器,设置好波特率(通常是115200或921600),然后通过TX引脚往外吐字符。

它的优点是简单、通用。你拿一根USB转串口线,接上GND、TX、RX,打开串口助手就能看到日志。我在项目中遇到过最头疼的情况——芯片上电后串口没任何输出。后来发现是UART的GPIO复用没配好,TX引脚被别的外设占用了。

UART日志输出流程:

  1. BootROM启动,初始化UART控制器
  2. 配置波特率、数据位、停止位、校验位
  3. 将日志字符串逐字符写入UART发送寄存器
  4. UART硬件自动将并行数据转成串行波形输出

3.1.2 SEMI输出

SEMI(Semihosting)是另一种方式。它不依赖物理串口,而是通过调试接口(如JTAG/SWD)把日志传给调试器,再由调试器打印到主机终端。

嗯,这里要注意:SEMI在芯片刚上电、时钟还没稳定时特别好用。因为UART需要配置波特率,而SEMI只需要调试器连着就行。我习惯在早期启动阶段用SEMI,等UART初始化好了再切过去。

我的经验:量产测试时用UART,开发调试时用SEMI。两个都开着也没问题,但要注意日志缓冲区不要溢出。

3.2 日志级别:INFO/WARN/ERROR/DEBUG

BootROM的日志不是一股脑全往外倒的。它分了四个级别,每个级别代表不同的严重程度。你想想看,如果每次启动都打印几千行DEBUG信息,谁受得了?

级别 含义 典型场景
ERROR 致命错误,启动失败 时钟锁相环失锁、Flash校验失败
WARN 异常但可恢复 时钟精度偏差、电压略低
INFO 正常流程信息 初始化完成、跳转到下一阶段
DEBUG 调试用详细信息 寄存器值、状态机跳转

我曾经在调试一个启动时序问题时,发现ERROR日志一直没打印,但芯片就是起不来。后来把日志级别调到DEBUG,才发现是某个中间状态超时了。所以我的建议是:先看ERROR,再看WARN,最后才看DEBUG。别一上来就开DEBUG,信息太多反而找不到重点。

避坑指南:我曾经遇到过DEBUG日志太多,把UART发送缓冲区撑爆的情况。结果后面的ERROR日志没打出来,误导了我整整两天。后来我在代码里加了环形缓冲区,才解决这个问题。

3.3 常见日志格式解析

BootROM的日志格式,各家芯片厂有细微差别,但大体结构差不多。我总结了一个通用模板:

[时间戳] [级别] [模块] [文件:行号] 日志内容

举个例子:

[0000.123] [INFO] [CLK] pll_init.c:45 PLL locked at 800MHz
[0000.456] [WARN] [PMU] pmu_check.c:123 VDD_CORE voltage 1.12V (expected 1.15V)
[0000.789] [ERROR] [FLASH] flash_init.c:78 Flash ID mismatch (read: 0xEF, expected: 0xC8)

咱们一条条拆开看:

  • 时间戳:从芯片复位开始算的毫秒数。注意,这个时间不一定准,因为BootROM早期时钟可能还没稳定。我一般只看相对时间差。
  • 级别:就是上面说的INFO/WARN/ERROR/DEBUG。看到ERROR就要警惕了。
  • 模块:哪个子系统出的日志。CLK是时钟,PMU是电源管理,FLASH是存储。这个能帮你快速定位问题范围。
  • 文件:行号:源码位置。这个对芯片原厂工程师特别有用,但对我们做系统集成的,知道个大概就行。
  • 日志内容:具体描述。这里经常包含关键数值,比如电压、频率、状态码。

实战技巧:拿到一份BootROM日志,我习惯先搜"ERROR"和"FAIL"。如果没有,再搜"WARN"。如果还是没有,那恭喜你,芯片大概率是正常启动了。但有时候日志里连INFO都没有——那就是芯片根本没跑到日志输出那一步,得从硬件上查原因了。

3.4 知识体系总览

下面这张图,是我自己总结的BootROM日志知识体系。你可以把它当成一个检查清单,调试时对照着看:

BootROM日志知识体系 输出原理 UART串口输出 SEMI调试接口输出 环形缓冲区管理 日志级别 ERROR - 致命错误 WARN - 异常警告 INFO - 正常信息 DEBUG - 调试细节 日志格式 时间戳解析 模块标识识别 关键数值提取 错误码对照 调试核心思路 1. 先看ERROR,再看WARN,最后DEBUG 2. 关注时间戳,判断启动阶段耗时 3. 结合模块标识,快速定位问题子系统

这张图把BootROM日志分成了三个维度:输出原理、日志级别、日志格式。调试时,你从任何一个维度切入都可以。我个人习惯先看日志级别,找到ERROR后,再看它的格式,最后根据输出原理判断是不是UART配置问题。

好了,关于BootROM日志的基础知识就聊到这。记住一句话:日志是芯片在说话,你得学会听懂它。下次遇到启动问题,别急着怀疑硬件,先看看日志里有没有线索。