Debug Monitor Exception for Breakpoint Handling on ARM Cortex-M

The ARM Cortex-M series of processors, including the Cortex-M3 and Cortex-M7, provide a powerful mechanism for setting breakpoints directly from code without the need for an external debugger. This is achieved through the Debug Monitor Exception, which allows developers to programmatically set breakpoints and handle them in software. The Debug Monitor Exception is particularly useful in scenarios where real-time debugging is not feasible or when the system needs to autonomously handle breakpoints during runtime.

The Debug Monitor Exception is enabled by setting the MON_EN bit (bit 16) in the Debug Exception and Monitor Control Register (DEMCR) at address 0xE000EDFC. Once enabled, the processor can trigger a Debug Monitor Exception when a breakpoint is hit. The breakpoints themselves are configured using the Flash Patch and Breakpoint (FPB) unit, which provides up to eight comparators for setting breakpoints on instruction addresses or literal data addresses.

To set a breakpoint on an instruction address, the FPB comparator registers 0-5 are used. Each comparator register has an ENABLE bit (bit 0) that must be set to 1 to enable the breakpoint. Additionally, the REPLACE field (bits 31:30) determines how the breakpoint is handled. For instruction addresses, the REPLACE field can be set to b01, b10, or b11, depending on the address alignment and the desired behavior. For literal data addresses, comparators 6-7 are used, and the REPLACE field is ignored.

Once the breakpoint is set and the FPB is enabled (by setting bit 0 in the FPB Control Register), the processor will trigger a Debug Monitor Exception when the specified instruction address is fetched. The Debug Monitor Exception handler can then perform any necessary actions, such as logging, state inspection, or modifying the program flow.

However, one common issue that arises when using the Debug Monitor Exception is the need to disable the breakpoint within the handler to prevent an infinite loop. If the breakpoint is not disabled, the processor will immediately re-enter the Debug Monitor Exception handler after exiting, as the breakpoint is still active. To avoid this, the breakpoint must be temporarily disabled within the handler, and the processor must be single-stepped to execute the instruction at the breakpoint address before re-enabling the breakpoint.

Single-Stepping and Breakpoint Management in Debug Monitor Handler

Single-stepping is a critical technique when working with breakpoints in the Debug Monitor Exception handler. Single-stepping allows the processor to execute one instruction at a time, which is necessary to avoid re-triggering the breakpoint immediately after exiting the handler. On ARM Cortex-M processors, single-stepping is achieved by setting the MON_PEND bit (bit 18) in the DEMCR register.

When the MON_PEND bit is set, the processor will execute one instruction and then re-enter the Debug Monitor Exception handler. This allows the handler to disable the breakpoint, single-step the instruction, and then re-enable the breakpoint before resuming normal execution. The sequence of operations in the Debug Monitor Exception handler is as follows:

  1. Disable the breakpoint by clearing the ENABLE bit in the corresponding FPB comparator register.
  2. Set the MON_PEND bit in the DEMCR register to enable single-stepping.
  3. Exit the Debug Monitor Exception handler.
  4. The processor will execute one instruction and then re-enter the Debug Monitor Exception handler.
  5. Re-enable the breakpoint by setting the ENABLE bit in the corresponding FPB comparator register.
  6. Exit the Debug Monitor Exception handler to resume normal execution.

This sequence ensures that the breakpoint is only triggered once per execution of the target instruction, preventing an infinite loop in the Debug Monitor Exception handler.

However, there are some nuances to be aware of when using single-stepping on ARM Cortex-M processors. For example, on the Cortex-M7, setting the MON_PEND bit in the Debug Monitor Exception handler may cause the handler to be called again immediately after exiting, without executing the instruction. This behavior can occur if the MON_STEP bit is not properly configured or if there are conflicts with other debug features, such as halt mode debugging.

The MON_STEP bit is not well-documented in the ARM architecture reference manuals, but it is related to the single-stepping mechanism. When MON_STEP is set, the processor should execute one instruction and then re-enter the Debug Monitor Exception handler. However, if MON_STEP is not set or if there are conflicts with other debug features, the single-stepping mechanism may not work as expected.

Debug Monitor Exception and Debugger Conflict on ARM Cortex-M

One of the challenges when using the Debug Monitor Exception on ARM Cortex-M processors is the potential conflict with external debuggers. The ARMv7-M architecture does not allow simultaneous use of the Debug Monitor Exception and halt mode debugging. When a debugger is connected and halt mode debugging is enabled, the C_DEBUGEN bit in the Debug Halting Control and Status Register (DHCSR) is set. This bit cannot be cleared by software, meaning that the Debug Monitor Exception cannot be used while the debugger is connected.

This limitation can be problematic for developers who need to use both the Debug Monitor Exception and an external debugger for debugging and monitoring purposes. For example, if a developer wants to implement an instruction counter using the Debug Monitor Exception, they may find that they cannot use the debugger to monitor the program’s execution at the same time.

One possible workaround is to use a timer interrupt to simulate single-stepping. In this approach, a timer interrupt is used to periodically check the program counter (PC) and count instructions. The timer interval is initially set to a minimal value, and if the PC has not changed after returning from the timer interrupt, the interval is increased. This process continues until the instruction is successfully executed, at which point the timer interval is reset to the minimal value, and the process repeats for the next instruction.

While this approach can be used to count instructions without relying on the Debug Monitor Exception, it is less efficient and more complex than using the built-in single-stepping mechanism. Additionally, the interrupt latency of the Cortex-M3/M4 processors (approximately 12 cycles for interrupt entry and 10 cycles for interrupt exit) must be taken into account when setting the timer interval.

In conclusion, the Debug Monitor Exception and FPB unit provide a powerful mechanism for setting and handling breakpoints on ARM Cortex-M processors without the need for an external debugger. However, developers must be aware of the limitations and potential conflicts with external debuggers, as well as the nuances of single-stepping and breakpoint management. By carefully configuring the DEMCR and FPB registers, and using techniques such as single-stepping and timer interrupts, developers can effectively use the Debug Monitor Exception for debugging and monitoring purposes on

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *