cortex M7: How to enable watchpoints

to investigate a race condition I would need to "turn on" the DWT.

To validate the code I'm going to have to use, I wrote a piece of simplified code, but even that doesn't work. Of course, I test it using the debugger (Segger J-Link).

    volatile static uint8_t dummy;
    volatile uint8_t       *pdummy;

    uint32_t dhcsr_DEBUGEN = (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) >> CoreDebug_DHCSR_C_DEBUGEN_Pos;
    assert(1 == dhcsr_DEBUGEN);

    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; /* this should enable also DWT */
    __DSB();
    __ISB();

    uint32_t demcr_TRCENA = (CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) >> CoreDebug_DEMCR_TRCENA_Pos;
    assert(1 == demcr_TRCENA);

    // CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->LAR = 0xC5ACCE55;  /* Is this really necessary? */

    pdummy = &dummy;

    DWT->COMP1     = (uint32_t)pdummy;
    DWT->MASK1     = 1; /* 1 byte */
    DWT->FUNCTION1 = 6; /* Write */
    __DSB();
    __ISB();

    *pdummy = 5 * ac; /* ac is a function parameter */
    __DSB();
    __ISB();

    uint32_t function_MATCHED = (DWT->FUNCTION1 & DWT_FUNCTION_MATCHED_Msk) >> DWT_FUNCTION_MATCHED_Pos;
    assert(1 == function_MATCHED);

The first assert confirms that halting debugging is enabled, while the second assert confirms that DWT should be enabled (as a consequence of the TRCENA bit)

Then I program comparator, mask and function of set 1 (I also tried 0). Finally I try to write the variable that should be monitored, but the debugger does not stop, and the core does not enter debug mode.
The last assert confirms that the event was not detected.

Can you help me understand where I am going wrong?

best regards

Max

  • Hello,

    I see that you are trying to use the DWT (Data Watchpoint and Trace) unit to investigate a race condition in your code. A race condition is a type of bug that occurs when multiple threads or processes access or modify the same data at the same time, without proper synchronization. This can lead to unpredictable and incorrect results.

    To use the DWT unit, you need to enable the CoreDebug and the TRCENA (Trace Enable) bits, as you have done in your code. You also need to unlock the DWT registers by writing the value 0xC5ACCE55 to the DWT->LAR register. This is necessary because the DWT unit is part of the debug components that are protected by the lock access mechanism. Dog Needs Best

    enabling and unlocking the DWT unit is not enough to trigger a debug event when you write to the variable that you want to monitor. You also need to enable the global interrupt mask (PRIMASK) bit, which controls whether the processor can be halted by external debug requests. You can do this by adding the following line of code before writing to the variable:

    __set_PRIMASK(1);

    This will prevent any interrupts from occurring while you are writing to the variable, and allow the DWT unit to detect the write access and generate a debug event. You can then clear the PRIMASK bit after writing to the variable, by adding this line of code:

    __set_PRIMASK(0);

    Alternatively, you can use the __disable_irq() and __enable_irq() functions to disable and enable interrupts

    I hope this helps you to solve your problem. If you have any questions or feedback, please let me know.

    I’m always happy to learn and improve.

    Best Regard,
    BookerE1