当前位置:首页 > 单片机 > 单片机
[导读]stm32 HardFault_Handler调试及问题查找方法STM32出现HardFault_Handler故障的原因主要有两个方面:1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。2、堆栈溢出。增加堆栈的大小。

stm32 HardFault_Handler调试及问题查找方法

STM32出现HardFault_Handler故障的原因主要有两个方面:

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

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

出现问题时排查的方法:

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

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

{

if (CoreDebug->DHCSR & 1) {//check C_DEBUGEN == 1 -> Debugger Connected

__breakpoint(0);// halt program execution here

}

while (1)

{

}

}

DEBUG如下图

SP值为0x20008560,查看堆栈里面的值依次为R0~R3、R12、Return address、PSR、LR,例如R0(1027 00 00),显然堆栈后第21个字节到24字节即为Returnaddress,该地址0x0801C907即为异常前PC将要执行的下一条指令地址。



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





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


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




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




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

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


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读
关闭