stm32触发硬件错误位置定位

news2024/11/17 23:51:42

1.背景 

1. 项目中,调试过程或者测试中都会出现程序跑飞问题,这个时候问题特别难查找。

2. 触发硬件错误往往是因为内存错误。这种问题特别难查找,尤其是产品到了测试阶段,而这个异常复现又比较难的情况下,简直头疼。

3. 我目前的工作完全是没有调试器的,代码都是写好了,通过bootloader烧写进去的。也就意味着不能在void HardFault_Handler(void)中打断点,然后通过当前lr寄存器中的值查看异常地址。

参考:

STM32进入HardFault_Handler的调试方法-电子工程世界 (eeworld.com.cn)

Keil环境下STM32定位hardfault位置方法和遇到的情况 - 张士玉小黑屋 (zhangshiyu.com)

还参考了很多文章, 有些写的时候都关掉了, 这里就不列出来了. 

2.裸机程序触发硬件错误

裸机触发硬件错误时, R14(LR)寄存器的值为0xFFFFFFF9,此时看的是MSP指针保存的栈顶地址,然后在Memory Window中输入这个值(0x20000738),第6个值就是错误退的地址(也就是我这个空指针的地址),查看.map文件,显然我们的0x080001D1在0x080001cd(my_test在flash的首地址)和0x080001d3(my_test1在flash的首地址)之间。因此我们就可以定位出错误就在my_test()这个函数中。

 也可以查看汇报,看到地址(不过这里看起来有点让人蒙圈)

3.RTOS程序触发硬件错误

 RTOS触发硬件错误时, R14(LR)寄存器的值为0xFFFFFFFD, 此时看的是PSP中的栈顶地址。同上分析,我们最终也能通过.map定位错误发生的位置。

补充知识:为什么裸机的是0xFFFFFFF9(9:1001)而多线程的是0xFFFFFFFD(1101),如下图,bit2是区别的关键,后面打印错误需要用到这一点。

4.在硬件错误中断打印这些值

我们最终的目的,就是在触发硬件中断的时候,要将这些值打印出来,从而准确定位出是哪个函数造成的错误。 

typedef struct
{
    u32 R0;
    u32 R1;
    u32 R2;
    u32 R3;
    u32 R12;
    u32 LR;
    u32 PC;
    u32 xPSR;
}STACK_DATA_TYPE;
void NotOSHardFault_Handler(u32 msp_addr)
{
    STACK_DATA_TYPE *p;             //堆栈中存储的数据

    printf("\r\n-----------------ERROR -----------------\r\nHardFault_Handler\r\n");

    p = (STACK_DATA_TYPE *)msp_addr;
    printf("R0:0x%08X\r\n", p->R0);
    printf("R1:0x%08X\r\n", p->R1);
    printf("R2:0x%08X\r\n", p->R2);
    printf("R3:0x%08X\r\n", p->R3);
    printf("R12:0x%08X\r\n", p->R12);
    printf("LR:0x%08X\r\n", p->LR);
    printf("PC:0x%08X\r\n", p->PC);
    printf("xPSR:0x%08X\r\n", p->xPSR);
    printf("系统即将复位 ...\r\n");
}

void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
int msp, psp;
    
    msp = __get_MSP();
    NotOSHardFault_Handler(msp);
    
    psp = __get_PSP();
    NotOSHardFault_Handler(psp);
    

  while (1)
  {
  }
}

当前还有一个问题需要解决, 我无法获取lr寄存器中保存的值, 也就是说我无法准确的确定是进程堆栈出错还是主堆栈出错.(我测试了发现在rtos中, 如果让错误放在main函数中, 此时MSP堆栈指向的位置是出错位置, 如果让错误放在任务中, 此时PSP堆栈指向的位置是出错位置, 如果在裸机程序中, 通过MSP查找, 当前我用的是keil编译的,我不知道IAR里面是否有__get_MSP(), __get_PSP())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1479248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CDH6.3.1离线安装

一、从官方文档整体认识CDH 官方文档地址如下: CDH Overview | 6.3.x | Cloudera Documentation CDH是Apache Hadoop和相关项目中最完整、测试最全面、最受欢迎的发行版。CDH提供Hadoop的核心元素、可扩展存储和分布式计算,以及基于Web的用户界面和重…

虚拟游戏理财【华为OD机试-JAVAPythonC++JS】

题目描述 题目描述: 在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。现有一家Bank,它提供有若干理财产品m,风险及投资回报不同,你有N(元)进行投资,能…

Python:练习:编写一个程序,录入一个美元数量(int),然后显示出增加%5税率后的相应金额。

案例: 编写一个程序,录入一个美元数量(int),然后显示出增加%5税率后的相应金额。格式如下所示: Enter an amount:100 With tax added:$105.0 思考: 1、录入一个美元数量,录入&am…

qt学习:实战 记事本 + 快捷键 + 鼠标滚轮 + 打开读取写入关闭文件

目录 功能 步骤 配置ui界面 添加图片资源 添加头文件和定义成员数据和成员函数 在构造函数里初始化 增加当前字体大小函数 减小当前字体大小函数 在用户按下 Ctrl 键的同时滚动鼠标滚轮时,执行放大或缩小操作 多选框变化后发出信号绑定槽函数来改变编码 …

flutter学习(一) 安装以及配置环境

首先需要下载flutter,然后解压 然后配置环境变量,配置到bin目录就行 配置完之后cmd运行flutter doctor 你就会发现,都是错 此时脑海里响起,卧槽,怎么回事,咋办 别着急,我教你。。。 问题 这…

【QQ案例-QQ框架-主流框架 Objective-C语言】

