Seeed XIAO BLE (nRF52840) with an external debugger (blackmagic)

I am trying to get a Seeed XIAO BLE (nRF52840) board going with PlatformIO.

I tried to use maxgerhardt’s port mentioned over here Support for Seeeduino XIAO BLE board - #8 by maxgerhardt but things are not working for me.

I dont know if is because I’m using a blackmagic probe soldered to SWD instead of the “normal” USB interface.

If I use the board nrf52840_dk everything plays nicely, compiling, uploading and debugging. But if I am using the xiaoble board definition, I cant upload, and if I jump to debugging, it can step though what ever left code on the chip, but that’s obviously no fun since it is not the currently build.

Here is my platformio.ini

[env]
framework = arduino
upload_protocol = blackmagic
debug_tool = blackmagic
platform = nordicnrf52

; compile, upload and debug is good, but pins are of course wrong 
[env:nrf52840_dk]
board = nrf52840_dk

; less good (for me)
[env:xiaoble_arduinocore_mbed]
platform = https://github.com/maxgerhardt/platform-nordicnrf52
board = xiaoble

The code is just a simple blinkly which “blinks” the wrong pin because I using the wrong board definition…

The error message in the Advanced->Verbose Upload task being what?

Hmm, not sure where to find “Advanced->Verbose Upload task” in vscode.

In the terminal I get a blob like the one below when hitting the blue “upload” button at the bottom. It might upload something, but the board is running what ever was on it previously (with the nrf52840_dk configuration).

 *  Executing task in folder blinky-nRF52840-arduino: platformio run --target upload --environment xiaoble_arduinocore_mbed 

