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

嵌入式踩坑:printf 未重定向引发 Semihosting BKPT 异常导致 HardFault 深度排查

项目场景:

工况:移动电源进行AC充电测试。

环境:GD32F305 + FreeRTOS,故障出在 BmsManageTask 任务。


问题描述

移动电源在AC充电时偶发性出现屏幕停止刷新并在几秒后重启。

移动电源是新开发的还没有测试过稳定性。


排查步骤:

步骤一:通过问题现象大概推测导致此问题的原因。

可能的原因:1. 内存踩踏或任务栈越界导致程序进入Hardfault(),最终看门狗复位系统。

2. 喂狗任务和显示任务异常阻塞得不到运行,最终看门狗复位系统。

3. 程序不断进入中断导致喂狗任务和显示任务得不到运行,最终看门狗复位系统。

步骤二:通过增加打印日志信息、仿真或其它方式来验证复位原因。

1. 使用Cmbacktrace来排查程序异常时是否进入了Hardfault()和分析出Hardfault()的原因。

当程序进入Hardfault()时会打印进入Hardfault()的原因和进入之前的调用了那些函数。

2. 在每个业务任务入口打印独立标记,例如,温度、电压、电流采样任务:LOG_ADC; Bms通信任务:LOG_BMS;显示任务:LOG_LCD等。当某个任务被永久阻塞时它的独立 标记不会被打印。

3. 在可能连续进入的中断里添加电平翻转测试函数。当连续进入中断时电平会以极快速度进 行翻转。

步骤三: 还原当时设备运行的工况尝试复现问题。

我当时复现出问题时,设备打印了进入Hardfault()的原因和进入前的函数调用关系。

进入Hardfault()原因:

函数调用关系:

步骤四: 根据现象和打印的信息分析原因

原因分析:

进入Hardfault()的原因是程序调用printf()打印接口但程序缺失printf()串口底层重定向;标准库启用半主机机制,执行BKPT指令触发DebugFault异常,因未做对应异常拦截处理,工程未实现Debug_HardFault异常处理函数,故障级联升级进入HardFault中断,同时造成JLINK仿真会话断开。

为什么调用了printf,当时是对系统添加系统日志,使用log输出接口替换printf()函数,但是由于printf()分散在各个文件比较零散,bms的iic通信相关.c文件的printf()没有替换干净。当IIC受干扰出现偶发通信异常时,程序会调用printf()打印IIC通信异常。

补充:

1. semihosting(半主机调试):

ARM 单片机专属调试功能仅插上 JLINK 仿真器时才能正常工作作用:没有自定义串口打印时,C 标准库借助仿真器,把printf文字打印到电脑 Keil 调试控制台。 实现方式:库内部自动插入BKPT硬件断点指令和调试器通信。

2. BKPT

ARM 汇编硬件断点指令BKPT,专门给调试器用:

  • 正常调试:JLINK 识别这条指令,接收 printf 数据,程序继续跑;
  • 无仿真器 / 调试配置不对CPU 识别到 BKPT,但没人处理,直接抛出异常。

3. DebugFault

单片机内核调试专用异常,只要执行 BKPT 断点指令,就会进入这个异常。 工程没有写DebugFault_Handler专门处理半主机断点,这个异常无法正常释放。

4. 级联进入HardFault

嵌入式内核异常有优先级:DebugFault 处理失败 → 异常升级,统一进入总故障中断HardFault_Handler,这就是调试看到进 HardFault 的根本原因。


解决:

方案一:

检查工程里调用了printf()的地方,删除干净并使用log打印接口替代。

方案二:

自定实现fputc()输出函数。

http://www.cnnetsun.cn/news/4083652.html

相关文章:

  • Starward米哈游游戏启动器:抽卡、时长、账号一站式管理指南
  • 人机对比:游戏学习中的经验敏感性行为研究与应用
  • 基于层理论的多智能体系统建模:统一共识与博弈均衡的代数拓扑框架
  • 基于广义沃罗诺伊图与效用梯度的多智能体协同覆盖控制
  • 反者道之动 深度释义|联动 唯有变是不变的(无漏究竟版)
  • 怎么快速全部重命名001到100?这个方法足够了
  • 5分钟快速上手r3f-game-demo:本地运行这个开源2D游戏demo的完整教程
  • 别再混淆了:3D高斯泼溅中的“仿射近似”、透视投影与正交投影
  • 锤子助手第064个开关:字体注入网页的位置、验证方法与网页显示安全边界
  • 窗口置顶工具 Topit 实测:把 Mac 上“不听话“的窗口钉在眼前
  • 点一次鼠标省下3小时:Pulover‘s Macro Creator 免费录制式自动化快速上手
  • 微信防撤回补丁怎么装?RevokeMsgPatcher 上手手记,5 分钟讲透
  • 软文发稿投放踩坑汇总|2026四大平台实力比对推荐
  • Motrix 开源项目教程
  • 给网页请一位“动画导演“:AOS 滚动动画库完整指南
  • 适老化做一个「药盒」而不是「健康中台」|爸妈的药盒上线笔记
  • League Akari 英雄联盟助手实战清单:从倒计时超时到秒选锁定的三天体验
  • CPU 优化:物理与动画——两个“偷偷吃 CPU“的大户
  • 你的围棋AI为什么又慢又飘?手把手KataGo引擎配置与调优完整指南
  • 【2014-04-28】kali linux 安装要点笔记
  • 别让笔记烂在Zotero里:ZotCard卡片笔记实战指南
  • BMS电池管理系统核心技术解析:从硬件设计到算法策略
  • douyin-downloader 批量下载实战指南:200 个视频,从两小时缩到八分钟
  • C# 学习8.7 泛型
  • Koodo Reader 阅读设置调校指南:按场景搭出一间专属书房
  • 窗口死活拖不动、改不了大小?用 Window Resizer 强制调整窗口大小,一步到位
  • 界面控件DevExpress WinForm——轻松构建类Visual Studio UI(三)
  • Sunshine 游戏串流应用配置终极指南:从第一次添加游戏到一键流畅串流
  • 迁移学习实战思路:如何用预训练模型完成文本分类
  • 67.QT-QSharedMemory