Posted 2017-03-29 05:56:12 +0200

blogs->nordicers

# Monitor Mode Debugging with J-Link and GDB/Eclipse

The biggest pain point when debugging an application on the nRF51 series is the inability to set breakpoints while the SoftDevice is active without triggering an assert. Although a workaround exists that allows the debugging process to limp along for a short amount of time after the SoftDevice complains, using breakpoints with the nRF51 is inevitably a disruptive process.

Thankfully, the nRF52 series includes support for a neat feature called Monitor Mode Debugging. When this feature is enabled, the processor will trigger a specific interrupt handler (DebugMon_Handler) instead of halting when a breakpoint is reached. This DebugMon_Handler then spins and executes some 'monitor' code until the debugger wishes to continue. Because the DebugMon_Handler is running in an interrupt context, it effectively halts the execution of all code except for code that runs in higher-priority contexts. The monitor code itself allows the debug probe (e.g. Segger J-Link) to maintain communication with the processor without actually halting it.

In short, using monitor mode instead of halt mode with the nRF52 allows the debugger to set breakpoints in low-priority contexts and perform normal debugging operations without impeding higher-priority code like the SoftDevice's time-critical routines.

## Prereqs

Monitor mode debugging requires support in the processor (in this case a Cortex-M4F) as well as in the debug probe (in this case a J-Link). As long as the processor and debug probe are correctly configured no further cooperation is required from the debugger: this means that the GDB client and therefore Eclipse can use monitor mode without any specific support for it. Adding monitor mode support to a GDB/Eclipse project is straightfoward as long as the following requirements are met:

• J-Link PLUS, ULTRA+, or PRO

NOTE: The J-Link OB that is included on Nordic development kits does not include a license for monitor mode debugging. On Windows machines, the J-Link driver will allow evaluation of the monitor mode debugging feature if the user accepts a license pop-up. On Linux and OSX machines, the J-Link driver will accept the commands to enable monitor mode debugging but will silently fail to enable it.

## Procedure

Segger supplies DebugMon_Handler code for several compilers. The files needed for using GDB/Eclipse are available in the 'Sample project' here. After downloading:

1. Create a new dir e.g. '{SDK13_ROOT}/external/jlink_monitor_mode_debug/gcc'

These files need to be compiled into the application so the default DebugMon_Handler is replaced by Segger's implementation. Regardless of whether GDB or Eclipse is being used, the fastest way to get started is to simply add these files to an existing Makefile. For a typical example in SDK13 this might involve copy-and-pasting the following to a line just above the 'default:' target:

ifeq ($(MMD), 1) CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF CFLAGS += -DMMD ASMFLAGS += -mcpu=cortex-m4 ASMFLAGS += -mthumb SRC_FILES +=$(SDK_ROOT)/external/jlink_monitor_mode_debug/gcc/JLINK_MONITOR.c
SRC_FILES += $(SDK_ROOT)/external/jlink_monitor_mode_debug/gcc/JLINK_MONITOR_ISR_SES.s INC_FOLDERS +=$(SDK_ROOT)/external/jlink_monitor_mode_debug/gcc
$(info Building for monitor debug mode.) endif ifeq ($(HALT), 1)
CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF
$(info Building for halt debug mode.) endif ifeq ($(RELEASE), 1)
CFLAGS += -O3 -g3
ASMFLAGS += -g3
$(info Building for release.) endif  Then, calling make clean followed by make MMD=1 will cause these files to included in the build. From Eclipse, calling make MMD=1 can be accomplished by modifying the existing 'Build Configuration' (or creating a new one): Next, two commands are required to be executed by JLinkGDBServerCL to enable monitor mode debugging: mon exec SetMonModeDebug=1 mon exec SetMonModeVTableAddr=0x1f000  The second command tells the J-Link where the application's vector table is located. This location varies between versions of a particular SoftDevice. The easiest way to locate it is to check a project's linker file. For example, in the ble_app_uart project in SDK13 the 'ble_app_uart_gcc_nrf52.ld' defines this offset as 0x1f000: MEMORY { FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 RAM (rwx) : ORIGIN = 0x200025f8, LENGTH = 0xda08 }  These two commands can be added to a command script or gdbinit file if GDB is being invoked directly from a Makefile: .PHONY: gdb_cmd_file gdb_cmd_file: default @echo "target remote localhost:$(GDB_PORT)" > $(GDB_CMD_PATH) @echo "mon speed 10000" >>$(GDB_CMD_PATH)
@echo "mon flash download=1" >> $(GDB_CMD_PATH) @echo "load$(DBG_BUILD_DIR)/$(PROJECT_NAME).out" >>$(GDB_CMD_PATH)
@echo "break main" >> $(GDB_CMD_PATH) @echo "mon reset 0" >>$(GDB_CMD_PATH)
@echo "mon exec SetMonModeDebug=1" >> $(GDB_CMD_PATH) @echo "mon exec SetMonModeVTableAddr=0x1f000" >>$(GDB_CMD_PATH)


