nRF52840 debug session with jlink - initial debug breakpoint incorrect

Hello everyone!

I’ve been running some nRF52840 (Particle Xenon with Adafruit Bootloader) debug sessions with jlink, and observed a problem with the debug_init_break setting in platformio.ini.

PlatformIO Core: 5.0.4
VSC: 1.52.1
Host: macOS Mojave 10.14.6

PlatformIO Framework: Arduino
Target: Particle Xenon
Bootloader: Adafruit Bootloader

Debug: Segger Edu Mini J-Link

platform.ini:

[env:xenon]
platform = nordicnrf52
board = particle_xenon
framework = arduino
lib_extra_dirs = ~/Documents/Arduino/libraries
upload_protocol= jlink
debug_tool = jlink
debug_init_break = tbreak setup

Problem: The PIO Debugger doesn’t stop at setup() in main.cpp. The initial break occurs at __asm volatile, in method vPortStartFirstTask() and file,
.platformio/packages/framework-arduinoadafruit52/cores/nRF5/freertos/portable/GCC/nrf52/portc.c

This issue seems to occur for any Particle Xenon (nRF52840) program that is debugged. The initial debug breaks fine for my STM32 board (blackpill_f411ce), so it may just be confined to nRF52840 boards.

I can live with the workaround but wondered if others have seen the same or similar, and whether there is a solution via PIO debug commands.

Observations:

  • Entering ‘run’ in the debug console results in debugger breaking at setup() in main.cpp. Afterwards the debug session proceeds fine.

  • A debug ‘restart’ from debug menu restarts the debug session & breaks at setup() in main.cpp, as expected. Afterwards the debug session proceeds fine.

  • When “debug_init_break = tbreak main” is used, the debugger breaks at main() as expected, with the following temporary breakpoint.

  • Temporary breakpoint 1, main () at .platformio/packages/framework-arduinoadafruitnrf52/cores/nRF5/main.cpp:75

  • With a breakpoint in setup(), a “run” in debug console runs the program and breaks at setup() as expected. Debug session proceeds fine.

Debug Console Output

Processing xenon (platform: nordicnrf52; board: particle_xenon; framework: arduino)

Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/particle_xenon.html
PLATFORM: Nordic nRF52 (5.0.1) > Particle Xenon
HARDWARE: NRF52840 64MHz, 243KB RAM, 796KB Flash
DEBUG: Current (jlink) External (blackmagic, cmsis-dap, jlink, stlink)
PACKAGES: 
 - framework-arduinoadafruitnrf52 1.2100.201028 (21.0) 
 - tool-sreccat 1.164.0 (1.64) 
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 59 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Servo> 1.1.2
Building in debug mode
Checking size .pio/build/xenon/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   2.8% (used 6960 bytes from 248832 bytes)
Flash: [          ]   4.6% (used 37568 bytes from 815104 bytes)
========================= [SUCCESS] Took 1.78 seconds =========================
SEGGER J-Link GDB Server V6.88b Command Line Version

JLinkARM.dll V6.88b (DLL compiled Nov 27 2020 15:44:17)

Command line: -singlerun -if SWD -select USB -device nRF52840_xxAA -port 2331
-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      yes
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               on
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 nRF52840_xxAA
Target interface:              SWD
Target interface speed:        4000kHz
Target endian:                 little


Connecting to J-Link...
J-Link is connected.
Firmware: J-Link EDU Mini V1 compiled Nov 12 2020 13:31:42
Hardware: V1.00
................
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 2331
Connecting to target...
Connected to target
Waiting for GDB connection...
Reading symbols from ...................
done.
PlatformIO Unified Debugger -> http://bit.ly/pio-debug
PlatformIO: debug_tool = jlink
PlatformIO: Initializing remote target...
Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x000279F6 (Data = 0x0100F8D3)
Read 2 bytes @ address 0x000279F6 (Data = 0xF8D3)
Read 2 bytes @ address 0x000279F8 (Data = 0x0100)

