2019-03-30 03:56 AM
I've been trying to use watchpoints to catch a possible bad write.
I tried with Atollic TrueSTUDIO, but it doesn't seen to catch anything.
Then I tried code, but haven't got it to catch anything either. I'd prefer the code, because GDB doesn't support memory regions, but the HW should.
Am I missing something? I would think that because breakpoints work, the debug events are handled right, or do I need the DebugMon_Handler and and (maybe) change the halting to debug monitor exception? (And loose the IDE breakpoints.)
#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; // for checking the C_DEBUGEN under breakpoint
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;
}
}
2019-04-01 10:20 AM
An update:
I checked that in our system thread mode is privileged (by reading the CONTROL register). So accessing the debug registers 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.
2019-04-01 11:14 AM
Somewhere I found something about lock register (LAR). If there is one in STM32F427, where can I find more? ARM documents seem to leave authentication IMPLEMENTATION DEFINED, and I haven't found any STM manuals that discuss those things. HAL and CMSIS don't seem to know anything about those things.
2019-04-01 11:50 AM
Hmm, CMSIS seems to know ITM LAR...
2019-04-02 03:31 AM
Tried with LAR address 0xE0001FB0 and 0xE0000FB0. No help.
BTW, reading DWT_CTRL gives 0x40000000. Does this mean that the DWT is not locked?
Still, the result of this is zero:
tmp = DWT_DEMCR;
if ((tmp & (1<<24)) == 0) // if TRACENA
{
DWT_DEMCR |= (1<<24); // DWT disabled, enable it
}
tmp = DWT_DEMCR;