If GDB is being launched by Eclipse then these commands can be appended to the commands under the 'Startup' tab in the project's 'Debug Configuration':

No other changes are required but if a standalone debug probe is used (i.e. a fancy J-Link) then the correct debug probe should be selected by entering its serial number in the 'Debugger' tab:

Note that a second 'Debug Configuration' can be created that omits these two commands to allow for switching between halt mode and monitor mode debugging. Care should be taken to ensure that the correct 'Build Configuration' was used to build the application before starting the debugger in monitor mode because the JLinkGDBServerCL has no way to ensure that the application was built with a valid DebugMon_Handler.

A proper Makefile for switching between halt debugging, monitor debugging, and release builds is provided for the ble_app_uart project in SDK13 here.

Finally, the application needs to assign a reasonable priority to the DebugMon_Handler. This can be done at the top of the main function in 'main.c' with a call to NVIC_SetPriority(DebugMonitor_IRQn, 7UL);. Priority level 7 allows for setting breakpoints in code that executes in the Thread (or main) context. For reference, here is list of the interrupt priorities that are use by the S132:

The priority level that is assigned to the DebugMon_Handler should be set to one level higher than the code that needs to be debugged. However, setting the DebugMon_Handler priority to level 0, 1, 2, 3, or 4 can lead to interference with the operation of the SoftDevice. Using priority level 6 allows breakpoints to be set in the on_ble_evt function and is the recommended level for most applications.

The JLinkGDBServerCL takes care of writing the required processor registers to enable monitor mode debugging. Note that if the application triggers a soft reset then there can be a brief window between when the processor resets and when the J-Link can write the registers to reenable monitor mode.

## Recent blog posts

Posted 2017-04-11 11:49:17 by Radosław Koppel
• ### Taking a deeper dive into Bluetooth 5

Posted 2017-04-07 14:53:51 by John Leonard
• ### Logging enabled by default in SDK Bluetooth examples

Posted 2017-03-29 11:27:02 by Håvard
• ### Monitor Mode Debugging with J-Link and GDB/Eclipse

Posted 2017-03-29 05:56:12 by Daniel Veilleux
• ### Getting started with Nordic's Secure DFU bootloader, a step by step guide

Posted 2017-03-20 17:13:52 by Hung Bui

## Recent questions

• ### nRF52832 one of output (p0.15) lost its power

Posted 2017-04-28 12:07:25 by Damian
• ### mesh dfu serial translate update file . 15 min？ why so slowlly？

Posted 2017-04-28 12:03:43 by mr_sev
• ### Ram related issue / What are the best practices (armgcc, linker) > nRF51 16 kB vs 32 kB

Posted 2017-04-28 11:39:06 by trdop
• ### SoftDevice Update size

Posted 2017-04-28 11:30:48 by Mihail
• ### How to setup a complete BLE5 enviornment ?

Posted 2017-04-28 10:33:28 by allankliu