HardFault_Handler异常

2023-11-17

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跳转到了不合法的内存地址产生异常

如果还找不到问题,注释部分函数,一个函数一个函数排查了,看看是哪个函数导致的,然后在锁定问题原因。

实际操作

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HardFault_Handler异常 的相关文章

随机推荐

  • 关于js报错 Cannot read property innerHTML of null和关于Cannot set property ‘innerHTML’ of null 错误原因

    解决关于js报错 Cannot read property innerHTML of null 1 相信很多同学在开发过程中都会遇到 Cannot read property innerHTML of null 这个报错的字面含义是 不能读
  • 前端文件下载的八种方法(解决pdf、图片在浏览器自动打开问题)

    系列文章目录 现在流行的chrom 和火狐浏览器 都会将图片和文档自动打开 图片自动打开的问题已经解决 请看第三条 提示 下面代码中会用到a标签中 target 会添加一个 view window 的属性 如果想要详细了解a标签的属性 可以
  • rabbitMQ初识

    消息队列 RabbitMQ 认识MQ 同步和异步通讯 微服务间通讯有同步和异步两种方式 同步通讯 就像打电话 需要实时响应 异步通讯 就像发邮件 不需要马上回复 同步通讯 同步调用的优点 时效性较强 可以立即得到结果 同步调用的问题 耦合度
  • C++之多重继承

    大多数应用程序使用单个基类的公用继承 但是在某些情况下 单继承是不够的 必须使用多继承 C 允许为一个派生类指定多个基类 这样的继承结构被称做多重继承 举个例子 交通工具类可以派生出汽车和船连个子类 但拥有汽车和船共同特性水陆两用汽车就必须
  • 使用Android studio开发第一个小程序

    1 点击新建安卓项目 填入项目名称 公司域 项目的修饰 项目路径 若不存在 会新建一个路径 下面两个不要选 点击下一步 2 接下来就是项目配置了 在这里我们只勾选第一个 适配的手机系统最小sdk版本 目前经常用的是API 17 当然你也可以
  • 深入理解浏览器缓存机制 ( http )

    一 介绍 http缓存 浏览器根据当前http请求报文策略 将网路资源存储到本地内存 memory cache 硬盘 disk cache 中 缓存流程 浏览器 浏览器缓存 服务端 发起请求 根据缓存
  • dns服务器经赏要修复,十要诀帮你修复DNS域名解析服务故障

    十个要诀帮你修复DNS故障 1 DNS是网络基础协议之一 想必大家都应该有所了解 对于所有基于Windows系统的网络来说 DNS都属于最重要的服务之一 在没有DNS支持的情况下 活动目录就不能正常工作 并且它使用到的功能也比任何其它类型的
  • 【C++】赋值运算符重载的返回值分析

    转载 https blog csdn net Always article details 50532323 其实对于重载赋值运算符 返回值是引用或者不是都行 代码都可以运行 之所以用引用是为了提高代码效率 为什么引用就会提高代码效率呢 对
  • 使用docker-maven-plugin插件构建镜像并推送至私服Harbor

    前言 如下所示 建议使用 Dockerfile Maven 插件 但该插件也停止维护更新了 因此先暂时使用docker maven plugin插件 一 开启Docker服务器的远程访问 1 1 开启2375远程访问 默认的dokcer是不
  • b+树和b树的区别

    B 树和B 树是两种在数据库索引实现中经常使用的平衡树 在实际应用中被广泛采用 B 树和B 树都是基于平衡树的数据结构 用来实现数据的索引和查找 它们都支持对数据的插入 删除和查找等操作 并且可以在较短的时间内完成数据的查找和遍历等操作 但
  • 13张图,带大家深入理解Synchronized

    目录 前言 内容大纲 Synchronized使用方式 普通函数 静态函数 代码块 Synchronized原理 Synchronized优化 锁粗化 锁消除 锁升级 偏向锁 轻量级锁 重量级锁 前言 Java并发编程系列第二篇Synchr
  • “用户登录”测试用例总结

    前言 作为测试工程师 你的目标是要保证系统在各种应用场景下的功能是符合设计要求的 所以你需要考虑的测试用例就需要更多 更全面 鉴于面试中经常会问 如何测试用户登录 我们利用等价类划分 边界值分析等设计一些测试用例 显式功能性需求测试用例 1
  • 牛客网C++项目课件资料

    1 Linux系统编程入门 2 Linux多进程 3 Linux多线程 4 Linux网络编程
  • Unity3D 地形(Terrain)设置

    这篇说的是Unity地形 关于Unity3D是什么 我就不多做解释了 由于工作原因 该系列原创教程不定期更新 每月必然有更新 谢谢各位 Unity地形 新建地形 如图在菜单中新建一个地形 就会在 中看到Terrain对象 如果要修改地形参数
  • 一文读懂数据安全分级分类

    目录 为什么要分级分类 通用数据分级分类框架 数据分类 数据分类的常用方法 数据分类流程 数据分级 数据分级的常用方法 数据定级流程 行业数据安全分级分类指南 金融行业 电信行业 政务数据 健康医疗 企业实践 附录 数据分级分类大合集 为什
  • MySQL——数据类型DECIMAL用法

    DECIMAL数据类型用于要求非常高的精确度的计算中 像坐标 钱这样的数据 对于精度要求高的 可以采用decimal来进行存储 用法 DECIMAL P D P是表示有效数字数的精度 P范围为1 65 D是表示小数点后的位数 D的范围是0
  • 在线画图工具

    转自 常用9款在线作图工具 总有一款适合你 shenhangyu1989的博客 CSDN博客 在线画图 最近想在团队里使用在线作图工具 使用的在线工具的原因是 一来免得大家再安装本地软件 二来在线工具在多人共享 团队协作方面的优势更大 再者
  • Flume 学习

    开始启动flume的学习 todo
  • 提示 需要 Oracle 客户端软件 8.1.7 或更高版本 解决方案

    一 问题 1 使用第三方接口连接Oracle数据库 程序内调用接口提示 需要 Oracle 客户端软件 8 1 7 或更高版本 网上看了很多答案 依然不起效果 在公司前辈指点下 终得以找到解决办法 2 数据库 Oracle 11g 二 解决
  • HardFault_Handler异常

    Cortex M3 双堆栈指针 MSP PSP Cortex M3内核中有两个堆栈指针 MSP PSP 但任何时刻只能使用到其中一个 复位后处于线程模式特权级 默认使用MSP 通过SP访问到的是正在使用的那个指针 可以通过MSR MRS指令