HardFault_Handler问题查找方法

[复制链接]
1775|16
 楼主| 王大熊 发表于 2015-5-27 08:46 | 显示全部楼层 |阅读模式
STM32出现HardFault_Handler故障的原因主要有两个方面:

1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。

2、堆栈溢出。增加堆栈的大小。

 楼主| 王大熊 发表于 2015-5-27 08:47 | 显示全部楼层
出现问题时排查的方法:

发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12、LR、PC、XPRS 寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。

注意:寄存器均是32位,且STM32是小端模式。(参考Cortex-M3权威)
 楼主| 王大熊 发表于 2015-5-27 08:47 | 显示全部楼层
 楼主| 王大熊 发表于 2015-5-27 08:48 | 显示全部楼层
 楼主| 王大熊 发表于 2015-5-27 08:48 | 显示全部楼层
编写问题代码如下:
  1. void StackFlow(void)
  2. {
  3. int a[3],i;

  4. for(i=0; i<10000; i++)
  5. {
  6.   a[i]=1;
  7. }
  8. }

  9. void SystemInit(void)
  10. {
  11.   /* Reset the RCC clock configuration to the default reset state ------------*/
  12.   /* Set HSION bit */
  13.   RCC->CR |= (uint32_t)0x00000001;



  14.   /* Reset CFGR register */
  15.   RCC->CFGR = 0x00000000;

  16.   /* Reset HSEON, CSSON and PLLON bits */
  17.   RCC->CR &= (uint32_t)0xFEF6FFFF;

  18.   /* Reset PLLCFGR register */
  19.   RCC->PLLCFGR = 0x24003010;

  20. StackFlow();

  21.   /* Reset HSEBYP bit */
  22.   RCC->CR &= (uint32_t)0xFFFBFFFF;

  23. 。。。。。。。。。。。。。。

  24. }
 楼主| 王大熊 发表于 2015-5-27 08:49 | 显示全部楼层
DEBUG如下图

SP值为0x20008560,查看堆栈里面的值依次为R0~R3、R12、LR、PC、XPRS, 例如R0(10 27 00 00),  显然堆栈后第21个字节到24字节即为LR,该地址0x08001FFD即为异常前PC将要执行的下一条指令地址(即StackFlow()后面的语句处 RCC->CR &= (uint32_t)0xFFFBFFFF)
QQ截图20150527084920.png
 楼主| 王大熊 发表于 2015-5-27 08:50 | 显示全部楼层
另一种方法:

默认的HardFault_Handler处理方法不是B .这样的死循环么?楼主将它改成BX LR直接返回的形式。然后在这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句那儿
  1. __asm void wait()
  2. {
  3.       BX lr
  4. }



  5. void HardFault_Handler(void)
  6. {
  7.     /* Go to infinite loop when Hard Fault exception occurs */
  8.        wait();
  9. }
angerbird 发表于 2015-6-15 21:28 | 显示全部楼层
堆栈溢出的话,一般来说需要精简程序代码的,尽量少占用RAM的使用空间的。
smilingangel 发表于 2015-6-16 20:48 | 显示全部楼层
HardFault_Handler的问题比较难找的吧。。原因很多的,一般处理办法就是在该处直接的加入复位机制的吧。
smilingangel 发表于 2015-6-16 20:48 | 显示全部楼层
不管怎样处理的,前提条件是不能让进入死循环的。。
旧影子 发表于 2015-6-17 07:22 | 显示全部楼层
学习了,比较有用,有时候进入了错误中断,但就是不知道是因为什么引起的。
deliciouscook 发表于 2015-6-19 15:53 | 显示全部楼层
这个对于定位错误很有帮助的,不用瞎乱找出错的地方了。
zhangbo1985 发表于 2015-6-19 19:18 | 显示全部楼层
这个问题的经常会出现的,,原来是这方面的问题的。
tongbu2015 发表于 2015-6-21 21:38 | 显示全部楼层
王大熊 发表于 2015-5-27 08:47
出现问题时排查的方法:

发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相 ...

这些线管寄存器的都需要检查的。
tongbu2015 发表于 2015-6-21 21:39 | 显示全部楼层
王大熊 发表于 2015-5-27 08:50
另一种方法:

默认的HardFault_Handler处理方法不是B .这样的死循环么?楼主将它改成BX LR直接返回的形式 ...

死循环的是需要注意的,避免进入死循环。
 楼主| 王大熊 发表于 2015-6-22 09:37 | 显示全部楼层
旧影子 发表于 2015-6-17 07:22
学习了,比较有用,有时候进入了错误中断,但就是不知道是因为什么引起的。 ...

其实,就是这样,也是比较难找的,好好的规范好程序,一般出现在还没有初始化完毕就开中断的情况。
旧影子 发表于 2015-6-23 10:18 | 显示全部楼层
王大熊 发表于 2015-6-22 09:37
其实,就是这样,也是比较难找的,好好的规范好程序,一般出现在还没有初始化完毕就开中断的情况。 ...

是了,和初始化的代码有很大的关系。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

236

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部