利用 STM32(ARMv7-M)DWT 实现指定变量被改写的时候触发中断

最近发现了 DWT 的比较器(就是 debug 的时候实现 watchpoint 功能的模块)是可以由软件控制并触发 Debug Monitor 异常的,
由此可以实现“当某个变量/内存地址被改写的时候触发一个中断”这样的功能。

测试代码:

    /* 时钟和 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[i] = 1;

        for (j = 0; j < 10; j++)
        {
            printf("%d ", data[j]);
        }
        printf("\n\r");
        HAL_Delay(1000);
    }

for 循环依次修改 data[10] 中的每一个数,DWT 的 4 个比较器分别在第 8、3、6、2 元素被修改时触发。

然后在 Debug Monitor 异常里面:

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");
    }
}

运行结果:
利用 STM32(ARMv7-M)DWT 实现指定变量被改写的时候触发中断_第1张图片

局限:
只有 4 个比较器;
不能在 debug 状态下用(会变成断点);
实际上是在监测指定地址的读/写,所以相同数据重复写入的情况需要额外处理。

你可能感兴趣的:(自己玩,arm,stm32)