STM32查找HardFault_Handler问题

 

出现问题的现象

在用Keil对STM32的程序进行仿真时,程序有时候回跑飞,停止仿真程序会停在HardFault_Handler函数里的死循环while(1)中。这说明STM32出现了硬件错误。


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

 

  1. 内存溢出或者访问越界。
  2. 堆栈溢出。

出现问题后查找问题点的方法

方法1:

① 发生异常后先查看LR寄存器中的值,确定当时使用堆栈为MSP还是PSP。

寄存器组介绍

处理器拥有R0-R15的寄存器组,其中R13为堆栈指针SP,SP有两个,但是同一时刻只能有一个可以看到,这就是所谓的“banked”(影子)寄存器。
a、R0-R12都是 32位通用寄存器,用于数据操作。但是注意:绝大多数 16位Thumb指令只能访问R0-R7,而 32位 Thumb-2指令可以访问所有寄存器,函数调用时的形参和局部变量被压入在其中。         

b、Cortex-M3拥有两个堆栈指针,然而它们是 banked,因此任一时刻只能使用其中的一个。 
  主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程) 
  进程堆栈指针(PSP):由用户的应用程序代码使用。堆栈指针的最低两位永远是0,这意味着堆栈总是4字节对齐的。 

c、R14:连接寄存器(LR)当呼叫一个子程序时,由R14存储返回地址          

d、R15:程序计数寄存器(PC)指向当前的程序地址,如果修改它的值,就能改变程序的执行流(这里有很多高级技巧)          

e、Cortex-M3还在内核水平上搭载了若干特殊功能寄存器,包括程序状态字寄存器组(PSRs)中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI) 
控制寄存器(CONTROL)

在Keil菜单栏点击【view】->【Registers Window】打开寄存器窗口,查看 R14(LR) 的值。
若R14(LR) = 0xFFFFFFE9, 查看 MSP(主堆栈指针)的值;
若R14(LR) = 0xFFFFFFFD, 查看 PSP(进程栈指针)的值。


------------------------------------- 图 2 -------------------------------------
上图的R14(LR) = 0xFFFF FFFD,则查看 PSP(进程栈指针)的值。

 

② 找到相应堆栈的指针,在内存中查看相应堆栈里的内容。

由于异常发生时,内核将R0~R3、R12、R14(LR)、PC、XPRS寄存器依次入栈,其中R14(LR)即为发生异常前PC将要执行的下一条指令地址。
注意:寄存器均是32位、且STM32是小端模式(高位在后面,逆序读)。(参考Cortex_M3权威指南)



------------------------------------- 图 3 -------------------------------------

从 图2 可看到SP的值为 0x20000B2C,在Keil菜单栏点击【view】->【Memory Windows】->【Memory1】,在【Address】地址栏中输入SP的值 0x20000B2C,然后查看堆栈里面的值依次是 R0~R3、R12、R14(LR)、PC、XPRS。


------------------------------------- 图 4 -------------------------------------
显然堆栈后第21个字节到24字节即为LR,图4显示该地址为0x08005907 即为异常前PC将要执行的下一条指令地址。

 

③ 找到将要执行下一条指令的位置

在Keil菜单栏中点击【view】->【Disassembly Window】,在【Disassembly Window】窗口中右击,在下拉菜单中选择【Show Disassembly at Address...】。在弹出框【Show Code at Address】的地址框中输入地址 0x08005907 进行搜索,然后就会找到相对应的代码。


------------------------------------- 图 5 -------------------------------------

 

方法2

① 在中断函数HardFault_Handler里的while(1)处打个断点


------------------------------------- 图 6 -------------------------------------

 

② 返回到出错的函数位置

在Keil菜单栏点击【view】->【Call Stack Window】,弹出【Call Stack + Locals】对话框,右键点击对话框中的【HardFault_Handler】,选择【Show Caller Code】,就会跳到出错的函数位置。


------------------------------------- 图 5 -------------------------------------

  • 6
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值