Monitor Mode Debugging

From SEGGER Knowledge Base
Jump to navigation Jump to search

Monitor Mode Debugging is a specialized debugging technique that enables less intrusive debugging of a running application compared to halting mode debugging, which is the de facto debugging technique in embedded systems. It lets the debugger interact with the processor and monitor its state without halting the execution of the entire system, making it indispensable for certain debugging scenarios. Unlike classic halt-based debugging, where the processor and even peripherals are completely stopped, Monitor Mode allows the core to continue running while executing a special monitor handler. This mode supports a wide range of debugging features, such as setting breakpoints, stepping through code, and inspecting registers and variables. Please see Support Overview for architectures that are supported by the J-Link software.

Refer to J-Link Model Overview to confirm that your J-Link / J-Trace model supports Monitor Mode debugging.

Use cases

Monitor Mode debugging is especially useful for applications in which an essential part of the firmware must be running for the system to function properly.

Examples for common use cases:

  • Network activity: Target applicaiton integrates a network communication via Ethernet or Wireless (WLAN, Bluetooth). Monitor Mode allows the applicaiton to step through but keep the network stack responsive to incoming packets.
  • Motor Control: Target application is using a PWM-controlled motor that needs to be adapted frequently to maintain a stable and safe state.

Support overview

Architectures

The following table lists all the architectures that can be used with Monitor Mode debugging.

Architecture Supported Supported Cores Additional information
ARMv7-M YES.png Cortex-M3 / M4 / M7
ARMv8-M/ARMv8.1-M YES.png Cortex-M23 / M33 / M55 / M85 Security Extensions (TrustZone) supported

If you require Monitor Mode debugging for architectures that are currently not supported, feel free to reach out to support@segger.com.

Compilers and Toolchains

We support the following compilers and toolchains:

  • SEGGER Embedded Studio (GCC)
  • Any GCC based environment (GCC)
  • IAR EWARM (IAR ARM compiler)
  • Keil MDK-ARM (ARM compiler)

Comparision Halting Mode vs. Monitor Mode

Features Halting mode Monitor Mode
Stepping Yes Yes
Inspecting Yes Yes
Breakpoints Yes Yes
Interrupts Disabled Enabled, processing with higher priority
Vector Catch Yes No, not supported by architecture [1]
  1. Currently we only support Monitor Mode for ARM-M architectures which do not support the Vector Catch for Monitor Mode.

How it works

In classic halting mode, the debug module halts core execution when a debug event (for example, a breakpoint or an external halt request) occurs, freezing the core at a specific point in the execution flow.

When the CPU is configured for monitor mode, a debug event causes the CPU to immediately enter a dedicated DebugMonitor exception instead of halting. The associated handler is responsible for processing the debug event. Once the handler exits, execution of the previously interrupted code resumes.

The DebugMonitor handler is specialized software that manages communication with the connected J-Link probe. This communication is used to control the target device and to retrieve relevant information, such as device registers. J-Link implements Monitor Mode in a way that is transparent to the IDE. So in general, no IDE-specific support is required. From the user's perspective, debugging in monitor mode should be indistinguishable from debugging in halting mode.

Because Monitor Mode is implemented as a regular CPU exception, it can itself be interrupted by higher-priority interrupts. As a result, only interrupts with a lower priority than the DebugMonitor exception can be debugged in Monitor Mode.

If J-Link is unable to locate a valid DebugMonitor handler in the target’s memory, it automatically falls back to halting mode to ensure that debugging remains possible.

Integrating in your project

Monitor Mode requires more setup than Halt Mode Debugging and must be actively supported by the application. Therefore additional software must be compiled and linked into the application's binary. SEGGER provides an implementation for the Debug Monitor Handler that integrates with the J-Link Software.

Project files

Get the template source code for Monitor Mode:

The template file contains three files:

  • JLINK_MONITOR.c: Source code file containing user-specific functions called during the Debug Monitor. They can be filled with user-specific code. Refer to section User Handlers.
  • JLINK_MONITOR.h: Header file defining the function prototypes for the JLINK_MONITOR functions.
  • JLINK_MONITOR_ISR_SES.s: Assembler file implementing the DebugMonitor ISR.

The ISR port for compilers and toolchains other than SEGGER's Embedded Studio is available on request at https://www.segger.com/downloads/jlink/#Monitor-mode

