硬件代码断点(Hardware Code Breakpoint)
硬件代码断点是通过MCU内部的专门硬件模块来实现。以ARM Cortex-M为例,Flash Patch and Breakpoint Unit (FPB)包含对应的PC地址比较器,当CPU想要运行对应地址的指令时,比较器会触发并返回Breakpoint Instruction (BKPT) 指令给到CPU,CPU会暂停,从而实现硬件代码断点功能。硬件代码断点的优势是速度快(因为是通过MCU内部的硬件比较器实现), 劣势是数量有限(ARM Cortex-M最多是6-8个)。
本地的CortexM33 的MCU 试验最多可以添加8个硬件断点,继续添加时回报如下的错误,添加硬件断点失败。
上述绿色部分描述对应cortex -m 架构的Flash Patch and Breakpoint Unit 对应的寄存器如下,对应的芯片的COMP 寄存器为8个,跟上述的8个硬件断点保持一致,硬件断点实现跟底层该寄存器数目相绑定。
添加如下硬件断点配置,设置断点后读取上述寄存器查看硬件断点配置情况。
读取对应的COMP 寄存器和断点设置地址发现寄存器数值和断点地址是匹配的,相对断点的地址要多1 是因为THUMB指令集的原因。
上述0xc26b7 对应的地址产看代码发现为如下main 函数的地址。
该断点的设置对应IAR 自动会停在main 函数的配置,也验证了IAR 函数debug 在main 函数停住也是配置了断点配置。
在非Debug 状态未设置断点时,读取FP_COMP 寄存器的值发现都为0
软件代码断点(Software Code Breakpoint)
软件代码断点是通过调试器(Debugger)将对应地址的指令替换成专门的断点指令。以ARM Cortex-M为例,调试器将对应地址的指令替换成Breakpoint Instruction (BKPT) 指令。当CPU想要运行对应地址的指令时,将会运行Breakpoint Instruction (BKPT) 指令,CPU会暂停,然后对应地址的指令又会恢复成原来的指令,从而实现软件代码断点功能。软件代码断点的优势是数量没有限制,但是由于对应地址的指令需要被调试器替换成专门的断点指令,只能用于在RAM中运行的代码。
在代码运行在flash 的基础上修改link file 将程序运行在RAM中,来验证上述标红部分的描述,发现这次IAR 中断点数量超过8个也不会报错了,没有数量的限制了。
验证完了上述标红部分的描述,我们继续对上述橙色部分的描述的软件断点的触发机制。我们在代码中添加如下连续地址的软件断点。
设置好断点后读取0x20050730 对应的RAM 空间数据如下。
取消断点后再读取0x20050730 对应的RAM 空间数据如下。
对比设置断电前后的memory 数据可以发现上述断点地址处的数据在设置断点后被修改为0xbe00,0xbe00是什么呢?
从上面曾色的内容描述,我们不难猜测0xbe00对应着BKPT 指令,查看ARM-M 指令可知0xbe00 对应 BKPT 0 的汇编指令编码。
除了上述的code 断点IAR 还支持了日志断点 (Log Breakpoints)的功能
除了代码断点,开发人员还可以使用日志断点。这是一个特殊的断点,因为它只会暂时停止应用来打印一条信息。只有当断点被触发时,它才会显示选定的信息。
我们可以利用此特性在IAR IDE 中显示一些调试信息,我们可以使用该断点统计某段代码被执行的次数,例如中断函数等被触发的次数等。
IAR 在代码运行的位置处右键添加日志断点
双击断点编辑触发时的输出信息。
触发后后Debug Log 窗口会输出对应的信息 及 被调用次数信息
数据断点 (Data breakpoints)
相比其他断点,数据断点有些不同,因为它们监测对特定内存地址、标志、变量或寄存器的读写访问。数据断点使用非常直截了当,只需右键点击标志或变量,然后选择选项Set Data Breakpoint即可。默认情况下,读和写的访问将被监测。如果开发人员想增加额外的设置,可以通过View->Breakpoints window和Edit option来完成。除了访问之外,还可以监测数据是否匹配。这意味着只有当数据匹配时,写或读的访问才会触发停止。选择“Edit”按钮,可以打开一个额外的窗口,可以选择绝对地址甚至是源代码行。如果是一个变量或标志,建议使用自动大小。如果需要监测更大的范围,应手动设置所需的大小。
数据断点对于调试被应用破坏的标志和变量非常有用。一旦出现了读写访问,应用就会停止。另一种用法是堆栈溢出调查,只需要在堆栈大小的 80-90% 处设置一个数据断点,当溢出接近时,就可以停止应用,并一步步找到问题的根源。
Cortex-M 架构数据断点 (Data breakpoints) 的实现方式
在Cortex-M 架构中数据断点的监测方式 通过DWT(Data Watchpoint and Trace unit) 来实现数据断点的监测。其监测过程主要通过DWT_FUNCTIONn 寄存器来设置监测的Data write/read/readwrite 的数据访问的触发方式,及监测数据访问的地址范围。DWT_COMPn 根据DWT_FUNCTIONn .MATCH 的不同来配置监测的比较的数据。
DWT_FUNCTIONn 寄存器说明如下:
其中主要定义了ID/MATCHED/DATASIZE/ACTION/MATCH 信号对应寄存器说明如下:
ID:定义监测事件的类型,指令访问/数据访问/CPU CYCLE 等具体定义如下
MATCHED:事件触发状态
DATASIZE:监测数据size
ACTION:监测匹配后执行动作
MATCH
DWT_COMPn 监测比较数据定义如下
按照上面的描述IAR 配置数据断点后读取DWT 寄存器发现配置数据断点后,DWT 上述寄存器已经按照上述规则更新
从上述寄存器配置发现数据断点的size 配置为8 时实际上配置的4 ,底层硬件最大支持的size 为4,如果需要监测超过4字节的地址范围需要添加DWT_COMPn 进行超过四字节的数据访问监测。
以下是配置数据断点前后对应DWT 对应寄存器的变化数据,从中可以发现更新了监测地址