一、接下来,我们来做一下这个QQ, 1.接下来,我们来做一下这个QQ, QQ框架啊, 这个东西呢,我们管它叫做“主流框架”, 首先呢,要告诉大家一点,这个东西呢,我们管它,叫做“主流框架”, 算是一个简称啊, 只能说,这种框架的类型,上边儿带navigation,下边儿带tabb…

Linux centos 变更MySQL数据存储路径

Linux centos 变更MySQL数据存储路径 登录mysql,查看数据存储路径创建新目录准备迁移数据检查是否配置成功 登录mysql,查看数据存储路径 mysql -u root -pshow global variables like "%datadir%";创建新目录 查看磁盘空间 df -h选取最大磁…

论文阅读:2015ResNet深度残差网络(待补充)

top5错误率:每张图片算法都会给出它认为最可能的五个类别,五个里面有一个是正确则算法预测正确。 技术爆炸1:2012年,DL和CNN用于CV;技术爆炸2:2015年,超过人类水平,网络可以更深&…

Unity-PDF分割器(iTextSharp)

PDF分割器 Unity-PDF分割器前言核心思路解决过程一、Unity安装iTextSharp二、运行时计算将要生成文件的大小三、分割核心代码四、使用StandaloneFileBrowser五、其他的一些脚本六、游戏界面主体的构建MainWindowWarningPanel & FinishPanel By-Round Moon Unity-PDF分割器 …

Vue3 在SCSS中使用v-bind

template 先创建一个通用的页面结构 <template><div class"v-bubble-bg"></div> </template>js 在JS中先对需要用的数据进行定义&#xff1a; 可以是参数&#xff0c;也可以是data <script setup>const props defineProps({bgCol…

Linux零基础快速入门

Linux的诞生 Linux创始人:林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学期间 因为创始人在上大学期间经常需要浏览新闻和处理邮件&#xff0c;发现现有的操作系统不好用,于是他决心自己写一个保护模式下的操作系统&#xff0c;这就是Linux的原型&#xff0c;当时他…

【笔记】:更方便的将一个List中的数据传入另一个List中,避免多重循环

这里是 simpleInfoList 集合&#xff0c;记为集合A&#xff08;传值对象&#xff09; List<CourseSimpleInfoDTO> simpleInfoList courseClient.getSimpleInfoList(courseIds);if(simpleInfoListnull){throw new BizIllegalException("当前课程不存在!");}这…

[Flutter]TextButton自定义样式

在Flutter中&#xff0c;TextButton是一个简单的文本按钮&#xff0c;它遵循当前的Theme。如果你想要修改TextButton的样式&#xff0c;可以通过设置其style属性来实现&#xff0c;该属性接收一个ButtonStyle对象。 给TextButton和里面Text添加背景后&#xff0c;效果如下。可…

设计模式(二)单例模式

单例模式&#xff1a;确保一个类只有一个实例&#xff0c;并提供了全局访问点&#xff1b;主要是用于控制共享资源的访问&#xff1b; 单例模式的实现分为懒汉式和饿汉式。 懒汉式单例在需要时才会创建&#xff0c;而饿汉式单例则在类加载时立即创建实例&#xff1b; 单例模…

【精准获客,优化体验】Xinstall助力企业提升App渠道效果与用户满意度

在数字化时代&#xff0c;企业对于用户体验的重视程度日益提升。为了更好地满足用户需求&#xff0c;提供个性化、专属化的服务已经成为企业竞争的关键。今天&#xff0c;我们将向大家介绍一款名为Xinstall的一站式App全渠道统计服务商&#xff0c;它凭借强大的技术实力和丰富的…

【测试开发面试复习(一)】计算机网络:计算机网络体系结构(P1)补充ing

我每次复习的第一趴都是网络。。 一、高频面试题记录 1.1 计算机网络为什么要分层&#xff1f; 网络庞大而且复杂&#xff08;大量的软硬件系统、大量的程序和协议等&#xff09;&#xff0c;分层可提高整体结构的灵活性、将层次之间结构解耦&#xff0c;各层相互独立、隔离&…

轻松三步制作电子签名

一、在纸上签名&#xff0c;并且拍照。 二、新建空白word文档&#xff0c;使用WPS方式打开&#xff0c;再将图片复制进来。 三、点击图片&#xff0c;先选择【图片工具】中的【设置透明色】&#xff0c;然后点击签名之外的图片背景&#xff0c;即可制作为矢量图&#xff1b…

Redis 面试指南:常见问题及最佳答案

Redis 是一个高性能的键值存储系统&#xff0c;已经成为了许多企业和互联网公司的核心技术之一。本文将总结 Redis 面试中常见的问题&#xff0c;并提供最佳答案&#xff0c;以帮助读者更好地准备 Redis 面试。 引言&#xff1a; Redis 是一个开源、高性能、键值存储系统&…

朴素贝叶斯(带你从原理到实践)

目录 一、引言 二、朴素贝叶斯算法原理 1 贝叶斯定理 2 特征条件独立假设 3 分类过程 三、实践事例 四、朴素贝叶斯算法应用 1 文本分类 2 垃圾邮件过滤 3 情感分析 五、朴素贝叶斯算法未来发展 1 特征选择优化 2 半监督学习与无监督学习 3 结合深度学习 4 处理…

vue中动态引入图片

分析 很多时间&#xff0c;不管是vue2&#xff0c;还是vue3开发中都会遇到&#xff0c;动态渲染图片的功能&#xff0c;但是为什么我们直接将图片的路径直接赋值给变量的时候&#xff0c;图片渲染不出来&#xff0c;而通过require引入加载图片后却能正常渲染呢&#xff1f;主要…