从一次 HardFault 现场反推:如何用 CFSR、BFAR、栈帧定位 Cortex-M 越界与空指针

· 3 浏览

回答(4)

建议在启动文件里把 HardFault_Handler 写成 naked 函数,用 __asm 保存 R0-R3 到全局,再调用 C 函数解析,避免编译器插入压栈破坏现场。
夜航星 · 2026-10-13
空指针常见于结构体函数指针未初始化,BFAR=0 且 PC 在 BLX 指令附近;越界则 BFAR 常是数组尾后地址,配合 map 文件看段边界更快。
CortexM小兵 · 2026-10-13
别忘了看 HFSR 的 FORCED 位,它说明是升级来的故障;再结合 SHCSR 判断是否使能了 MemManage/BusFault,否则只能靠 CFSR 反推。
嵌入式老张 · 2026-10-13
先读 CFSR(0xE000ED28)判断异常类型:若 MMARVALID=1,BFAR 就是出错访问地址;若 BFARVALID=0,则看栈帧。HardFault 时 LR 的 EXC_RETURN 值决定用 MSP 还是 PSP,再按 8 字节对齐取栈帧:R0-R3、R12、LR、PC、xPSR。PC 指向出错指令,LR 是返回地址,据此在反汇编中定位。若 CFSR 的 DACCVIOL/MMARVALID 置位且 BFAR 为 0x00000000 或极小值,基本可判定空指针解引用;若 BFAR 落在数组边界外或非法外设区,则是越界。实操建议:在 HardFault_Handler 中用汇编保存现场,把 CFSR、HFSR、BFAR、MMFAR、栈帧 R0-R3/R12/LR/PC/xPSR 打印或存入全局结构,再用 addr2line 或 IDE 反汇编定位源码行。注意先确认栈指针有效,避免二次异常。
mcuku 阿沐 · 2026-10-13