Lazy loaded image
原理篇14-操作系统故障诊断
Words 672Read Time≈ 2 min
2026-9-2
🎯
本篇目标:HardFault 是嵌入式开发的高频噩梦。本篇讲清故障寄存器怎么看、现场怎么抓、stp_rtos 的 HardFault 处理怎么写的。

一、Cortex-M 的故障体系

Cortex-M3/M4/M7 有四类故障异常:
异常
默认状态
说明
UsageFault
可配置使能
除零、未对齐访问、未定义指令、非法状态
BusFault
可配置使能
总线错误、取指/取数失败
MemManageFault
可配置使能
MPU 违规、非法内存访问
HardFault
总是使能
兜底,上面三类未使能时都升级为 HardFault

二、四个关键寄存器

都在 SCB(系统控制块)里:
寄存器
地址
作用
CFSR
0xE000ED28
可配置故障状态(MFSR+BFSR+UFSR 三合一)
HFSR
0xE000ED2C
HardFault 状态(FORCED 位表示由其他 fault 升级)
MMFAR
0xE000ED34
MemManage 出错地址
BFAR
0xE000ED38
BusFault 出错地址
CFSR 按字节拆成三个:

三、抓现场:HardFault_Handler

出故障时,硬件已经把 R0~R3、R12、LR、PC、xPSR 压进栈。关键一步是判断用的是 MSP 还是 PSP:
EXC_RETURN 的 bit2 是金标准:0 = MSP(异常里出的事),1 = PSP(线程里出的事)。这决定了去哪个栈里找 PC。

四、stp_hw_hard_fault_exception

hard_fault_track 读 HFSR 的 FORCED 位,再分发到 usage_fault_track / bus_fault_track / mem_manage_fault_track,逐位翻译成人类可读的故障名(DIV_BY_ZERO、UNALIGNED_ACCESS、PRECISERR……)。

五、分析流程(实战)

  1. 看 PC:反汇编定位出错指令;
  1. 看 LR:LR - 1 - 4 反推调用链(Thumb 地址减 1,LR 是返回地址的下一条);
  1. 看 CFSR/HFSR:确定故障类型;
  1. 看 BFAR/MMFAR:精确故障时给出出错地址;
  1. 常见根因:栈溢出(PC 跑到数据区)、野指针(BFAR 指向非法地址)、除零(UFSR DIV_BY_ZERO)。
注意:先读 BFAR/MMAR,再读 VALID 位,顺序反了可能被更高优先级 fault 抢占导致地址被擦除。

六、小结

  • HardFault 是兜底,具体原因看 CFSR/HFSR;
  • EXC_RETURN bit2 决定去 MSP 还是 PSP 找现场;
  • 先读地址寄存器再读状态位,最后清状态位。
核心一句话:故障诊断 = 抓 PC/LR + 读状态寄存器 + 定位出错地址,三步定位根因。
上一篇
C++ String 常用操作
下一篇
嵌入式工程师习题集

Comments
Loading...