4. Log分析工具入门:常用串口工具(Putty/SecureCRT)、Log抓取与保存、时间戳对齐
在嵌入式 HAL 驱动调试中,串口(UART)是最基础、最可靠的调试信息输出通道。掌握串口工具的使用、Log 抓取与保存方法,以及时间戳对齐技术,是进行高效 Log 分析的前提。本节将系统介绍常用串口工具的特性、配置要点与实战技巧。
4.1 常用串口工具对比与选型
嵌入式调试领域最常用的两款串口终端工具是 PuTTY 和 SecureCRT。下表从多个维度对比两者的核心差异:
| 对比维度 | PuTTY | SecureCRT |
|---|---|---|
| 授权方式 | 免费开源 | 商业付费(试用期有限) |
| 串口支持 | 原生支持 Serial 连接 | 原生支持 Serial 连接,配置更丰富 |
| Log 自动保存 | 需手动开启“Logging”功能 | 支持 Session 自动记录 Log |
| 会话管理 | 单会话,配置保存在注册表 | 多会话管理,支持文件夹分组 |
| 脚本支持 | 有限(仅命令行参数) | 支持 VBScript / Python 脚本 |
| 时间戳功能 | 需额外配置或第三方插件 | 内置时间戳选项,支持多种格式 |
| 适用场景 | 快速调试、临时连接 | 长期调试、自动化测试、团队协作 |
选型建议: 对于初学者或临时调试任务,PuTTY 完全够用;对于需要长时间抓取 Log、多会话管理或自动化脚本的复杂调试场景,推荐使用 SecureCRT。
4.2 串口工具配置要点
无论使用哪款工具,串口参数配置必须与目标板 UART 设置完全一致。以下为典型配置参数:
- 波特率(Baud Rate): 常用 115200、921600,需与驱动代码中
HAL_UART_Init()的BaudRate字段匹配。 - 数据位(Data Bits): 通常为 8 位。
- 停止位(Stop Bits): 通常为 1 位。
- 校验位(Parity): 通常为 None。
- 流控(Flow Control): 通常为 None。
PuTTY 配置示例:
打开 PuTTY → 选择 "Serial" 连接类型 → 输入串口号(如 COM3)→ 设置 Speed 为 115200 → 在左侧 "Serial" 分类中确认 Data Bits=8, Stop Bits=1, Parity=None, Flow Control=None → 保存 Session。
打开 PuTTY → 选择 "Serial" 连接类型 → 输入串口号(如 COM3)→ 设置 Speed 为 115200 → 在左侧 "Serial" 分类中确认 Data Bits=8, Stop Bits=1, Parity=None, Flow Control=None → 保存 Session。
4.3 Log 抓取与保存方法
Log 抓取的核心目标是 完整、连续、不丢行 地记录所有串口输出。以下是两种工具的 Log 保存配置:
4.3.1 PuTTY Log 保存
- 在 PuTTY 配置界面左侧选择 "Logging"。
- 选择 "Printable output" 或 "All session output"。
- 指定 Log 文件路径(支持
&Y、&M、&D、&T等时间变量)。 - 勾选 "Flush log file more frequently" 以减少缓存丢失。
4.3.2 SecureCRT Log 保存
- 打开 Session 选项 → "Log File" 选项卡。
- 勾选 "Start logging upon connection"。
- 设置 Log 文件路径与命名规则。
- 在 "Advanced" 中勾选 "Append to file" 和 "Include timestamp in log"。
避坑提示: 抓取 Log 时,务必确保串口工具的缓冲区足够大(如 SecureCRT 的 "Scrollback buffer" 设置为 5000 行以上),否则在高速输出时可能丢失早期 Log 行。
4.4 时间戳对齐技术
时间戳对齐是 Log 分析中最关键的环节之一。它允许我们将 Log 中的每一行与系统时间或外部参考时间关联,从而精确定位事件发生的先后顺序和间隔。
4.4.1 时间戳对齐的三种方式
| 方式 | 原理 | 精度 | 适用场景 |
|---|---|---|---|
| 工具侧时间戳 | 串口工具在接收 Log 时自动添加 PC 端时间 | 毫秒级(受串口延迟影响) | 快速定位、粗略时序分析 |
| 目标板时间戳 | 嵌入式代码在 Log 输出时打印系统滴答(SysTick)或 RTC 时间 | 微秒级(取决于时钟源) | 精确时序分析、中断延迟测量 |
| 混合对齐 | 工具侧时间戳 + 目标板时间戳交叉验证 | 高精度 | 复杂故障排查、多板同步 |
4.4.2 目标板时间戳实现示例
在 HAL 驱动中,通常使用 HAL_GetTick() 获取系统滴答时间,并将其格式化后随 Log 输出:
#include "main.h"
void debug_log(const char *fmt, ...) {
va_list args;
char buffer[256];
uint32_t tick = HAL_GetTick(); // 获取系统滴答(单位 ms)
// 格式化时间戳前缀
int len = snprintf(buffer, sizeof(buffer), "[%lu.%03lu] ",
tick / 1000, tick % 1000);
// 格式化用户消息
va_start(args, fmt);
vsnprintf(buffer + len, sizeof(buffer) - len, fmt, args);
va_end(args);
// 通过串口输出
HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 1000);
}
4.5 时间戳对齐流程
下图展示了从 Log 抓取到时间戳对齐的完整流程:
4.6 时间戳对齐实战技巧
- 工具侧时间戳配置: SecureCRT 中可在 "Log File" 选项卡勾选 "Include timestamp in log",格式建议选择
[YYYY-MM-DD HH:MM:SS.mmm]。 - 目标板时间戳精度提升: 使用
DWT_CYCCNT寄存器(Cortex-M 内核)获取 CPU 周期计数,可实现纳秒级时间戳。 - 对齐验证: 在 Log 开头和结尾分别打印一个已知时间点(如
SystemClock_Config()完成时的 SysTick 值),与工具侧时间戳对比,验证对齐精度。 - 常见问题: 如果工具侧时间戳与目标板时间戳出现固定偏移,通常是由于串口驱动中的发送缓冲延迟导致,可在代码中增加
__DSB()指令强制刷新写缓冲。
实战案例: 某摄像头预览卡顿问题中,通过目标板时间戳发现 ISP 处理线程每帧耗时从 28ms 突增到 45ms,而工具侧时间戳仅显示整体延迟。混合对齐后定位到是 DMA 传输完成中断被更高优先级中断抢占导致,最终通过调整中断优先级解决。