问题现象:
死机。
分析过程
添加Cmbacktrace库。
打印信息如下:
Fault on thread Daemon
===== Thread stack information =====
addr: 2001a558 data: 00000000
addr: 2001a55c data: 0000b3b0
addr: 2001a560 data: a5a5a5a5
addr: 2001a564 data: 0804166d
addr: 2001a568 data: a5a5a5a5addr: 2001a56c data: a5a5a5a5
====================================
=================== Registers information ====================
R0 : 10000000 R1 : e000ed04 R2 : 2001a1cc R3 : 0000f30d
R12: a5a5a5a5 LR : 0804991d PC : 08032812 PSR: 61000000
==============================================================
Debug fault is caused by BKPT instruction executed
根本原因
当初增加bkpt指令就是为了方便调试,在连接仿真器,调试模式运行时,如果有异常,则程序会自动停下来。
软件断点指令:
__BKPT(0)
没想到,在系统上实际运行时,没有连接仿真器,却变成了灾难性的后果:硬故障。
参考:
5.1 hardfault产生的原因
- 上面三个可配置异常如果没使能,就直接触发hardfault。这也是笔者目前最经常遇到的状态;
- 取向量期间收到总线异常;(这个书中在总线异常那小节有描述)
- 连接了调试器(暂停调试未使能)且调试监控异常未使能时执行了断点(BKPT)指令;
- 如果在BKPT指令执行时却发现C_DEBUGEN和MON_EN都为0,则会因为无法进入调试而
上访成硬fault,并且把硬fault状态寄存器(HFSR)的DEBUGEVT位给置1,同时在调试fault状态寄存器(DFSR)中的BKPT位也置1(笔者最近就遇到了该问题,没有连接调试器,但还没有找到是哪里执行了BKPT指令);
5.2 hardfault错误状态寄存器SCB->HFSR(0xE000ED2C)表示的信息
以下大部分参考《COTEX-M3权威指南》- 宋岩,附录E
- DEBUGEVT:调试事件触发了hardfault;
1)断点/观察点事件
2)如果在硬 fault 服务例程的执行过程中,没有使能监视器异常(MON_EN=0)也没有使能停机调试(C_DEBUGEN=0),却执行了 BKPT 指令。缺省时,有些 C 编译器可能会在半主机代码中使用 BKPT 指令。 - FORCED:总线错误、存储器管理错误或使用错误导致hardfault;
试图在 SVC/监视器服务例程中执行 SVC/BKPT,或者在其它拥有相同或更高优先级的服务例程中执行 SVC/BKPT。 - VECTBL:取向量失败导致hardfault;
1)在取向量过程中发生总线 fault
2)向量表偏移量设置有误
解决措施
去掉软件断点。
用其他方式提示异常状态。