ARM Cortex-M33数据断点和TRAP功能

日常调试中,除了需要在指令执行上插入断点以进行跟踪或单步调试,在某些情况下,也需要跟踪数据变化并当某内存数据发生变化时产生断点。

这个功能在ARM Cortex-M33中,可以通过利用DWT实现。

配置DWT

打开DWT功能

在Secure模式下修改DEMCR(0xE000EDFC)寄存器中打开DWT功能:

配置比较器

回到Non-Secure下,修改DWT_COMP寄存器,n的范围为硬件支持DWT比较器个数, DWT_COMP0的地址是0xE0001020,
在此寄存器中填入希望跟踪的地址,例如0x2800_8000:

DWT比较器可以跟踪多种类型,比如cycle count, PC地址,这里只关心Data Access:

使能比较器

DWT_FUNCION寄存器的基地址为0xE0001028, 内容如下:

其中,[31:27] ID位, [24] MATCHED位为只读

DATASIZE(此处配置为4BYTE)

ACTION(此处配置为2’b01, Generate debug event)

MATCH:
MATCH位较为复杂,具体参考armv8m-arm D2.2.62 DWT_FUNCTION, 此处配置为4’b0101, 即Data Address Write

最终DWT_FUNCTION0 = 0x58000815

挂载调试器

挂在GDB Server:

打开GDB Client 并继续程序

target remote localhost:2331
monitor halt
info reg
c

测试

完成了DWT使能、DWT_COMP0、DWT_FUNCION0的配置后,如果有data access到测试地址0x2800_8000将会产生调试时间并被调试器捕获进而可以展开更多调试:

TRAP

类似的, 既然ARM可以监测到数据变化并产生debug event, 那也是可以产生Debug Monitor Excpetion,从而不用调试器就可以拦截特定地址的数据访问或者指令访问。

这种在某些应用场合会非常的有帮助,比如无法一直挂在调试器,又或者当部分代码是按照lib的形式存储在ROM上,而随着软件的升级部分功能需要替换,或者ROM上的代码有部分bug, 为了不完全替换ROM code(可能会浪费大量内存), 可以把需要替换的代码的入口地址加入监视目标,当程序跳转此处时产生中断,打断当前执行并进行替换。通常此类操作为TRAP & CATCH。

而使用方法则非常简单,在前面提到的DEMCR寄存器[16]位MON_EN置位为1即可,如果有对应地址或者指令的访问,Secure端的Debug Monitor Exception将会执行。

1
2
3
4
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
CoreDebug->DEMCR |= CoreDebug_DEMCR_MON_EN_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
DWT->CYCCNT = 0;