1. 它包含了 4 个比较器,可以配置成在发生比较匹配时,执行如下动作:
a) 硬件观察点(产生一个观察点调试事件,并且用它来调用调试模式,包括停机
模式和调试监视器模式
b) ETM 触发,可以触发 ETM 发出一个数据包,并汇入指令跟踪数据流中
c) 程序计数器(PC)采样器事件触发
d) 数据地址采样器触发
e) 第一个比较器还能用于比较时钟周期计数器(CYCCNT),用于取代对数据地址
的比较
2. 作为计数器,对下列项目进行计数:
a) 时钟周期(CYCCNT)
b) 被折叠(Folded)的指令
c) 对加载/存储单元(LSU)的操作
d) 睡眠的时钟周期
e) 每指令周期数(CPI)
f) 中断的额外开销(overhead)
3. 以固定的周期采样 PC 的值
4. 中断事件跟踪
当用于硬件观察点或 ETM 触发时,比较器既可以比较数据地址,也可以比较程序计数
器 PC。当用于其它功能时,则只能比较数据地址。
每一个比较器都有 3 个寄存器:COMP 寄存器、MASK 寄存器、FUNCTION 控制寄存器。
其中, COMP 寄存器是一个 32 位寄存器,用于存储要比较的值。 MASK 寄存器可以用于
掩蔽数据地址的一些位,被掩蔽的位不参与比较。
5.源码
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
#define DWT_CYCCNT *(volatile uint32_t *)0xE0001004
#define DWT_CR *(volatile uint32_t *)0xE0001000
#define DEM_CR *(volatile uint32_t *)0xE000EDFC
#define DBGMCU_CR *(volatile uint32_t *)0xE0042004
uint32_t DWT_TestTable[10];
void dwt_tim_init(void){
DEM_CR |= (uint32_t)DEM_CR_TRCENA;
DWT_CYCCNT = (uint32_t)0u;
DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
}
void dwt_trace_test(void){
uint8_t i = 0;
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk | CoreDebug_DEMCR_MON_EN_Msk;
DWT->FUNCTION0 = 0;
DWT->COMP0 = (uint32_t)&DWT_TestTable[8];
DWT->MASK0 = 2;
DWT->FUNCTION0 = 6;
DWT->FUNCTION1 = 0;
DWT->COMP1 = (uint32_t)&DWT_TestTable[3];
DWT->MASK1 = 2;
DWT->FUNCTION1 = 6;
DWT->FUNCTION2 = 0;
DWT->COMP2 = (uint32_t)&DWT_TestTable[6];
DWT->MASK2 = 2;
DWT->FUNCTION2 = 6;
DWT->FUNCTION3 = 0;
DWT->COMP3 = (uint32_t)&DWT_TestTable[2];
DWT->MASK3 = 2;
DWT->FUNCTION3 = 6;
for(i = 0; i < 10; i++){
DWT_TestTable[i] = 1;
}
}
void DebugMon_Handler(void){
if (DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk){
printf("Inerrput from dwt comp 0.\n");
}
if (DWT->FUNCTION1 & DWT_FUNCTION_MATCHED_Msk){
printf("Inerrput from dwt comp 1.\n");
}
if (DWT->FUNCTION2 & DWT_FUNCTION_MATCHED_Msk){
printf("Inerrput from dwt comp 2.\n");
}
if (DWT->FUNCTION3 & DWT_FUNCTION_MATCHED_Msk){
printf("Inerrput from dwt comp 3.\n");
}
}