Hard Fault 异常调试方法_go to infinite loop when hard fault exception occu

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Cortex-M3/4的Fault异常是由于非法的存储器访问(比如访问0地址、写只读存储位置等)和非法的程序行为(比如除以0等)等造成的。常见的4种异常及产生异常的情况如下:

**Bus Fault:**在fetch指令、数据读写、fetch中断向量或中断时存储恢复寄存器栈情况下,检测到内存访问错误则产生Bus Fault。

**Memory Management Fault:**访问了内存管理单元(MPU)定义的不合法的内存区域,比如向只读区域写入数据。

**Usage Fault:**检测到未定义指令或在存取内存时有未对齐。还可以通过软件配置是否检测到除0和其它未对齐内存访问也产生该异常,默认关闭,需要在工程初始化时配置:

[cpp] 
view plain
 copy

print
?

  1. SCB->CCR |= 0x18; // enable div-by-0 and unaligned fault

**Hard Fault:**在调试程序过程中,这种异常最常见。上面三种异常发生任何一种异常都会引起Hard Fault,在上面的三种异常未使能的情况下,默认发生异常时进入Hard Fault中断服务程序。使能前三种异常也要在初始化时配置:

[cpp] 
view plain
 copy

print
?

  1. SCB->SHCSR |= 0x00007000;   // enable Usage Fault, Bus Fault, and MMU Fault

在默认复位初始化时,Hard Fault使能,其它三者不使能,因此当程序中出现不合法内存访问(一般是指针错误引起)或非法的程序行为(一般就是数学里面常见的除0)时都将产生Hard Fault中断。

2 Hard Fault调试方法

假设IDE环境为Keil,芯片为STM32F103。

在stm32f10x_it.c中,添加软件断点,一旦调试时出现Hard Fault则会在停在__breakpoint(0)处。

[cpp] 
view plain
 copy

print
?

  1. /**
  2. * @brief  This function handles Hard Fault exception.
  3. * @param  None
  4. * @retval None
  5. */
  6. void HardFault_Handler(void)
  7. {
  8. /* Go to infinite loop when Hard Fault exception occurs */
  9. if (CoreDebug->DHCSR & 1) {  //check C_DEBUGEN == 1 -> Debugger Connected
  10. __breakpoint(0);  // halt program execution here
  11. }
  12. while (1)
  13. {
  14. }
  15. }

当进入Hard Fault断点后,菜单栏Peripherals >Core Peripherals >Fault Reports打开异常发生的报告,查看发生异常的原因。


上面的报告发生了BUS FAULT,并将Fault的中断服务转向Hard Fault。

相对于检测发生了什么异常,定位异常发生位置显得更重要。
(1)打开Call Stack窗口(如下图左侧,断点停在Hard Fault服务程序中)


(2)在Call Stack的HardFault_Handler上右键Show Caller Code(有的Keil版本也可以直接双击)

这时将跳转到发生异常的源代码位置(如上图),异常发生在p->hour=0这一行。这里错误很明显:指针p尚未为成员变量分配内存空间,直接访问未分配的内粗空间肯定出错。

再说明2点:
[1] 在复杂的情况下,即使定位了异常发生位置也很难容易的改正错误,要学会使用Watch窗口对发生错误的指针变量进行跟踪;
[2] 在问题不明晰的情况下,尝试分析反汇编代码,就自己遇到的,部分情况下的异常发生在BL等跳转指令处,BL跳转到了不合法的内存地址产生异常


在没有JTAG的情况下,通过串口打印出堆栈信息:

 1 /\* Private typedef -----------------------------------------------------------\*/
 2 enum { r0, r1, r2, r3, r12, lr, pc, psr};
 3 
 4 /\* Private define ------------------------------------------------------------\*/
 5 /\* Private macro -------------------------------------------------------------\*/
 6 /\* Private variables ---------------------------------------------------------\*/
 7 extern __IO uint16_t ADC_InjectedConvertedValueTab[32];
 8 uint32_t Index = 0;
 9 
 10 /\* Private function prototypes -----------------------------------------------\*/
 11 void Hard\_Fault\_Handler(uint32\_t stack[]);
 12 
 13 /\* Private functions ---------------------------------------------------------\*/
 14 
 15 static void printUsageErrorMsg(uint32\_t CFSRValue)
 16 {
 17     printf("Usage fault: \r\n");
 18     CFSRValue >>= 16; // right shift to lsb
 19 
 20     if((CFSRValue & (1<<9)) != 0) {
 21         printf("Divide by zero \r\n");
 22     }
 23     if((CFSRValue & (1<<8)) != 0) {
 24         printf("Unaligned access \r\n");
 25     }
 26 }
 27 
 28 static void printBusFaultErrorMsg(uint32\_t CFSRValue)
 29 {
 30     printf("Bus fault: \r\n");
 31     CFSRValue = ((CFSRValue & 0x0000FF00) >> 8); // mask and right shift to lsb
 32 }
 33 
 34 static void printMemoryManagementErrorMsg(uint32\_t CFSRValue)
 35 {
 36     printf("Memory Management fault: \r\n");


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/2bc48d0d36b4ab188ad4f03f8b9487b1.png)
![img](https://img-blog.csdnimg.cn/img_convert/0ef41b1af040715ac5c9878bc9196894.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值