This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex M4, setting HW watchpoints?

I haven't been able to get a watchpoint to work.

I'm playing with an STM32F4 series device and I'm using Atollic TrueSTUDIO for debugging.

I'd like to use a function for setting up a watchpoint, and I guess the debug events are handled right, because the breakpoints set via the IDE work fine,

but I haven't been able to get a watchpoint to work.

What am I missing?

(I seem to have problems with code-tags. I'll try to put the code tnto the next posting.)

  • #define DWT_ADDRESS 0xE0001000
    #define DHCSR_ADDR	0xE000DEF0
    #define DFSR_ADDR	0xE000ED30
    
    #define DWT_CTRL		(*((uint32_t *)DWT_ADDRESS))
    #define DWT_COMP_0		(*((uint32_t *)DWT_ADDRESS + 0x20))
    #define DWT_MASK_0		(*((uint32_t *)DWT_ADDRESS + 0x24))
    #define DWT_FUNCTION_0	(*((uint32_t *)DWT_ADDRESS + 0x28))
    #define DWT_COMP_1		(*((uint32_t *)DWT_ADDRESS + 0x20 + 1*16))
    #define DWT_MASK_1		(*((uint32_t *)DWT_ADDRESS + 0x24 + 1*16))
    #define DWT_FUNCTION_1	(*((uint32_t *)DWT_ADDRESS + 0x28 + 1*16))
    
    #define DWT_DHCSR (*((uint32_t *)DHCSR_ADDR))
    #define DWT_DEMCR (*((uint32_t *)DHCSR_ADDR + 12))
    
    /*
     * address: within region
     * region_sz: region size as power of 2
     * datasize: 0=none, 1 = byte, 2=half word, 3 = word
     * accessmode: 0 = none1 = RO, 2=WO, 3=RW
     *
     * if datasize = 0, then check for address only
     * if accessmode = 0, then remove watchpoint
     */
    void set_watchpoint(uint32_t address, uint32_t region_sz, uint32_t data, uint8_t datasize, uint8_t accessmode)
    {
    	uint32_t mask = 0;
    	uint32_t tmp;
    
    	tmp = DWT_DHCSR;
    	tmp = DWT_DEMCR;
    	if ((tmp & (1<<24)) == 0) // if TRACENA
    	{
    		DWT_DEMCR |= (1<<24); // DWT disabled, enable it
    	}
    	while(region_sz) {
    		region_sz >>= 1;
    		mask++;
    	}
    	/* address region to watch */
    	DWT_COMP_0 = address;
    	DWT_MASK_0 = mask;
    	if (datasize !=0) {
    		/* address and data match used */
    		datasize -=1;
    		DWT_FUNCTION_0 = 0; // DWT_COMP_0 is linked address comparator
    		tmp = 0x0100; // data match + linked comparator 1
    		tmp |= (datasize << 10);
    		DWT_COMP_1 = data; // DWT_COMP_1 is the data value comparator
    		DWT_MASK_1 = 0;
    		if (accessmode == 0) DWT_FUNCTION_1 = 0;
    		else DWT_FUNCTION_1 = tmp | (4 + accessmode);
    	} else {
    		/* only address match used */
    		if (accessmode == 0) DWT_FUNCTION_0 = 0;
    		else DWT_FUNCTION_0 = 4 + accessmode;
    	}
    }
    
    

  • Some update:

    I checked that in our system thread mode is privileged (by reading the CONTROL register). So accessing the debug registerd should be allowed.

    Then I read the DHCSR and it was zero. DEMCR was also zero even after I tried to set the TRCENA-bit.

    Any idea what keeps the TRCENA-bit low? The running debugger (SWD)?

    To my understanding STM32F427 should have watchpoints implemented.

  • BTW, reading DWT_CTRL gives 0x40000000. Does this mean that the DWT is not locked?

    And setting the TRACENA is refused for some other reason?