ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HardFault_Handler异常

2022-02-21 23:01:39  阅读:396  来源: 互联网

标签:HardFault MSP Handler mode 寄存器 堆栈 PSP 异常 指针


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,MSP,Handler,mode,寄存器,堆栈,PSP,异常,指针
来源: https://blog.csdn.net/m0_37187962/article/details/123021033

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有