HardFault_Handler异常
2022/2/22 0:14:45
本文主要是介绍HardFault_Handler异常,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Cortex-M3 双堆栈指针(MSP&PSP)
- Cortex-M3内核中有两个堆栈指针(MSP & PSP),但任何时刻只能使用到其中一个。
- 复位后处于线程模式特权级,默认使用MSP。
- 通过SP访问到的是正在使用的那个指针,可以通过MSR/MRS指令访问指定的堆栈指针。
- 通过设置CONTROL寄存器的bit[1]选择使用哪个堆栈指针。CONTROL[1]=0选择主堆栈指针;CONTROL[1]=1选择进程堆栈指针。
- Handler模式下,只允许使用主堆栈指针MSP。
双堆栈指针在OS中的应用
典型的OS环境中,MSP和PSP的用法如下:
MSP用于OS内核和异常处理。
PSP用于应用任务。
M3有两种mode:分别是handler mode和thread mode。有两种权限,分别是特权级和用户级。
那么经过组合后理论上有四种状态。
状态 | 使用条件 |
---|---|
特权级 handler mode | 异常/中断 |
用户级 handler mode | 无 |
特权级 thread mode | 应用 |
用户级 thread mode | 应用 |
特权级下用MSP,用户级用PSP。
特权级下权限很大,用户级下会有限制。
裸机下,一般不需要区分。MSP就足够用了,因为单线程的程序没必要用2个堆栈,但值得注意的一点就是,单片机进入中断时必定是用MSP,即使你当前使用的是PSP,在进入中断时单片机也会调整过来使用MSP,中断返回时再恢复,
应用在操作系统中,MSP给内核,PSP给用户。
双堆栈指针的初始化
系统复位时从0x00000000处读出MSP的初始值。
在OS初始化时,对PSP进行初始化。
PSP指针在不同任务间切换
用任务A的SP执行入栈操作,并保存任务A的SP。
设置PSP指向任务B的栈空间,用任务B的SP执行出栈,随后开始执行任务B。
HardFault_Handler异常
STM32出现硬件错误可能有以下原因:
(1)数组越界操作; (2)内存溢出,访问越界; (3)堆栈溢出,程序跑飞; (4)中断处理错误;
1、异常发生时,内核将R0~R3、R12、Return address、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址,因此在堆栈中反数第三个字即为出错位置。发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。
2、默认的HardFault_Handler处理方法是B .将它改成BX LR直接返回的形式。然后在这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句那儿。
这个有时候可能需要在反汇编模式下调试,因为可以是程序跑飞一会儿才出现HardFault_Handler。
3、还是将中断函数修改,打印中断时的一些信息:
HardFault_Hander()定义如下:
void HardFault_Handler(void) { uint32_t r_sp ; r_sp = __get_PSP(); //获取SP的值 PERROR(ERROR,Memory Access Error!); Panic(r_sp); while (1); }
发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。
如果LR寄存器中的值是0xFFFFFFF9
应该去看MSP的地址,找到该地址的地址然后如下图所示打开内存,输入上面找到的寄存器地址,右键选择以long型查看地址如下所示:
然后查看这个地址向下数六个long地址,为什么是6个long地址呢,因为由于异常发生时,内核将R0~R3、R12、Returnaddress、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址;大概是0x08xxxxxx这样开始的即为出错的代码位置,然后可以反汇编查看,如下图所示:
如果LR寄存器中的值是0xFFFFFFFD
[1] 在复杂的情况下,即使定位了异常发生位置也很难容易的改正错误,要学会使用Watch窗口对发生错误的指针变量进行跟踪;
[2]在问题不明晰的情况下,尝试分析反汇编代码,就自己遇到的,部分情况下的异常发生在BL等跳转指令处,BL跳转到了不合法的内存地址产生异常
如果还找不到问题,注释部分函数,一个函数一个函数排查了,看看是哪个函数导致的,然后在锁定问题原因。
实际操作
这篇关于HardFault_Handler异常的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16ShardingSphere 如何完美驾驭分布式事务与 XA 协议?
- 2024-11-16ShardingSphere如何轻松驾驭Seata柔性分布式事务?
- 2024-11-16Maven资料入门指南
- 2024-11-16Maven资料入门教程
- 2024-11-16MyBatis Plus资料:新手入门教程与实践指南
- 2024-11-16MyBatis-Plus资料入门教程:快速上手指南
- 2024-11-16Mybatis资料入门教程:新手必看指南
- 2024-11-16MyBatis资料详解:新手入门与初级实战指南
- 2024-11-16MyBatisPlus资料:初学者入门指南与实用教程
- 2024-11-16MybatisPlus资料详解:初学者入门指南