µVISION DEBUGGER: Breakpoint location affects program behavior
Information in this knowledgebase article applies to:
NOP * NOP STR r0,[r2] ; enable timer peripheral LDR r1,[r3] ; read timer peripheral NOP * NOP
NOP NOP * STR r0,[r2] ; enable timer peripheral LDR r1,[r3] ; read timer peripheral NOP * NOP
In both of the examples above the STR instruction writes to a peripheral register and the load instruction reads from another register belonging to the same peripheral. For example, the store causes a timer to start and the load reads the current timer value. In case 1 a breakpoint (denoted by the asterisk "*") is set on the NOP instruction before the store instruction. In case 2 a breakpoint is set on the STR instruction. Consider the following scenario:
After carrying out these three steps you might expect the value loaded into r1 to be the same for both cases. However, the result may vary.
Why is the value loaded in to r1 different for cases 1 and 2?
To perform step 2) above, when the first breakpoint remains set, the debugger cannot simply just clear the C_HALT bit in the Debug Halting Control and Status Register (DHCSR) to allow the processor to continue execution, because the processor will hit the same breakpoint again. To avoid hitting the breakpoint again, the debugger performs the following steps:
In Case 1 the NOP instruction is "single-stepped", but in Case 2 the STR instruction is "single-stepped". Therefore in Case 2, the timer has already started before the debugger continues execution.
This debugger behavior is intentional. Stepping the processor core using C_STEP should not generate debug events and allows the core to advance when the program counter is at a hardware breakpoint. Otherwise the debugger would have to disable the breakpoint before continuing.
To avoid this behavior, the user must manually disable the breakpoint before continuing execution, and re-enable it later if necessary.
Last Reviewed: Friday, September 23, 2016
of your data.