When getting started with BLE using the NRF52-DK Development Kit there are a couple of benefits. One major helper is the onboard programmer implementing the Segger JLINK SWD protocol.
However, as soon as moving away from the development platform working with an off-board programmer becomes important.
Being a friend of FOSS, the Blackmagic Probe is one of the obvious choices when selecting a programmer for almost any of the popular ARM Cortex based SoCs.
This post bridges the gaps when setting up the Blackmagic Probe in order to use it for flashing the NRF52DK (with the NRF52840). While Ubuntu Linux is used for this guide, most of the steps will translate in a similar fashion to Windows or Mac OS.
Setting up the Development Kit

- NRF Power Source Switch should be set to
VDD
- To disable the interfacing MCU make sure to flip the switch for the Power Selecting to
nRF ONLY
instead ofDEFAULT
. - Attach the 8 Pin Connector from the Blackmagic Probe with the
Debug in
headers on the NRF52DK. - Attach Power via Micro USB to the NRF52DK.
- Attach the USB of the Blackmagic Probe to the host system (hitting
dmesg
should show that two new/dev/ttyACMX
Devices should appear.)
Getting the latest Firmware for the Blackmagic Probe
If the Blackmagic Probe has been ordered a while ago, make sure to have the most recent firmware image installed. The one on the github release page is quite a bit dated, head over to the Wiki to get a more recent one (see the section “Use the daily build at …”) . Link as of writing this post: Firmware Link.
# Install DFU-Utils Package in Ubuntu
sudo apt install dfu-util
# Flash Probe
# In this case the file blackmagic-native.bin contained the most recent firmware version.
sudo dfu-util -d 1d50:6018,:6017 -s 0x08002000:leave -D blackmagic-native.bin
This is the output after flashing the Blackmagic Probe:
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 1d50:6018
Run-time device DFU version 011a
Claiming USB DFU Runtime Interface...
Determining device status: state = appIDLE, status = 0
Device really in Runtime Mode, send DFU detach request...
Device will detach and reattach...
Opening DFU USB Device...
Claiming USB DFU Interface...
Setting Alternate Setting #0 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 1024
DfuSe interface name: "Internal Flash "
Downloading to address = 0x08002000, size = 88992
Download [=========================] 100% 88992 bytes
Download done.
File downloaded successfully
Transitioning to dfuMANIFEST state
Connecting to the GDB Server with gdb
One of the key challenges to overcome is to replace the nrfjprog
utility as it will not work with the Blackmagic Probe.
The Blackmagic Probe runs already a version of the GDB server, therefore all that needs to be done is to connect with the gdb
client.
When working with the NRF52, having a copy of the arm-gcc
toolchain installed is essential. If not using a recent version already there are a couple of options where to get one. The most obvious choice is heading over to ARM’s website and fetch an archive with the binaries. Other options are to visit the Linaro project or build it on your own.
For the next step, open a terminal and locate the toolchain directory and navigate to the bin
folder.
Note: there are two popular options to skip finding your toolchain folder over and over again. One is to add it to the
PATH
environment variable in the~/.profile
file or link the binary somewhere withln -s
in the~/bin
directory.
In the terminal execute ./arm-none-eabi-gdb
. Notice the ./
in front of the command.
GNU gdb (GNU Tools for Arm Embedded Processors 8-2019-q3-update) 8.3.0.20190703-git
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)
Now connect to the gdb server and query targets.
(gdb) target extended-remote /dev/ttyACM0
Remote debugging using /dev/ttyACM0
(gdb) monitor swdp_scan
Target voltage: 3.0V
Available Targets:
No. Att Driver
1 Nordic nRF52 M3/M4
2 Nordic nRF52 Access Port
(gdb) attach 1
Attaching to Remote target
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x00015fd6 in ?? ()
(gdb)
If for some reason the targets Nordic nRF52 M3/M4
and Nordic nRF52 Access Port
are missing, it may be due to an old firmware version on the Blackmagic Probe. See the steps above on how to get a more recent version. Else, you should be good to start flashing the device with a Softdevice hex, a custom firmware binary or both.
Flashing the NRF52 via GDB
The load
command in gdb will download and flash a firmware image to the NRF52. Here is the typical series of gdb
commands to use in order to flash the target:
load [filename of hex here]
mon hard_srst
detach
Following the guide found on the Blackmagic github wiki page, there are ways to automate the flashing task. Also very helpful is this article from the Electronut Project explaining how to flash an image with gdb
for the NRF52.
Let’s start by creating a bash
script that erases the flash, burns the softdevice s140
and then flashes the application and restarts the target. Let’s call the script gdb-flash.sh
.
#!/bin/bash
# this is gdb-flash.sh
# Adjust this to where your toolchain is located
GDB=../../../../toolchain/bin/arm-none-eabi-gdb
$GDB -nx --batch -ex 'target extended-remote /dev/ttyACM0' -x gdb-erase.scr
$GDB -nx --batch -ex 'target extended-remote /dev/ttyACM0' -x gdb-flash.scr ../../../components/softdevice/s140/hex/s140_nrf52_6.1.1_softdevice.hex
$GDB -nx --batch -ex 'target extended-remote /dev/ttyACM0' -x gdb-flash.scr pca10056/s140/armgcc/_build/nrf52840_xxaa.hex
$GDB -nx --batch -ex 'target extended-remote /dev/ttyACM0' -x gdb-kill.scr
Now let’s create the two files gdb-erase.scr
, gdb-flash.scr
, and gdb-kill.scr
.
# this is gdb-erase.scr
monitor swdp_scan
attach 1
mon erase_mass
mon hard_srst
detach
# this is gdb-flash.scr
monitor swdp_scan
attach 1
load
compare-sections
mon hard_srst
detach
# this is gdb-kill.scr
monitor swdp_scan
attach 1
mon hard_srst
kill
Let’s make the gdb-flash.sh
script executable running chmod a+x gdb-flash.sh
and let’s give it a shot by running it with ./gdb-flash.sh
.
./gdb-flash.sh
Target voltage: 3.0V
Available Targets:
No. Att Driver
1 Nordic nRF52 M3/M4
2 Nordic nRF52 Access Port
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x00015fd6 in ?? ()
erase..
[Inferior 1 (Remote target) detached]
Target voltage: 3.0V
Available Targets:
No. Att Driver
1 Nordic nRF52 M3/M4
2 Nordic nRF52 Access Port
0xfffffffe in ?? ()
Loading section .sec1, size 0xb00 lma 0x0
Loading section .sec2, size 0xf000 lma 0x1000
Loading section .sec3, size 0x10000 lma 0x10000
Loading section .sec4, size 0x5de8 lma 0x20000
Start address 0x0, load size 153832
Transfer rate: 32 KB/sec, 973 bytes/write.
Section .sec1, range 0x0 -- 0xb00: matched.
Section .sec2, range 0x1000 -- 0x10000: matched.
Section .sec3, range 0x10000 -- 0x20000: matched.
Section .sec4, range 0x20000 -- 0x25de8: matched.
[Inferior 1 (Remote target) detached]
Target voltage: 2.9V
Available Targets:
No. Att Driver
1 Nordic nRF52 M3/M4
2 Nordic nRF52 Access Port
0x00000a60 in ?? ()
Loading section .sec1, size 0xa000 lma 0x26000
Loading section .sec2, size 0x8000 lma 0x30000
Start address 0x262b4, load size 73728
Transfer rate: 32 KB/sec, 957 bytes/write.
Section .sec1, range 0x26000 -- 0x30000: matched.
Section .sec2, range 0x30000 -- 0x38000: matched.
[Inferior 1 (Remote target) detached]
Target voltage: 3.0V
Available Targets:
No. Att Driver
1 Nordic nRF52 M3/M4
2 Nordic nRF52 Access Port
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x00000a80 in ?? ()
Kill the program being debugged? (y or n) [answered Y; input not from terminal]
[Inferior 1 (Remote target) killed]
Hopefully this post has been helpful for you! Of course let us know in the comments if there are things tripping you off or further explanation needed.
The following Posts / Sites were quite helpful getting this figured out, so kudos to these: