【STM32】Fault 类异常_记一次STM32中HardFault问题的调试解决

1. 基础知识       

Fault 类异常
有若干个系统异常专用于 fault 处理。 CM3 中的 Faults 可分为以下几类:

  • 总线 faults
  • 存储器管理 faults
  • 用法 faults
  • 硬 fault

表 7.8 总线 fault 状态寄存器(BFSR),            地址:0xE000_ED29
表 7.9 存储器管理 fault 状态寄存器(MFSR),地址:0xE000_ED28
表 7.10 用法 fault 状态寄存器(UFSR),          地址:0xE000_ED2A
表 7.11 硬 fault 状态寄存器                              地址:0xE000_ED2C

1.1 总线 Faults


当 AHB 接口上正在传送数据时,如果回复了一个错误信号(error response),则会产生总线 faults,产生的场合可以是:

  • z 取指,通常被称作“预取流产”(prefetch abort)
  • z 数据读/写,通常被称作“数据流产”(data abort)

在 CM3 中执行如下动作可以触发总线异常:

  •  中断处理起始阶段的堆栈 PUSH 动作。 称为“入栈错误”
  •  中断处理收尾阶段的堆栈 POP 动作。 称为“出栈错误”
  •  在处理器启动中断处理序列(sequence)后的向量读取时。这是一种罕见的特殊情况,被归类为硬 fault。


1.3存储器管理 faults


存储器管理faults多与MPU有关,其诱因常常是某次访问触犯了MPU设置的保护策略。另外,某些非法访问,例如,在不可执行的存储器区域试图取指,也会触发一个 MemManagefault,而且即使没有 MPU 也会触发。MemManage faults 的常见诱因如下所示:

  • 访问了 MPU 设置区域覆盖范围之外的地址
  • 往只读 region 写数据
  • 用户级下访问了只允许在特权级下访问的地址

1.4 用法 faults


用法 faults 发生的场合可以是:

  •  执行了未定义的指令
  •  执行了协处理器指令(Cortex‐M3 不支持协处理器,但是可以通过 fault 异常机制来使用软件模拟协处理器的功能,从而可以方便地在其它 Cortex 处理器间移植)
  •  尝试进入 ARM 状态(因为 CM3 不支持 ARM 状态,所以用法 fault 会在切换时产生。软件可以利用此机制来测试某处理器是否支持 ARM 状态)
  •  无效的中断返回(LR 中包含了无效/错误的值)
  •  使用多重加载/存储指令时,地址没有对齐。另外,通过设置 NVIC 的对应控制位,可以在下列场合下也产生用法 fault:
  •  除数为零
  •  任何未对齐的访问


1.5硬 fault


        硬 fault 是上文讨论的总线 fault、存储器管理 fault 以及用法 fault 上访的结果。如果这些 fault 的服务例程无法执行,它们就会成为“硬伤”——上访(escalation)成硬 fault。另外,在取向量(异常处理是对异常向量表的读取)时产生的总线 fault 也按硬 fault 处理。

       在NVIC 中有一个硬 fault 状态寄存器(HFSR),它指出产生硬 fault 的原因。如果不是由于取向量造成的,则硬 fault 服务例程必须检查其它的 fault 状态寄存器,以最终决定是谁上访的。

 

2. 经典案例

       STM32F103项目中使用了uCOS-II,出现一个致命问题:当只跑uCOS-II时,程序运行正常,一旦开启USB功能(或任何其它带高优先级中断的程序),程序运行一段时间后就会死掉,时间是随机的。

通过keil启动程序,死机时停下来,看到死在HardFault_Handler中:

HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler          [WEAK]
                B       .
                ENDP

提示出现了硬件错误。
看下这时的寄存器:

SCB(System Control Block)寄存器是Cortex-M4处理器的一个重要组成部分,包含了许多控制系统行为的寄存器。其,AIRCR(Application Interrupt and Reset Control Register)寄存器的地址为0xE000ED0C,用于控制断和复位的行为。以下是一些常用的AIRCR寄存器位: 1. 重启系统(SYSRESETREQ)位(位2):当该位被置位时,系统将重启。这相当于执行一次软件复位。 2. 向量表偏移(VECTKEYSTAT)位(位16-31):当该位被设置为0x05FA时,可以访问向量表偏移寄存器(VTOR)。该寄存器用于指定向量表的基地址。 3. 向量表重定位(PRIGROUP)位(位8-10):该位用于指定断优先级分组方式。例如,如果该位设置为4,则将使用4位断优先级和4位子优先级。 以下是一些使用AIRCR寄存器的示例代码: 1. 重启系统: ```c SCB->AIRCR |= SCB_AIRCR_SYSRESETREQ_Msk; ``` 2. 访问向量表偏移寄存器: ```c // 先写入VECTKEYSTAT位,然后再写入VTOR寄存器 SCB->AIRCR = (0x05FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_VECTKEYSTAT_Msk; SCB->VTOR = 0x08000000; // 设置向量表基地址 ``` 3. 指定断优先级分组方式: ```c // 将PRIGROUP位设置为4,使用4位断优先级和4位子优先级 SCB->AIRCR = (4 << SCB_AIRCR_PRIGROUP_Pos) & SCB_AIRCR_PRIGROUP_Msk; ``` 需要注意的是,修改AIRCR寄存器可能会对系统的稳定性和安全性产生影响。在使用AIRCR寄存器时,应该遵循Cortex-M4处理器的参考手册和硬件手册的指导,并根据具体情况进行权衡。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值