当前位置: 首页 > news >正文

STM32 产生Hard Fault 调试方法

STM32 产生hard-fault 调试方法

需求

当STM32 产生Hard Fault的时候我们希望可以打印出一些重要的寄存器信息,然后定位代码出错的地方。

参考

https://github.com/ferenc-nemeth/arm-hard-fault-handler

原理

STM32代码运行的时候一般在是main函数while(1)中循环的运行代码,在运行代码的过程中突然发生了Hard Fault错误,则会产生一个中断。中断产生的时候CPU会将一些重要的寄存器压入栈中,这个动作是CPU自动运行的,无需代码控制。那么我们就可以在中断的服务函数里面获取栈的地址,然后将重要的寄存器信息打印出来即可。
备注:STM32有两个栈指针,分别是MSP和PSP,所以在HardFault_Handler中需要判断产生中断之前使用的是MSP还是PSP。

下面是核心代码。
void HardFault_Handler(void)
{__asm volatile("TST    LR, #0b0100;      ""ITE    EQ;               "			   //判断堆栈指针使用的是MSP还是PSP。"MRSEQ  R0, MSP;          "              // 如果是MSP则将MSP的值放在R0,作为ReportHardFault函数的第一个参数。"MRSNE  R0, PSP;          "			  // 如果是MSP则将MSP的值放在R0,作为ReportHardFault函数的第一个参数。"MOV    R1, LR;           "			    // 将LR的值放在R1寄存器,作为ReportHardFault函数的第二个参数。"B      ReportHardFault;  "             //跳转到ReportHardFault函数,在这个函数可以打印出产生hard fault时候的堆栈信息。);
}备注:
1、LR保存的是产生中断的时候CPU下一步要执行的指令,可以通过使用 BX LR 指令返回,这会触发硬件恢复之前保存的上下文。
2、在STM32中,产生中断的时候,CPU会将一些重要的寄存器数据压入堆栈中,这些寄存器是r0、r1、r2、r3、r12、lr、pc、psr。
所以我们HardFault_Handler中断函数中第一时间就获取SP的值,从而找到产生中断的时候堆栈的指针的值是多少,
从而打印出产生Hard Fault时候代码运行到那里。void ReportHardFault(uint32_t *stack_frame, uint32_t exc)
{uint32_t r0   = stack_frame[0];			//备注:stack_frame是产生中断的时候,将重要的寄存器压栈后的地址。uint32_t r1   = stack_frame[1];uint32_t r2   = stack_frame[2];uint32_t r3   = stack_frame[3];uint32_t r12  = stack_frame[4];uint32_t lr   = stack_frame[5];uint32_t pc   = stack_frame[6];uint32_t psr  = stack_frame[7];uint32_t hfsr = SCB->HFSR;     //这是重要的错误寄存器信息,可以查找数据手册知道产生什么错误。uint32_t cfsr = SCB->CFSR;uint32_t mmar = SCB->MMFAR;uint32_t bfar = SCB->BFAR;uint32_t afsr = SCB->AFSR;//下面的代码将堆栈的信息打印出来。
}

背景知识补充

MSP 和 PSP

在 STM32 微控制器中,MSP(Main Stack Pointer)和 PSP(Process Stack Pointer)是两个用于管理堆栈的指针。它们是 ARM Cortex-M 处理器架构的一部分,用于在不同模式下进行堆栈操作管理。

MSP(Main Stack Pointer)

MSP(Main Stack Pointer) 是主堆栈指针。
通常用于系统模式或特权模式下的堆栈操作。
在复位后,处理器默认使用 MSP 作为堆栈指针。
一般情况下,操作系统或裸机程序中的中断服务程序和异常处理程序使用 MSP。

PSP(Process Stack Pointer)

PSP(Process Stack Pointer) 是进程堆栈指针。
通常用于用户模式或线程模式下的堆栈操作。
在使用操作系统(例如 FreeRTOS)时,每个任务或线程可以使用 PSP 进行独立的堆栈管理,从而实现任务的隔离。
PSP 允许应用程序在不同的模式下使用不同的堆栈,提供更好的灵活性和安全性。

相关文章:

STM32 产生Hard Fault 调试方法

STM32 产生hard-fault 调试方法 需求 当STM32 产生Hard Fault的时候我们希望可以打印出一些重要的寄存器信息,然后定位代码出错的地方。 参考 https://github.com/ferenc-nemeth/arm-hard-fault-handler 原理 STM32代码运行的时候一般在是main函数while(1)中循…...

java-selenium 截取界面验证码图片并对图片文本进行识别

参考链接 1、需要下载Tesseract工具并配置环境变量&#xff0c;步骤如下 Tesseract-OCR 下载安装和使用_tesseract-ocr下载-CSDN博客 2、需要在IDEA中导入tess4j 包&#xff1b;在pom.xml文件中输入如下内容 <!--导入Tesseract 用于识别验证码--><dependency>&l…...

【Linux】进程信号 --- 信号产生

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…...

Docker 容器中的 Docker Compose 简介

Docker Compose是什么 Docker Compose是一个用于定义和运行多个Docker容器的工具。它是Docker官方提供的开源项目&#xff0c;用于实现对Docker容器集群的快速编排。通过Compose&#xff0c;开发者可以使用YAML文件&#xff08;通常是docker-compose.yml文件&#xff09;来配置…...

手机日历如何与Outlook同步

有很多人和我一样遇到手机日历与Outlook同步问题&#xff0c;如新版outlook与小米日历的同步问题 - Microsoft Community&#xff0c;outlook账号无法在手机端自带的电子邮件App以exchange模式登录 - Microsoft Community&#xff0c;在安卓手机端无法电子邮件App以exchange模式…...

python基础语法 007 文件操作-1读取写入

1 文件操作 1.1 什么时候用文件操作&#xff1f; 打开文档写东西看东西拿文档做统计 在python 文档操作作用 存储数据读取数据 打开文件有什么用&#xff1f; 读取数据&#xff0c;写入数据不管什么数据都可以用open打开&#xff0c;如可复制一张图片 1.2 open() 读取,…...

C语言·函数(超详细系列·全面总结)

前言&#xff1a;Hello大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;为了更好地形成一个学习c语言的体系&#xff0c;最近将会更新关于c语言语法基础的知识&#xff0c;今天更新一下函数的知识点&#xff0c;我们一起来看看吧&#xff01; 目录 一、函数是什么 &a…...

Windows及Linux系统加固

君衍. 一、Windows加固1、配置简介2、账户配置3、本地配置4、安全设置 二、Linux加固1、配置简介2、网络配置3、日志和审计配置4、访问认证和授权配置5、系统运维配置 一、Windows加固 1、配置简介 通常在Windows安全配置中有两类对象 一类是Windows Server&#xff0c;如win …...

Postman安装使用教程(详解)

目录 一、Postman是什么 二、安装系统要求 三、下载Postman 四、注册和登录Postman 五、创建工作空间 六、创建请求 一、Postman是什么 在安装之前&#xff0c;让我们先来简单了解一下Postman。Postman是一个流行的API开发工具&#xff0c;它提供了友好的用户界面用于发送…...

【嵌入式开发之标准I/O】文件I/O的基本概念,打开、关闭、定位函数及实例

文件I/O和标准I/O 什么是文件I/O?什么是标准I/O? 文件I/O&#xff1a;文件I/O又称系统IO&#xff0c;系统调用&#xff0c;称之为不带缓存的IO&#xff08;unbuffered I/O)。是操作系统提供的API接口函数。不带缓存指的是每个read&#xff0c;write都调用内核中的一个系统调…...

C++文件操作-文本文件-读文件

第一种 #include<iostream>//1、包含头文件 fstream #include<fstream> using namespace std;void test01() {//2、创建流对象ifstream ifs;//3、打开文件 并且判断是否打开成功ifs.open("test.txt", ios::in);if (!ifs.is_open()){cout << "…...

二叉树精选面试题

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ 1. 相同的树 100. 相同的树 同时遍历两棵树 判断结构相同&#xff1a;也就是在遍历的过程中&#xff0c;如果有一个节点为null&#xff0c;另一棵树的节点不为null&#xff0c;那么结构就不相同 判断值相同&#xff1a;只需…...

如何在 Android 中删除和恢复照片

对于智能手机用户来说&#xff0c;相机几乎已经成为一种条件反射&#xff1a;你看到值得注意的东西&#xff0c;就拍下来&#xff0c;然后永远保留这段记忆。但如果那张照片不值得永远保留怎么办&#xff1f;众所周知&#xff0c;纸质快照拿在手里很难舍弃&#xff0c;而 Andro…...

HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(六)

一、仅支持一个静态块 规则&#xff1a;arkts-no-multiple-static-blocks 级别&#xff1a;错误 ArkTS不允许类中有多个静态块&#xff0c;如果存在多个静态块语句&#xff0c;请合并到一个静态块中。 TypeScript class C {static s: stringstatic {C.s aa}static {C.s C.s …...

功能测试与APPSCAN自动化测试结合的提高效率测试策略

背景 手工探索性测试&#xff08;Manual Exploratory Testing&#xff0c;简称MET&#xff09;是一种软件测试方法&#xff0c;它依赖于测试人员的直觉、经验和即兴发挥来探索应用程序或系统。与传统的脚本化测试相比&#xff0c;手工探索性测试不遵循固定的测试脚本&#xff0…...

AVL树的理解和实现[C++]

文章目录 AVL树AVL树的规则或原理 AVL树的实现1.节点的定义2.功能和接口等的实现默认构造函数&#xff0c;析构函数拷贝构造函数插入搜索打印函数检查是否为平衡树&#xff0c;检查平衡因子旋转 AVL树 AVL树&#xff0c;全称Adelson-Velsky和Landis树&#xff0c;是一种自平衡…...

云计算遭遇的主要安全威胁

以下是详细说明云计算遭遇的所有主要安全威胁&#xff1a; 1. 数据泄露 描述&#xff1a;数据泄露是指未经授权的情况下访问和获取敏感数据。云计算环境中的数据泄露通常由于不安全的配置、软件漏洞或内部威胁造成。 案例&#xff1a; Capital One数据泄露&#xff1a;2019…...

[MySQL]02 存储引擎与索引,锁机制,SQL优化

Mysql存储引擎 可插拔式存储引擎 索引是在存储引擎底层上实现的 inno DB MySQL默认存储引擎: inno DB高可靠性和高性能的存储引擎 DML操作遵循ACID模型支持事务行级锁,提高并发访问性能支持外键 约束,保证数据完整性和可靠性 MySAM MySAM是MySQL的早期引擎 特点: 不支持事…...

ld,GNU 链接器介绍以及命令行参数详解

ld&#xff0c;GNU 链接器介绍以及命令行参数详解 当我们使用GCC编译源代码生成可执行程序&#xff0c;经过预处理、汇编、编译、链接四个阶段。 链接器&#xff08;Linker&#xff09;将多个目标文件和库文件链接起来&#xff0c;链接器还解决目标文件之间的符号引用&#xff…...

[web]-反序列化-base64

看到源码 <?php error_reporting(0); class A {public $contents "hello ctfer";function __toString(){if ((preg_match(/^[a-z]/i,$this->contents))) {system("echo $this->contents");return 111;}else{return "...";}} }functi…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...