Attention: DO NOT modify the ISR code and select the right version for your architecture and toolchain (SES, GCC, IAR). Changes may break monitor mode debugging functionality.

Enable Monitor Mode

By default, J-Link operates in halting mode debugging. To use Monitor Mode debugging, it must be explicitly enabled using the SetMonModeDebug command. For more information on how to use this and other related commands, refer to Using J-Link Command Strings.

Enabling Monitor Mode:

SetMonModeDebug = 1

SEGGER provides a JLinkScript file that can be integrated in your application tools like EmbeddedStudio, Ozone etc.: File:MonitorModeDebugging.JLinkScript. Please refer to the tools' user manuals on how to use JLinkScript files.

Forwarding Monitor Interrupts

In some applications, an additional software layer may be present that initially receives all interrupts and then forwards them to the user application by explicitly invoking the ISRs from the user application’s vector table.

In such configurations, J-Link cannot automatically detect the presence of a Monitor Mode handler, because the handler is typically linked into the user application rather than into the intermediate software layer. As a result, J-Link automatically falls back to halting mode debugging.

To enable Monitor Mode debugging in these cases, the base address of the user application's vector table — where the actual DebugMonitor handler is located — must be specified manually. This can be done using the SetMonModeVAddrTable command.

Configure vector table address:

SetMonModeVAddrTable = 0x08001000

User Handlers

SEGGER's Debug Handler implementation defines three User Functions where the user can implement custom functionality while executing Monitor Mode. Please note that the functions are called in handler mode and blocking operations like I/O should be avoided. Blocking a function call for more than 100 ms results in unpredictable behavior or debug session crashes.

  • JLINK_MONITOR_OnEnter: This function is called after the Monitor is entered. Target application is already halted at this point.
  • JLINK_MONITOR_OnPoll: This function is called periodically while inside Monitor mode.
  • JLINK_MONITOR_OnExit: This function is called before the Monitor exits and CPU execution continues.

Refer to section Examples for reference implementation of the User Handlers.

Limitations

There are some limitations to be considered when using monitor mode:

  • Be aware of User Handler functions that are called early e.g. before main(). It is up to the developer to protect your user handler against unsafe accesses to your hardware etc.
  • Vector Catch feature is disabled. Automatic halting the core on exceptions like HardFault is not supported.
  • The Debug Monitor handler itself cannot be debugged.
  • User Handlers should avoid using blocking I/O operations.
  • It is not possible to modify the stack pointer or stack pointer selection during monitor mode.
  • Setting breakpoints in exception handlers that have a higher priority than the debug monitor exception will result in a HardFault exception because the CPU is not able to enter the DebugMonitor exception.
  • ARMv8 / ARMv8.1 with TrustZone: Only the Debug Monitor in Secure Mode is supported.

Target resets during Monitor Mode

For Cortex-M–based target CPUs, special care is required if the target application contains code that triggers a reset (for example, a watchdog reset), particularly with respect to breakpoints.

In general, a target reset leaves the CPU's debug logic untouched, meaning that breakpoints and related debug settings remain active. However, monitor mode is disabled during the reset, as the corresponding bits in the DEMCR register are cleared.

J-Link automatically restores the monitor mode bits immediately after detecting that they were cleared without an explicit request from J-Link. Despite this, there is a small time window during which a breakpoint may be hit before J-Link has restored the monitor bits. If this occurs, the CPU does not enter debug mode; instead, a HardFault is triggered.

To prevent this behavior, a special version of the HardFault Handler is required. This handler detects whether the HardFault was caused by a breakpoint and, if so, ignores it and resumes normal execution of the target application.

An example for a HardFault handler handling this case can be found at SEGGER website, file: "Generic SEGGER HardFault handler".

Examples

SEGGER provides pre-configured projects that runs out-of-the-box using SEGGER's EmbeddedStudio V8.24. All sample projects contains a README.txt for further information on usage and demonstrated functionality.

ARMv7-M Cortex

ARMv8-M / ARMv8.1-M Cortex using TrustZone

TrustZone makes Monitor Mode integration more complex than on ARMv7-M due to the separation between Secure and Non-secure execution states. Unlike ARMv7-M, there is no generic Monitor Mode solution for ARMv8-M, as security features and their configuration are highly dependent on vendor- and device-specific implementations. To get started, SEGGER provides some examples for different evaluation boards.