Keil Logo

µVISION DEBUGGER: Breakpoint location affects program behavior


Information in this knowledgebase article applies to:

  • µVision Debugger

SCENARIO

Case 1

  NOP
* NOP
  STR r0,[r2]     ; enable timer peripheral
  LDR r1,[r3]     ; read timer peripheral
  NOP
* NOP

Case 2

  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:

  1. The program runs until the processor hits the first breakpoint.
  2. The user clicks on the "run"/"go" button again.
  3. The program runs until the processor hits the second breakpoint.

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.

QUESTION

Why is the value loaded in to r1 different for cases 1 and 2?

ANSWER

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:

  1. Step the instruction where the breakpoint is set by setting the C_STEP bit in the DHCSR
  2. Clear C_HALT to resume execution

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.

SEE ALSO

Last Reviewed: Friday, September 23, 2016


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.