CmBacktrace:一款专门给ARM Cortex-M系列单片机用的开源错误追踪库

什么是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,就能直接定位到出错那一行。

优缺点分析

优点

缺点

自动化程度高,一键输出故障现场

初次移植要配置cmb_cfg.h,配置项略多

调用栈回溯精度高,支持多操作系统

FreeRTOS源代码需稍微改动

支持Flash保存日志,断电也不丢失

Cortex-M0对栈回溯支持有限(指令集限制)

语言/编译器/MCU支持面广

对新手来说,SP/LR寄存器参数传入需小心调整

总结与展望
总的来说,CmBacktrace就像给ARM调试加了双“智能翅膀”,不管你是入门小白还是调试老鸟,都能瞬间提升效率。从此可以少挠头多干活,硬fault再也没什么好怕的。如果你也在为ARM系统的崩溃排查而烦恼,不妨试试这个神器。

项目地址:https://github.com/armink/CmBacktrace

发表评论