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.
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:
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.
Segger supplies DebugMon_Handler code for several compilers. The files needed for using GDB/Eclipse are available in the 'Sample project' here. After downloading:
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.)
ifeq ($(HALT), 1)
CFLAGS += -O0 -ggdb -DDEBUG -DDEBUG_NRF
$(info Building for halt debug mode.)
ifeq ($(RELEASE), 1)
CFLAGS += -O3 -g3
ASMFLAGS += -g3
$(info Building for release.)
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:
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:
@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.
The article was helpful to know the more in detail about the monitor mode Debugging. But trying to make it working without any practical experience on the same can go in water as you might end up with errors. flats in kochi It is better to get help from an experienced person who work with the same.
These are very helpful tips with users can easily handle bugs an errors without asking of help from others. People are very happy with read of comments from college-paper.org reviews here about writing of recent papers.
I had the same problem and found this : https://github.com/NordicPlayground/j-link-monitoring-mode-debugging/blob/master/pca10040/s132/ses/README.mdIn fact, the interrupt priority wasn't high enough. Here is the relevent line from the README : NVIC_SetPriority(DebugMonitor_IRQn, _PRIO_SD_LOW)
i was all the setting give in the tutorial, still i am getting new problem like after break point now the code is moving Hardfault handler in startup file . Can any one help on this
"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."