Processing xiaoble_arduinocore_mbed (platform: https://github.com/maxgerhardt/platform-nordicnrf52; board: xiaoble; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/xiaoble.html
PLATFORM: Nordic nRF52 (9.5.0+sha.3204db4) > Seeed XIAO BLE nRF52840
HARDWARE: NRF52840 64MHz, 232KB RAM, 792KB Flash
DEBUG: Current (blackmagic) External (blackmagic, cmsis-dap, jlink)
PACKAGES: 
 - framework-arduino-mbed-seeed @ 2.8.1+sha.b7a8974 
 - tool-adafruit-nrfutil @ 1.503.0 (5.3) 
 - tool-bossac-nordicnrf52 @ 1.10901.201022 (1.9.1) 
 - tool-openocd @ 2.1100.211028 (11.0) 
 - tool-sreccat @ 1.164.0 (1.64) 
 - toolchain-gccarmnoneeabi @ 1.80201.181220 (8.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 32 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Checking size .pio/build/xiaoble_arduinocore_mbed/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [==        ]  17.6% (used 41856 bytes from 237568 bytes)
Flash: [=         ]   9.1% (used 74108 bytes from 811008 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, jlink, nrfjprog, nrfutil, sam-ba
CURRENT: upload_protocol = blackmagic
Looking for BlackMagic port...
Auto-detected: /dev/ttyACM0
Uploading .pio/build/xiaoble_arduinocore_mbed/firmware.hex
Target voltage: ABSENT!
Available Targets:
No. Att Driver
 1      Nordic nRF52 M3/M4
 2      Nordic nRF52 Access Port 
0x0000068c in ?? ()
Loading section .text, size 0x11b7c lma 0x27000
Loading section .ARM.exidx, size 0x8 lma 0x38b7c
Loading section .data, size 0x5f8 lma 0x38b84
Start address 0x2f968, load size 74108
Transfer rate: 30 KB/sec, 950 bytes/write.
Section .text, range 0x27000 -- 0x38b7c: matched.
Section .ARM.exidx, range 0x38b7c -- 0x38b84: matched.
Section .data, range 0x38b84 -- 0x3917c: matched.
Kill the program being debugged? (y or n) [answered Y; input not from terminal]
[Inferior 1 (Remote target) killed]
========================================================================================================== [SUCCESS] Took 4.08 seconds ==========================================================================================================

Environment               Status    Duration
------------------------  --------  ------------
xiaoble_arduinocore_mbed  SUCCESS   00:00:04.084
========================================================================================================== 1 succeeded in 00:00:04.084 ==========================================================================================================
 *  Terminal will be reused by tasks, press any key to close it. 

grafik

Okay, so that says it has loaded correctly.

And for reference, what’s the log when you upload using the nrf52840_dk environment?

The Verbose Upload for the xiaoble board:

*  Executing task in folder blinky-nRF52840-arduino: platformio run --verbose --target upload --environment xiaoble_arduinocore_mbed 

Processing xiaoble_arduinocore_mbed (platform: https://github.com/maxgerhardt/platform-nordicnrf52; board: xiaoble; framework: arduino; upload_protocol: blackmagic; debug_tool: blackmagic)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/xiaoble.html
PLATFORM: Nordic nRF52 (9.5.0+sha.3204db4) (git+https://github.com/maxgerhardt/platform-nordicnrf52) > Seeed XIAO BLE nRF52840
HARDWARE: NRF52840 64MHz, 232KB RAM, 792KB Flash
DEBUG: Current (blackmagic) External (blackmagic, cmsis-dap, jlink)
PACKAGES: 
 - framework-arduino-mbed-seeed @ 2.8.1+sha.b7a8974 (git+https://github.com/maxgerhardt/framework-mbed-seeed.git) 
 - tool-adafruit-nrfutil @ 1.503.0 (5.3) 
 - tool-bossac-nordicnrf52 @ 1.10901.201022 (1.9.1) 
 - tool-openocd @ 2.1100.211028 (11.0) 
 - tool-sreccat @ 1.164.0 (1.64) 
 - toolchain-gccarmnoneeabi @ 1.80201.181220 (8.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 32 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
MethodWrapper(["checkprogsize"], [".pio/build/xiaoble_arduinocore_mbed/firmware.elf"])
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [==        ]  17.6% (used 41856 bytes from 237568 bytes)
Flash: [=         ]   9.1% (used 74108 bytes from 811008 bytes)
.pio/build/xiaoble_arduinocore_mbed/firmware.elf  :
section             size        addr
.text              72572      159744
.ARM.exidx             8      232316
.data               1528   536895488
.nvictable           256   536870912
.crash_data_ram      256   536871168
.bss               40328   536897016
.heap             194688   536937344
.stack              1024   537132032
.ARM.attributes       46           0
.comment             147           0
.debug_frame        4612           0
.stab                 60           0
.stabstr             118           0
Total             315643
<lambda>(["upload"], [".pio/build/xiaoble_arduinocore_mbed/firmware.hex"])
AVAILABLE: blackmagic, cmsis-dap, jlink, nrfjprog, nrfutil, sam-ba
CURRENT: upload_protocol = blackmagic
MethodWrapper(["upload"], [".pio/build/xiaoble_arduinocore_mbed/firmware.hex"])
Auto-detected: /dev/ttyACM0
arm-none-eabi-gdb -nx --batch -ex "target extended-remote /dev/ttyACM0" -ex "monitor swdp_scan" -ex "attach 1" -ex load -ex compare-sections -ex kill /home/mogul/PlatformIO/Projects/blinky-nRF52840-arduino/.pio/build/xiaoble_arduinocore_mbed/firmware.elf
Target voltage: ABSENT!
Available Targets:
No. Att Driver
 1      Nordic nRF52 M3/M4
 2      Nordic nRF52 Access Port 
0x0000069e in ?? ()
Loading section .text, size 0x11b7c lma 0x27000
Loading section .ARM.exidx, size 0x8 lma 0x38b7c
Loading section .data, size 0x5f8 lma 0x38b84
Start address 0x2f968, load size 74108
Transfer rate: 30 KB/sec, 950 bytes/write.
Section .text, range 0x27000 -- 0x38b7c: matched.
Section .ARM.exidx, range 0x38b7c -- 0x38b84: matched.
Section .data, range 0x38b84 -- 0x3917c: matched.
Kill the program being debugged? (y or n) [answered Y; input not from terminal]
[Inferior 1 (Remote target) killed]
================================================================================================== [SUCCESS] Took 3.94 seconds ==================================================================================================

Environment                Status    Duration
-------------------------  --------  ------------
nrf52840_dk                IGNORED
xiaoble_arduinocore_mbed   SUCCESS   00:00:03.944
nano33ble                  IGNORED
adafruit_feather_nrf52840  IGNORED
================================================================================================== 1 succeeded in 00:00:03.944 ==================================================================================================
 *  Terminal will be reused by tasks, press any key to close it. 

And the Verbose Upload for the nrf52840_dk definition

 *  Executing task in folder blinky-nRF52840-arduino: platformio run --verbose --target upload --environment nrf52840_dk 

Processing nrf52840_dk (board: nrf52840_dk; framework: arduino; upload_protocol: blackmagic; debug_tool: blackmagic; platform: nordicnrf52)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/nrf52840_dk.html
PLATFORM: Nordic nRF52 (9.6.0) > Nordic nRF52840-DK
HARDWARE: NRF52840 64MHz, 256KB RAM, 1MB Flash
DEBUG: Current (blackmagic) On-board (cmsis-dap, jlink) External (blackmagic, stlink)
PACKAGES: 
 - framework-arduinonordicnrf5 @ 1.700.201209 (7.0) 
 - tool-bossac-nordicnrf52 @ 1.10901.201022 (1.9.1) 
 - tool-jlink @ 1.77001.0 (7.70.1) 
 - tool-openocd @ 2.1100.211028 (11.0) 
 - tool-sreccat @ 1.164.0 (1.64) 
 - toolchain-gccarmnoneeabi @ 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 2 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
MethodWrapper(["checkprogsize"], [".pio/build/nrf52840_dk/firmware.elf"])
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.1% (used 140 bytes from 262144 bytes)
Flash: [          ]   0.2% (used 2228 bytes from 1048576 bytes)
.pio/build/nrf52840_dk/firmware.elf  :
section            size        addr
.text              2112           0
.ARM.exidx            8        2112
.data               108   536870912
.bss                 32   536871020
.heap              4096   536871056
.stack_dummy       4096   536871056
.ARM.attributes      46           0
.comment            126           0
.debug_frame        148           0
Total             10772
<lambda>(["upload"], [".pio/build/nrf52840_dk/firmware.hex"])
AVAILABLE: blackmagic, cmsis-dap, jlink, mbed, nrfjprog, stlink
CURRENT: upload_protocol = blackmagic
MethodWrapper(["upload"], [".pio/build/nrf52840_dk/firmware.hex"])
Auto-detected: /dev/ttyACM0
arm-none-eabi-gdb -nx --batch -ex "target extended-remote /dev/ttyACM0" -ex "monitor swdp_scan" -ex "attach 1" -ex load -ex compare-sections -ex kill /home/mogul/PlatformIO/Projects/blinky-nRF52840-arduino/.pio/build/nrf52840_dk/firmware.elf
Target voltage: ABSENT!
Available Targets:
No. Att Driver
 1      Nordic nRF52 M3/M4
 2      Nordic nRF52 Access Port 
0x000005a0 in delay ()
Loading section .text, size 0x840 lma 0x0
Loading section .ARM.exidx, size 0x8 lma 0x840
Loading section .data, size 0x6c lma 0x848
Start address 0x2e4, load size 2228
Transfer rate: 7 KB/sec, 445 bytes/write.
Section .text, range 0x0 -- 0x840: matched.
Section .ARM.exidx, range 0x840 -- 0x848: matched.
Section .data, range 0x848 -- 0x8b4: matched.
Kill the program being debugged? (y or n) [answered Y; input not from terminal]
========================================================================================================== [SUCCESS] Took 1.48 seconds ==========================================================================================================

Environment                Status    Duration
-------------------------  --------  ------------
nrf52840_dk                SUCCESS   00:00:01.485
xiaoble_arduinocore_mbed   IGNORED
nano33ble                  IGNORED
adafruit_feather_nrf52840  IGNORED
========================================================================================================== 1 succeeded in 00:00:01.485 ==========================================================================================================
 *  Terminal will be reused by tasks, press any key to close it. 

Interesting. Why does it do that with base address 0x0? Seeed Studio’s ArduinoCore-mbed fork starts flash at 0x27000.

That’s an offset of 159744 bytes.

Per framework-mbed-seeed/bootloaders/Seeed_XIAO_nRF52840_Sense at main · maxgerhardt/framework-mbed-seeed · GitHub there is a bootloader on these devices, so maybe that’s what’s missing.

It could be the case that by uploading to the board with board = nrf52840_dk config, you killed off the bootloader on your board that would normally execute the application at 0x27000.

Let’s do a really simple test and try and shift down the firmware so that it may be able to run without a bootloader. Find the file

C:\Users\<user>\.platformio\packages\framework-mbed-seeed\variants\SEEED_XIAO_NRF52840\linker_script.ld

and for the FLASH memory, set ORIGIN = 0x0.

Reupload the firmware and post the logs again.

Ok, good.
Changed ORIGIN to 0x0 and everything works as expected.

My file was named a bit different than your instructions, I found it here: .platformio/packages/framework-arduino-mbed-seeed/variants/SEEED_XIAO_NRF52840/linker_script.ld
Notice framework-arduino-mbed-seeed vs ``framework-mbed-seeed`
Maybe a difference since I’m on linux?

It indeed sounds plausible that I have smashed the arduino bootloader. Let me try to restore that and undo the changes made to linker_script.ld

Now I just need to figure out how to do that…

Oh yes my bad, I didn’t take the right package name into account. framework-arduino-mbed-seeed is absolutely correct.

Given the bootloader hex file you could use objcopy like that to turn it into a .elf file, then use the flashing command with the newly created .elf file as target.

arm-none-eabi-gdb -nx --batch -ex "target extended-remote /dev/ttyACM0" -ex "monitor swdp_scan" -ex "attach 1" -ex load -ex compare-sections -ex kill bootloader.elf

The arm-none-eabi-gdb and arm-none-eabi-objcopy for that should be in ~/.platformio/packages/toolchain-gccarmnoneeabi/bin.

Bingo.
With the Arduino bootloader restored, everything seem to work as expected now.

For future reference, these are the two commands I ran:

arm-none-eabi-objcopy \
  -I ihex Seeed_XIAO_nRF52840_Sense_bootloader-0.6.1_s140_7.3.0.hex \
  -O elf32-little Seeed_XIAO_nRF52840_Sense_bootloader-0.6.1_s140_7.3.0.elf

arm-none-eabi-gdb \
  -nx \
  --batch \
  -ex "target extended-remote /dev/ttyACM0" \
  -ex "monitor swdp_scan" \
  -ex "attach 1" \
  -ex load \
  -ex compare-sections \
  -ex kill Seeed_XIAO_nRF52840_Sense_bootloader-0.6.1_s140_7.3.0.elf
1 Like