Reset_Handler () at .platformio/packages/framework-arduinoadafruitnrf52/cores/nRF5/linker/gcc_startup_nrf52840.S:252
252	    str     r2, [r0]
Reading 64 bytes @ address 0x000279C0
Read 4 bytes @ address 0x00027A10 (Data = 0xE000E100)
Received monitor command: clrbp
Received monitor command: speed auto
Select auto target interface speed (2000 kHz)
Select auto target interface speed (2000 kHz)
Received monitor command: reset
Resetting target
Resetting target
Received monitor command: halt
Halting target CPU...
...Target halted (PC = 0x00000A80)
Loading section .text, size 0x9064 lma 0x26000
Downloading 16080 bytes @ address 0x00026000
Downloading 15936 bytes @ address 0x00029ED0
Downloading 4948 bytes @ address 0x0002DD10
Loading section .ARM.exidx, size 0x8 lma 0x2f064
Downloading 8 bytes @ address 0x0002F064
Loading section .data, size 0x254 lma 0x2f06c
Start address 0x279dc, load size 37568
Downloading 596 bytes @ address 0x0002F06C
Writing register (PC = 0x   279dc)
Transfer rate: 9171 KB/sec, 7513 bytes/write.
Read 4 bytes @ address 0x000279DC (Data = 0x4A0B490A)
Read 2 bytes @ address 0x000279DC (Data = 0x490A)
Read 2 bytes @ address 0x000262D4 (Data = 0xB508)
**Temporary breakpoint 1 at 0x262d4: file src/main.cpp, line 18.**

PlatformIO: Initialization completed
**PlatformIO: Resume the execution to `debug_init_break = tbreak setup`**
PlatformIO: More configuration options -> http://bit.ly/pio-debug
Setting breakpoint @ address 0x000262D4, Size = 2, BPHandle = 0x0001
Starting target CPU...
...Target halted (DBGRQ, PC = 0x00000A64)
Reading all registers

Program
 **received signal SIGTRAP, Trace/breakpoint trap.**
Removing breakpoint @ address 0x000262D4, Size = 2
Read 4 bytes @ address 0x00000A64 (Data = 0x471868DB)
Read 2 bytes @ address 0x00000A64 (Data = 0x68DB)
0x00000a64 in ?? ()
Read 4 bytes @ address 0x2003FFDC (Data = 0x8100000B)
Reading 64 bytes @ address 0x2003FFC0
Read 4 bytes @ address 0x00000ACA (Data = 0x47106812)
Read 2 bytes @ address 0x00000ACA (Data = 0x6812)
Read 4 bytes @ address 0x2003FFFC (Data = 0x61000000)
Read 4 bytes @ address 0x00027952 (Data = 0x6000BF00)
Read 4 bytes @ address 0x00027696 (Data = 0xFFC4F7FF)
Reading 64 bytes @ address 0x20040000
2
Read 4 bytes @ address 0x00000000 (Data = 0x20000400)

Approximately as in Hang Starting nRF52840 Feather Express Under Segger Debugger - #3 by chrisgr99

Read 4 bytes @ address 0x0002A04C (Data = 0x3D04F84D)
0x0002a04c in PendSV_Handler () at /Users/chrisgr/.platformio/packages/framework-arduinoadafruitnrf52/cores/nRF5/freertos/portable/GCC/nrf52/port.c:104
104    __asm volatile

Also the

0x00000a64 in ?? ()

line is identically appearing in both topics.

We suspect it has something to do with the USB peripheral re-init or the bootloader. Some workarounds are also displayed in that thread.

Thanks maxgerhardt.

Yes, possible an issue with the Adafruit bootloader or something to do with the USB peripheral. I’ll keep an eye out the next time I debug under PIO/Zephyr using J-Link.

I don’t recall seeing a similar issue when debugging under Segger Embedded Studio with the Segger Edu Mini J-Link.

Following the link, I added a .gdbinit script to my home folder.

I like the added benefit of a “restart” without having the PIO debugger rebuild & flash.

.gdbinit (in home folder):

define restart
    monitor reset
    shell sleep 1
    cont
end

My updated platformio.ini file:

[env:xenon]
platform = nordicnrf52
board = particle_xenon
framework = arduino
lib_extra_dirs = ~/Documents/Arduino/libraries
upload_protocol= jlink
debug_tool = jlink
debug_extra_cmds =
   source gdbinit

This seems to be an issue specifically with the J-Link EDU Mini and Zephyr/PlatformIO, and doesn’t necessarily depend on the platform being used.

I’ve posted an issue on GitHub.

You’re using an nRF52840, I’m using an nRF52832, but I’ve seen another post (linked in that GitHub issue) from someone with an Atmel chip.

In my case, I can debug both Arduino and Mbed successfully in PlatformIO, and I can debug Zephyr successfully in SEGGER Embedded Studio. The issue seems to be with PlatformIO, Zephyr, and the J-Link EDU Mini.