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

STM32通过rt_hw_hard_fault_exception中的LR寄存器追溯程序问题​

1. 问题现象

程序运行导致rt_hw_hard_fault_exception

如图
在这里插入图片描述
显示错误相关代码

struct exception_stack_frame
{uint32_t r0;uint32_t r1;uint32_t r2;uint32_t r3;uint32_t r12;	uint32_t lr;	 // 链接寄存器 (LR)uint32_t pc;	// 程序计数器 (PC)uint32_t psr;	// 程序状态寄存器 (PSR)
};void rt_hw_hard_fault_exception(struct exception_stack_frame *contex)
{Fm24cl64bInit();
//	static struct exception_stack_frame test;static CoreRegister_Type s_error_save;
//	test = *contex;   s_error_save.r0 = contex->r0;s_error_save.r1 = contex->r1;s_error_save.r2 = contex->r2;s_error_save.r3 = contex->r3;s_error_save.r12 = contex->r12;s_error_save.lr = contex->lr;s_error_save.pc = contex->pc;s_error_save.psr = contex->psr;uint8_t save_res = WriteCoreRegisterToEeprom(&s_error_save);lcd_Init();lcd_Init_PowerOn();lcd_Init_BackLight(1);lcd_BufferClear();lcd_BufferPrint(0, 0, 16, "R0:0x%08X  R1:0x%08X", s_error_save.r0, s_error_save.r1);lcd_BufferPrint(0, 2, 16, "R2:0x%08X  R3:0x%08X", s_error_save.r2, s_error_save.r3);lcd_BufferPrint(0, 4, 16, "R12:0x%08X LR:0x%08X", s_error_save.r12, s_error_save.lr);lcd_BufferPrint(0, 6, 16, "PC:0x%08X PSR:0x%08X", s_error_save.pc, s_error_save.psr);lcd_BufferPrint(0, 8, 16, "save_res:%d", save_res);lcd_BufferPrint(0, 10, 16, "Dst:%d 1st:%d 2st:%d", msg.MsgDstId, msg.FirstSubId, msg.SecondSubId);lcd_ScreenRefresh();while(1);
}

2. 问题分析

在ARM Cortex-M架构中,LR (Link Register, R14) 的值在HardFault或其他异常发生时,对追溯问题根源非常关键。
LR—保存函数返回地址

3. 问题追溯

1. 定位触发HardFault的代码位置

通过 LR:0x08009B47 找到对应的代码位置
使用调试器(如ST-Link + IDE)直接跳转到该地址。在这里插入图片描述
​​

2. 分析LR地址附近的代码

常见触发HardFault的操作:

  • 访问非法地址(野指针、数组越界)。
  • 未对齐的内存访问(如对非4字节对齐地址执行LDR)。
  • 堆栈溢出(检查线程栈大小是否足够)。
  • 错误的函数指针调用(如跳转到无效地址)

在这里插入图片描述
这里的LPTIM1_IRQ_callback是个空指针,最终导致硬件错误。

http://www.xdnf.cn/news/10078.html

相关文章:

  • 深圳南山沙河社区联合心美行动举办“青少年天赋提升”助青春成长
  • 用于工业设备的高精度仪表放大器“NL9620”开始上市~日本首家!高EMC性能的仪表放大器
  • 使用matlab读取txt文件中的2进制数据
  • 文字转图片的字符画生成工具
  • JavaScript 计算两个日期之间天数的全面指南
  • [网页五子棋][对战模块]前后端交互接口(建立连接、连接响应、落子请求/响应),客户端开发(实现棋盘/棋子绘制)
  • 将Kotti从Pyramid1.0升级到2.0 (失败的记录)
  • CATIA高效工作指南——测量分析篇(一)
  • C++ TCP程序增加TLS加密认证
  • Java本地缓存实现方案全解析:原理、优缺点与应用场景
  • C/C++ 面试复习笔记(2)
  • 漫画Android:事件分发的过程是怎样的?
  • JS数组 concat() 与扩展运算符的深度解析与最佳实践
  • MySQL + CloudCanal + Iceberg + StarRocks 构建全栈数据服务
  • 单元测试报错
  • 由反汇编代码确定结构体的完整声明
  • 调试技巧总结
  • SAP 生产订单收货数量超额报错问题研究
  • 《java创世手记》---java基础篇(上)
  • 【Linux基础知识系列】第五篇-软件包管理
  • Ubuntu本地文件上传github(版本控制)
  • 常见压缩算法性能和压缩率对比 LZ4 LZO ZSTD SNAPPY
  • Haproxy搭建web群集
  • WWW22-可解释推荐|用于推荐的神经符号描述性规则学习
  • 【免费的高清录屏软件】OBS Studio
  • 架构加速-深度学习教程
  • A类地址中最小网络号(0.x.x.x) 默认路由 / 无效/未指定地址
  • Qt中使用正则表达式来提取字符串
  • 第100+41步 ChatGPT学习:R语言实现误判病例分析
  • Windows 权限提升 | TryHackMe | Windows Privilege Escalation