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?