在我们平常的单片机开发的过程中,肯定会经常用到JLINK仿真器进行程序调试,无论程序是正常运行还是崩溃,当程序运行到断点位置处程序就会停止运行,所有的数据和状态都会保持在这个时刻,不知道大家有没有想过为什么会这样那?
平常开发调试的时候,我们只需要在程序前方点一下,就会生成一个断点,编译器运行到这个断点位置处会自动停止,平常我们不需要知道这个断点是怎么实现和工作的,今天我们就来简单看一下这个断点是怎么让程序停止的吧。

其实我们使用的断点分为两种形式,分别为硬件断点和软件断点。我们一STM32F103单片机的Cortex-M3内核为例,简单描述一下这两种断点。
硬件断点利用 Cortex-M3 内部的调试和监视硬件来实现。这些硬件断点允许在不修改代码的情况下,在特定的程序地址上停止执行。Cortex-M3 包含一定数量的断点单元,这些单元可以被配置为当程序执行到特定的内存地址时产生一个停止信号。这使得处理器暂停执行,等待调试器的进一步指令。
由此可见实际上 FPB 本质上是个比较器。而 Cortex-M3 的 FPB 中存在最多 8 个比较器:
- 比较器 5 为指令地址比较器。每个都可设置为产生断点事件,或者将指令访问重映射到 SRAM(不能同时生效)。
- 比较器 7 为字符比较器。它们可以将 CODE 区域中的字符数据重映射到 SRAM。
因此 Cortex-M3 最多只能设置 6 个硬件断点。
软件断点通过修改程序代码来实现,通常是将特定的指令插入到要停止的代码位置。在 Cortex-M3 中,这通常是通过插入一个 BKPT 指令来实现。当执行到这条指令时,处理器会进入调试模式,暂停执行。软件断点一般要求程序在 RAM 中运行,而我们的程序普遍都放在 Flash 中运行,调试时无法修改 Flash 中的数据,此时可能就无法设置软件断点,比如在 KEIL 中你可能会看到如下提示:

上述提示为: “硬件断点:所有断点都已被使用,软件断点:无法写入内存”。