金牌会员
 
- 积分
- 1366
- 金钱
- 1366
- 注册时间
- 2016-5-26
- 在线时间
- 1698 小时
|
最近发现了 DWT 的比较器(就是 debug 的时候实现 watchpoint 功能的模块)是可以由软件控制并触发 Debug Monitor 异常的,
由此可以实现“当某个变量/内存地址被改写的时候触发一个中断”这样的功能。
测试代码:
[mw_shl_code=c,true]
uint_fast8_t i, j;
/* 时钟和 printf 初始化略 */
/* data[10] 是初始为 0 的全局整型数组 */
/* Enable Trace and Debug Monitor exception */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk |
CoreDebug_DEMCR_MON_EN_Msk;
// /* Number of comparators available */
// dwt_numcomp = _FLD2VAL(DWT_CTRL_NUMCOMP, DWT->CTRL);
/* Configure comparators */
DWT->FUNCTION0 = 0; /* Disable */
DWT->COMP0 = (uint32_t)&data[8]; /* Target address */
DWT->MASK0 = 2; /* 0 - Byte; 1 - Halfword; 2 - Word */
DWT->FUNCTION0 = 6; /* 5 - Read; 6 - Write; 7 - R & W */
DWT->FUNCTION1 = 0; /* Disable */
DWT->COMP1 = (uint32_t)&data[3]; /* Target address */
DWT->MASK1 = 2; /* 0 - Byte; 1 - Halfword; 2 - Word */
DWT->FUNCTION1 = 6; /* 5 - Read; 6 - Write; 7 - R & W */
DWT->FUNCTION2 = 0; /* Disable */
DWT->COMP2 = (uint32_t)&data[6]; /* Target address */
DWT->MASK2 = 2; /* 0 - Byte; 1 - Halfword; 2 - Word */
DWT->FUNCTION2 = 6; /* 5 - Read; 6 - Write; 7 - R & W */
DWT->FUNCTION3 = 0; /* Disable */
DWT->COMP3 = (uint32_t)&data[2]; /* Target address */
DWT->MASK3 = 2; /* 0 - Byte; 1 - Halfword; 2 - Word */
DWT->FUNCTION3 = 6; /* 5 - Read; 6 - Write; 7 - R & W */
for (i = 0; i < 10; i++)
{
data = 1;
for (j = 0; j < 10; j++)
{
printf("%d ", data[j]);
}
printf("\n\r");
HAL_Delay(1000);
}
[/mw_shl_code]
for 循环依次修改 data[10] 中的每一个数,DWT 的 4 个比较器分别在第 8、3、6、2 元素被修改时触发。
然后在 Debug Monitor 异常里面:
[mw_shl_code=c,true]
void DebugMon_Handler(void)
{
if ((DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) != 0)
{
printf("Interrupt from DWT Comparator 0.\n\r");
}
if ((DWT->FUNCTION1 & DWT_FUNCTION_MATCHED_Msk) != 0)
{
printf("Interrupt from DWT Comparator 1.\n\r");
}
if ((DWT->FUNCTION2 & DWT_FUNCTION_MATCHED_Msk) != 0)
{
printf("Interrupt from DWT Comparator 2.\n\r");
}
if ((DWT->FUNCTION3 & DWT_FUNCTION_MATCHED_Msk) != 0)
{
printf("Interrupt from DWT Comparator 3.\n\r");
}
}
[/mw_shl_code]
运行结果:
局限:
只有 4 个比较器;
不能在 debug 状态下用(会变成断点);
实际上是在监测指定地址的读/写,所以相同数据重复写入的情况需要额外处理。
|
|