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工具并配置环境变量,步骤如下 Tesseract-OCR 下载安装和使用_tesseract-ocr下载-CSDN博客 2、需要在IDEA中导入tess4j 包;在pom.xml文件中输入如下内容 <!--导入Tesseract 用于识别验证码--><dependency>&l…...
【Linux】进程信号 --- 信号产生
👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…...
Docker 容器中的 Docker Compose 简介
Docker Compose是什么 Docker Compose是一个用于定义和运行多个Docker容器的工具。它是Docker官方提供的开源项目,用于实现对Docker容器集群的快速编排。通过Compose,开发者可以使用YAML文件(通常是docker-compose.yml文件)来配置…...
手机日历如何与Outlook同步
有很多人和我一样遇到手机日历与Outlook同步问题,如新版outlook与小米日历的同步问题 - Microsoft Community,outlook账号无法在手机端自带的电子邮件App以exchange模式登录 - Microsoft Community,在安卓手机端无法电子邮件App以exchange模式…...
python基础语法 007 文件操作-1读取写入
1 文件操作 1.1 什么时候用文件操作? 打开文档写东西看东西拿文档做统计 在python 文档操作作用 存储数据读取数据 打开文件有什么用? 读取数据,写入数据不管什么数据都可以用open打开,如可复制一张图片 1.2 open() 读取,…...
C语言·函数(超详细系列·全面总结)
前言:Hello大家好😘,我是心跳sy,为了更好地形成一个学习c语言的体系,最近将会更新关于c语言语法基础的知识,今天更新一下函数的知识点,我们一起来看看吧! 目录 一、函数是什么 &a…...
Windows及Linux系统加固
君衍. 一、Windows加固1、配置简介2、账户配置3、本地配置4、安全设置 二、Linux加固1、配置简介2、网络配置3、日志和审计配置4、访问认证和授权配置5、系统运维配置 一、Windows加固 1、配置简介 通常在Windows安全配置中有两类对象 一类是Windows Server,如win …...
Postman安装使用教程(详解)
目录 一、Postman是什么 二、安装系统要求 三、下载Postman 四、注册和登录Postman 五、创建工作空间 六、创建请求 一、Postman是什么 在安装之前,让我们先来简单了解一下Postman。Postman是一个流行的API开发工具,它提供了友好的用户界面用于发送…...
【嵌入式开发之标准I/O】文件I/O的基本概念,打开、关闭、定位函数及实例
文件I/O和标准I/O 什么是文件I/O?什么是标准I/O? 文件I/O:文件I/O又称系统IO,系统调用,称之为不带缓存的IO(unbuffered I/O)。是操作系统提供的API接口函数。不带缓存指的是每个read,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 << "…...
二叉树精选面试题
💎 欢迎大家互三:2的n次方_ 1. 相同的树 100. 相同的树 同时遍历两棵树 判断结构相同:也就是在遍历的过程中,如果有一个节点为null,另一棵树的节点不为null,那么结构就不相同 判断值相同:只需…...
如何在 Android 中删除和恢复照片
对于智能手机用户来说,相机几乎已经成为一种条件反射:你看到值得注意的东西,就拍下来,然后永远保留这段记忆。但如果那张照片不值得永远保留怎么办?众所周知,纸质快照拿在手里很难舍弃,而 Andro…...
HarmonyOS Next原生应用开发-从TS到ArkTS的适配规则(六)
一、仅支持一个静态块 规则:arkts-no-multiple-static-blocks 级别:错误 ArkTS不允许类中有多个静态块,如果存在多个静态块语句,请合并到一个静态块中。 TypeScript class C {static s: stringstatic {C.s aa}static {C.s C.s …...
功能测试与APPSCAN自动化测试结合的提高效率测试策略
背景 手工探索性测试(Manual Exploratory Testing,简称MET)是一种软件测试方法,它依赖于测试人员的直觉、经验和即兴发挥来探索应用程序或系统。与传统的脚本化测试相比,手工探索性测试不遵循固定的测试脚本࿰…...
AVL树的理解和实现[C++]
文章目录 AVL树AVL树的规则或原理 AVL树的实现1.节点的定义2.功能和接口等的实现默认构造函数,析构函数拷贝构造函数插入搜索打印函数检查是否为平衡树,检查平衡因子旋转 AVL树 AVL树,全称Adelson-Velsky和Landis树,是一种自平衡…...
云计算遭遇的主要安全威胁
以下是详细说明云计算遭遇的所有主要安全威胁: 1. 数据泄露 描述:数据泄露是指未经授权的情况下访问和获取敏感数据。云计算环境中的数据泄露通常由于不安全的配置、软件漏洞或内部威胁造成。 案例: Capital One数据泄露:2019…...
[MySQL]02 存储引擎与索引,锁机制,SQL优化
Mysql存储引擎 可插拔式存储引擎 索引是在存储引擎底层上实现的 inno DB MySQL默认存储引擎: inno DB高可靠性和高性能的存储引擎 DML操作遵循ACID模型支持事务行级锁,提高并发访问性能支持外键 约束,保证数据完整性和可靠性 MySAM MySAM是MySQL的早期引擎 特点: 不支持事…...
ld,GNU 链接器介绍以及命令行参数详解
ld,GNU 链接器介绍以及命令行参数详解 当我们使用GCC编译源代码生成可执行程序,经过预处理、汇编、编译、链接四个阶段。 链接器(Linker)将多个目标文件和库文件链接起来,链接器还解决目标文件之间的符号引用ÿ…...
[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…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
用js实现常见排序算法
以下是几种常见排序算法的 JS实现,包括选择排序、冒泡排序、插入排序、快速排序和归并排序,以及每种算法的特点和复杂度分析 1. 选择排序(Selection Sort) 核心思想:每次从未排序部分选择最小元素,与未排…...
