I am trying to use Data Watchpoint and Trace (DWT) mechanism to obtain runtime instruction and accessed memory address. Specifically, I focus on STR(store) instruction operate on a continuous memory address space (more than 1000 bytes). I successfully configured DEMCR and the corresponding registers, it does trigger an interrupt and triggers the execution of the DebugMon_Handler function.
However, I do not know how to obtain the corresponding instruction and the memory address that triggered the interrupt.I can obtain the return address using the following code:```__attribute__((naked)) void DebugMon_Handler(void ) {
__asm volatile( "tst lr, #4 \n" "ite eq \n" "mrseq r0, msp_ns \n" "mrsne r0, psp_ns \n" "b my_debug_handler \n" );}
void my_debug_handler(uint32_t* sp){printf("ret address:%p \n\r", *(sp+6));}```However, I found that the obtained "ret address" is not the exact instruction after the corresponding store instruction.Instead, it is sometimes the next instruction and sometimes has two or three instruction delays. For example, ```.text:0804116A loc_804116A .text:0804116A CMP R1, R2.text:0804116C BNE loc_8041170.text:0804116E POP {R4,PC}.text:08041170 loc_8041170 .text:08041170 LDRB.W R4, [R1],#1.text:08041174 STRB.W R4, [R3,#1]!.text:08041178 B loc_804116A```the instruction 0x08041174 ` STRB.W` triggered the interrupt and the ret address was printed as 0x0804116C.But what I really need is the instruction 0x08041178, which is exactly after the 0x08041174 `STRB.W` instruction,which is helpful to do an analysis.
What I want to know is why the delays are uncertain?Besides, how to obtain the exact return address in the Debug_Monitor function?Any suggestions on how to obtain the exact memory address that triggers the interrupt?
Hi 'boofish'
You don't say exactly which DWT counter you are using to trigger an event, but I suspect you are seeing some effects of the Cortex-M33's pipeline.
The "Armv8-M Architecture Reference Manual" says in section B14.2.9 "Profiling counter support":IMPQN: The architecture does not define the point in a pipeline where the particular instruction increments an Event counter, relative to the point where the incremented counter can be read.
However, experts on the "Cortex-M / M-Profile forum" at https://community.arm.com/developer/ip-products/processors/f/cortex-m-forum may be able to help you better.Hope this helpsStephen
Hi Stephen,
Sorry for my misleading words.
I used two registers to configure and monitor continuous memory being accessed, the code shows as following:
uint32 memory[1000]; CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk |CoreDebug_DEMCR_MON_EN_Msk; uint32_t * comp1 = 0xE0001030; *comp1 = &memory[999]; DWT->FUNCTION1 = (0<<11)|1<<4|7; uint32_t *comp0 = 0xE0001020; *comp0 = &memory[0]; DWT->FUNCTION0 = (0 << 11) | 1<<4 | 5;
Then, every instruction writes the memory will trigger an exception and invoke the DebugMon_Handler.
What I want is to do is to obtain which instruction to write the memory in DebugMon_Handler.
OK, thanks for the clarification. I still suspect you are seeing some effects of the Cortex-M33's pipeline.The Armv8-M Architecture Reference Manual says in section B14.2.2 "DWT unit Operation"RYZLM: Watchpoints that occur as a result of DWT Unit events will be taken when all in-flight instructions have completed. However, under rare circumstances, the architecturally-visible overlap of instructions might be observableHowever, this isn't really the right forum for detailed questions on DWT, so suggest you re-post to the "Cortex-M / M-Profile forum" as I mentioned earlier.Stephen
Thanks for your suggestion.
HI,boofish one question,are you using actual hardware board or a simulator (QEMU ,KILE simulator mode).
i am unable to use DWT functionality on simulators and i dont have hardware boards.in case if you are doing this on
a simulator ,can you please guide me how to enable DWT to check for memory access?? also can you provide complete code
for the above example.