MCU 软件断点调试注意事项!!!

——为什么调试器会在运行中改我的Flash程序?

调试单片机时,很多人都有这样的疑问:

明明我在调试前刷进去的固件是好的,为什么加了一个断点之后,调试器居然去改了 Flash?
如果我拔掉调试器,这个固件还能正常跑吗?

今天我们就来完整讲一讲**软件断点(Software Breakpoint)**的原理,以及它和 MCU Flash 之间的关系。


1. 什么是断点?

调试器要让程序在某一行停下来,有两种方法:

断点类型原理数量限制速度是否改写代码
硬件断点利用 MCU 内部的 FPB(Flash Patch and Breakpoint) 单元,在指令地址匹配时自动中断一般 4~6 个极快
软件断点直接把目标指令改成一条特殊的“陷阱指令”(如 BKPT理论无限(可写内存)RAM 中快,Flash 中慢

 

所以,ST-Link / J-Link / DAPLink 这些调试器本质上都一样,只是硬件断点数量受 MCU 限制,而软件断点理论上可以很多,但需要改写代码。


2. 软件断点的工作原理

以 ARM Cortex-M 为例,软件断点的流程是这样的:

  1. 下断点
    调试器接收到“在地址 0x08001234 停下来”的指令。

  2. 备份原指令
    从 MCU 读出该地址的机器码(2 字节或 4 字节),保存到调试器内存。

  3. 写入陷阱指令
    将该位置改成 BKPT #imm(机器码通常是 0xBE00)。

  4. 运行时触发异常
    CPU 执行到 BKPT → 进入 Debug 模式 → 调试器接管。

  5. 恢复原指令
    当你“移除断点”或“单步执行”时,调试器把原机器码写回去。

关键点

  • 如果断点地址在 RAM 中,直接写就行,很快,也不会磨损。

  • 如果断点地址在 Flash 中,就必须擦除整页 → 改一条指令 → 回写整页,这会稍微慢一些,还会增加 Flash 擦写次数。


3. 为什么调试器会改 Flash?

因为软件断点就是修改原程序的一个过程。

  • 硬件断点不改代码,但数量有限。

  • 软件断点数量无限,但需要替换原来的指令为 BKPT。

  • 在 Flash 中替换指令 → 必须擦写 Flash。

这也解释了两个现象:

  1. 加 Flash 断点有延迟:那是擦写 Flash 的时间(几十到几百微秒)。

  2. 断点太多可能会磨损 Flash:虽然调试时次数不多,但确实有写入动作。


4. 调试结束后的风险

大多数调试器在结束调试时,会自动恢复原指令
但在以下情况可能会残留 BKPT:

  • IDE / 调试器崩溃;

  • 直接拔掉 USB / 断电;

  • 固件编译时手动写了 __BKPT(),且 Release 版没屏蔽。

如果 BKPT 留在 Flash 里,MCU 在无调试器连接的情况下运行到这里:

  • 会触发 HardFaultDebug Monitor Exception

  • 如果程序没有异常处理,就会直接死机。


5. 如何避免死机

  1. 发布版本不用软件断点
    确保 Release 固件是干净的,不带调试指令。

  2. 异常处理里跳过 BKPT
    在 HardFault Handler 中检查指令,如果是 BKPT,就跳过它:

    void HardFault_Handler(void) {uint32_t *pc = (uint32_t *)__get_MSP();if (*(uint16_t *)(*pc) == 0xBE00) { // BKPT*pc += 2; // 跳过断点指令return;}while (1); // 其他错误
    }
    

     

  3. 调试结束前移除断点
    养成好习惯,不要让调试器崩溃时处于有断点的状态。


6. 总结

  • 硬件断点:靠 MCU 内部比较器实现,不改代码,速度快但数量有限。

  • 软件断点:通过改指令(RAM 直接写,Flash 要擦写)实现,数量无限但会改程序。

  • 调试结束时如果 BKPT 没被恢复,独立运行可能直接死机。

  • 最安全的做法是:发布固件前移除所有软件断点,并做好异常处理。

 

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

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

相关文章

启发式合并 + 莫队 恋恋的心跳大冒险

题目来源:2025 Wuhan University of Technology Programming Contest 比赛链接:Dashboard - 2025 Wuhan University of Technology Programming Contest - Codeforces 题目大意: Solution: 首先肯定要预处理出以每个节点为起点…

JCTools 无锁并发队列基础:ConcurrentCircularArrayQueue

ConcurrentCircularArrayQueue ConcurrentCircularArrayQueue 是一个抽象类,它为基于数组的并发循环队列提供了基础功能。从其命名可以看出几个关键特性:​​Concurrent​​:常指无锁并发。​​Circular Array​​:内部使用循环数…

力扣(LeetCode) ——622. 设计循环队列(C语言)

题目:622. 设计循环队列示例1: MyCircularQueue circularQueue new MyCircularQueue(3); // 设置长度为 3 circularQueue.enQueue(1); // 返回 true circularQueue.enQueue(2); // 返回 true circularQueue.enQueue(3); // 返回 true circularQueue.…

在JVM跑JavaScript脚本 | Oracle GraalJS 简介与实践

这是2024年初的 GraalVM 系列博文,当时写了大纲,知道一年半后的现在才得以完成发布😄 1、概述 实话说,标题的场景为小众需求,日常开发基本用不到,我是最近在做一个低代码轮子玩具 app-meta 需要实现 FaaS&…

基于 EC 数据与大模型技术实现天气预报:从数据到上线的全栈方法

1. 先校准“EC 数据”与“AI 预报”的语境 EC 数据家族(常用) IFS/HRES:确定性全球模式,水平分辨率约 9 km,常用预报范围 10 天; IFS/ENS:51 成员集合预报,提供 15 天概率信息; ERA5:再分析数据,小时级、0.25,可追溯至 1940 年,用作训练/评测黄金基准。 AI 预报…

迭代器模式及优化

迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种统一的方式遍历聚合对象(如集合、容器)中的元素,而无需暴露对象的内部实现细节。它将遍历逻辑与聚合对象分离,使得遍历操作可以…

纯Qt手撕gb28181协议/gb28181协议服务端/gb28181协议设备端/gb28181设备模拟器/gb28181虚拟监控设备

一、前言说明 搞完onvif设备模拟器,总想着把28181设备模拟也实现,因为之前已经花了大力气把28181平台软件端实现了,为了实现这个组件,头发掉了一大把,专门把国标文档看了好几遍,逐行阅读,针对需…

【渗透实战】无下载器环境(curl/wget)下玩转 Metasploit 自动利用

1. 背景与问题场景 在渗透测试或漏洞利用中,Metasploit(MSF)是业界最常用的框架之一。 其许多 RCE(远程代码执行)模块在落地 payload(如 Meterpreter 或反弹 shell)时,采用了 CMD St…

jd-hotkey探测热点key

对任意突发性的无法预先感知的热点数据,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后…

C#WPF实战出真汁07--【系统设置】--菜品类型设置

1、菜品设置介绍 菜品设置跟餐桌设置的功能目的是相同的,包括了新增,删除,编辑,分页,查询,重置,全选,全消,列表功能,实现流程也是布局设计,后台逻…

aave v3 存款与借款利息的计算方式

本文只涉及到利率计算的数学原理,不作源码解析:存款首先我们假设小明在aave里面存了10000usdt,存的时候年化收益率是5%,那么半年后其存款的利息是多少呢?常规的计算方式如下:利息10000*5%*(存款的时长/一年的时长)这么做有什么问题呢?假设现…

Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析

📋 目录 项目概述 技术架构深度解析 核心功能模块详解 代码实现分析 使用场景与实战案例 性能优化与最佳实践 扩展开发指南 总结与展望 项目概述 什么是Windows-MCP.Net? Windows MCP.Net是一个基于.NET 10.0开发的Windows桌面自动化MCP&…

Boost.Asio学习(7):Boost.Beast实现简易http服务器

namespace beast boost::beast;beast::flat_buffer是一个用于 Boost.Asio 和 Boost.Beast 网络读写的缓冲区实现。专为 一次性顺序读取 / 消费 场景设计,比 std::string 或 std::vector 高效,因为它是扁平内存结构(contiguous memory&#x…

深入解析JVM内存区域划分:从理论到实践

Java虚拟机(JVM)是Java程序运行的核心环境,它负责管理内存分配、垃圾回收、字节码执行等关键任务。理解JVM的内存区域划分,对于优化Java应用性能、排查内存问题(如OutOfMemoryError、StackOverflowError)至…

滑窗|贪心|✅滚动数组

lc17.08pair按身高升序、相同时体重降序排序结果是找体重序列的最长递增子序列长度核心&#xff1a;转化为二维最长递增子序列问题求解vector<int> dp;for (auto& p : hw) {int w p.second;auto it lower_bound(dp.begin(), dp.end(), w);if (it dp.end()) {dp.pu…

深入理解数据库架构:从原理到实践的完整指南

一、数据库存储架构的多维度分类体系 1.1 基于数据组织方式的存储架构分类 数据库的存储架构从根本上决定了其性能特征、适用场景和扩展能力。理解不同的数据组织方式是选择合适数据库技术的基础&#xff0c;这种分类不仅反映了技术实现的差异&#xff0c;更体现了对不同业务需…

体彩排列三第2025218期号码分析

大家好&#xff0c;本人蔡楚门来此平台分享一下本期得经验和思路&#xff0c;希望能够给大家带来好的运气和灵感&#xff01;体彩排列三第2025218期号码分析&#xff0c;大小号码数字分析&#xff0c;上期开出全小号码最多&#xff0c;最近两期的开奖号码全部都是全小号码最多&…

java设计模式之迪米特法则介绍与说明

一、核心概念与目标 基本定义 迪米特法则的核心思想是&#xff1a;一个对象应该对其他对象尽可能少地了解&#xff0c;仅与直接关联的对象&#xff08;即“朋友”&#xff09;通信&#xff0c;避免与“陌生人”产生直接交互。 直接朋友&#xff1a;包括当前对象的成员变量、方法…

2024-2025华为ICT大赛中国区 实践赛昇腾AI赛道(高职组)全国总决赛 理论部分真题+解析

Part 1 昇腾AI全栈系统模块(共6题)&#xff1a;1、许多计算芯片可以设计作为人工智能的计算芯片&#xff0c;但不同的芯片计算性能不同&#xff0c;昇腾计算芯片是一种()芯片。(单选题)A.CPU B.GPU C. NPU D.TPU正确答案&#xff1a;C解析&#xff1a;A项CPU中央处理器的架…

网络安全和基础设施安全局 (CISA) 表示微分段不再是可选的

网络安全和基础设施安全局 (CISA) 最近发布了一系列指导文件中的第一份&#xff0c;旨在帮助联邦机构实施微分段&#xff0c;作为其零信任架构 (ZTA) 战略的一部分&#xff0c;以遵守2022 年白宫的授权。 该文件《零信任中的微分段&#xff0c;第一部分&#xff1a;介绍和规划…