您的位置:首页 > 其它

调试STM32遇到Hardfault知识总结

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

1、寄存器描述

首先查看硬故障寄存器,判别原因。

硬故障状态寄存器

硬fault状态寄存器(地址:0xE000_ED2C)

位段   名称            描述

31     DEBUGEVT        硬fault因调试事件而产生

30     FORCED          硬fault是总线fault,存储器管理fault或是用法fault上访的结果

29:2

1      VECTBL          硬fault是在取向时发生的

0

121页手册

各个fault状态寄存器(FSRs)都保持住它们的状态,直到手工清除。Fault服务例程在处理了相应的fault后不要忘记清除这些状态,否则如果下次又有新的fault发生时,服务例程在检视fault源时又将看到早先已经处理的fault状态标志,因此无法判断哪个fault是新发生的。

293页

FORCED

使用硬故障寄存器来获取激活硬故障处理器的事件的相关信息。

寄存器地址、访问类型和复位状态:

地址          0xE000ED2C

访问类型      读/写清除

复位状态      0x00000000

HFSR是一个写-清除寄存器。即向该位写1可以将其清除。

R14,R15的地址就是我们出错的代码所在的地址,需要在这个地址基础上,首先偶数对齐,然后向上减去8个字节。

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

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

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

科普小知识:

LR   连接寄存器

MSP  主堆栈指针

PSP  进程堆栈指针

Banked R13:两个堆栈指针

Cortex-M3拥有来个堆栈指针,然而它们是banked,因此任一时刻只能使用其中的一个。

主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)

进程堆栈指针(PSP):由用户的应用程序代码使用。

堆栈指针的最低两位永远是0,这意味着堆栈总是4字节对齐的。

排查方法:

发生异常之后可首先查看LR寄存器中的值,确定进入异常前一刻使用的堆栈为MSP或PSP,然后找到相应堆栈的指针?

注:在HandFault_Handler(void)中断里第一条语句打断点,进入中断后,查看LR寄存器的值,如果是0XFFFFFFF9,那么中断前使用的是MSP,如果是0XFFFFFFFD,那么中断前使用的是PSP:

中断/异常的相应序列

当CM3开始相应一个中断时,会在它看不见的体内喷涌起三股暗流:

1)入栈:把8个寄存器的值压入栈。

2)取向量:从向量表中找出对应的服务新恒旭入口地址。

3)选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接器LR,更新程序计数器PC.

另一种方法:

    默认的HardFaudler 处理方法不是死循环么?将它改成BX LR直接返回的形式。然后再这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句哪里。

_asm void wait()

{

    BX lr  //BX无条件转移指令

}

void HardFault_Handler(void)

{

    wait();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stm32