HardFault 故障排除

HardFault 在实际工作中比较常见,遇到这样问题,重要的是定位问题,当然有比较好的开源工具(backtrace),但这就失去分析问题本质的机会。

在这里插入图片描述

一、原因分析

1、可能堆栈溢出。
2、数组越界或局部变量未初始化

二、解决办法

1、增加栈空间
在这里插入图片描述

将0x800增大看是否解决问题,大多数情况可以解决问题,如果没有效果就要定位是进入HardFault之前的情况。

三、定位HardFault之前的情况

在这里插入图片描述
在这里插入图片描述

1、首先产看LR寄存器的值为)0XFFFFFFF1.
2、定位到MSP的值(主堆栈指针)0X20001550.
3、通过memory 产看0X20001550的值。
4、HardFault原因一般以0x08开头,找到0x080023D2.
5、在汇编窗口右键打开Disassembly Window,输入刚才的地址.
6、定位到HardFault之前的函数。
7、分析是因为变量i未赋除值,那么i就是随机数,问题解决。

四、boot跳转APP进入hardfault

1、通过上诉方法定位到问题是APP触发了定时器中断,导致hardfault,通过Call Stack + Locals也可以看出HAL_TIM_IRQHandler完之后就进入hardfault了,而且定位的地址则和上诉方式定位结果一致。所以又多了一种定位方法,而且更快速准确。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
2、最近现在调试说stm32 的iap程序时,每次跳转总是进入hardfault_handler,仔细检查跳转时的设置,
前面进行了两个操作关中断 __disable_irq()和把用户代码的栈顶地址设置为栈顶指针__set_MSP(),
首先用户代码的栈顶地址是正确的,看了下__disable_irq()使用的“cpsid i”只是简单的禁止CPU去响应中断,
没有真正的去屏蔽中断的触发,中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()后,
由于中断标志位没请空,还会触发中断,因此禁止中断需要逐个对模块进行Disable操作。进行修改后程序正常运行。

SysTick->CTRL = 0;                                /*关键代码*/
HAL_DeInit();                                     /*可选*/
HAL_NVIC_DisableIRQ(SysTick_IRQn);                /*可选*/
HAL_NVIC_ClearPendingIRQ(SysTick_IRQn);           /*可选*/
  • 0
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值