什么是CmBacktrace
先来拆解一下这个名字,Cortex Microcontroller Backtrace,听起来就很牛。简单说,它是一款专门给ARM Cortex-M系列单片机用的开源错误追踪库,能在断言(assert)、硬fault(HardFault)、内存管理fault、总线fault、使用fault等各种“当机”场景里自动捕获故障原因。它会帮你:
-
• 自动分析寄存器里的fault原因
-
• 抽取并输出完整的函数调用栈
-
• 拿到C源码里的精确行号(配合addr2line工具)
有了它,调试时不用偏左偏右猜寄存器,也不用连仿真器F10/F11地一步步追,直接给你报错堆栈,一看就懂。
解决了哪些痛点
很多人从51、MSP430转ARM,常常被HardFault搞傻:
-
• “我明明没写错,怎么就挂了?”
-
• 连接仿真器跑断点又费时又难复现
-
• fault寄存器代码自己得去手册查,还要推栈回溯一大堆
资深大佬虽有寄存器分析法,但每次都要手动拆逻辑,效率极低。甚至有些产品在现场一旦断开debug就找不回错。
CmBacktrace一把梳理好:当机现场,串口/Flash日志里就能看到完整调用链、寄存器状态、固件版本等信息,哪条逻辑出了问题一目了然。
核心功能一览
|
功能 |
描述 |
|
自动诊断 |
断言、HardFault、MemManage、BusFault、UsageFault全覆盖 |
|
调用栈回溯 |
输出PC地址列表,配合addr2line定位函数名和源码行号 |
|
多平台支持 |
Bare-Metal、RT-Thread、UCOSII、FreeRTOS |
|
多MCU/编译器支持 |
Cortex-M0/M3/M4/M7,IAR/Keil/GCC |
|
多语言输出 |
简体中文、English |
|
崩溃后日志保留 |
支持在Flash(EasyFlash)里保存最后一次崩溃信息,重启后读取 |
快速上手示例
下面这个小Demo,演示一个典型的除零fault:
#include "cm_backtrace.h"
int main(void){
// 初始化:固件名、硬件版本、软件版本
cm_backtrace_init("my_firmware.bin","HW1.0","SW1.0");
int a =100, b =0;
if (b ==0){
cm_backtrace_assert(cmb_get_sp());// 触发断言
}
int c = a / b;// 这里会触发硬fault
(void) c;
while(1);
return 0;
}
当程序跑到a/b,硬fault抛出,串口会立刻打印:
[HardFault] 原因:除以零 UsageFault
Stack: 0x08001234 0x08001100 ...
CPU Regs: LR=0xFFFFFFFF, SP=0x20002000 ...
Firmware: my_firmware.bin HW1.0 SW1.0
配合addr2line -e my_firmware.bin 0x08001234,就能直接定位到出错那一行。
优缺点分析
|
优点 |
缺点 |
|
自动化程度高,一键输出故障现场 |
初次移植要配置 |
|
调用栈回溯精度高,支持多操作系统 |
FreeRTOS源代码需稍微改动 |
|
支持Flash保存日志,断电也不丢失 |
Cortex-M0对栈回溯支持有限(指令集限制) |
|
语言/编译器/MCU支持面广 |
对新手来说,SP/LR寄存器参数传入需小心调整 |
总结与展望
总的来说,CmBacktrace就像给ARM调试加了双“智能翅膀”,不管你是入门小白还是调试老鸟,都能瞬间提升效率。从此可以少挠头多干活,硬fault再也没什么好怕的。如果你也在为ARM系统的崩溃排查而烦恼,不妨试试这个神器。
项目地址:https://github.com/armink/CmBacktrace