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
- To disable the interfacing MCU make sure to flip the switch for the Power Selecting to
nRF ONLYinstead of
- Attach the 8 Pin Connector from the Blackmagic Probe with the
Debug inheaders on the NRF52DK.
- Attach Power via Micro USB to the NRF52DK.
- Attach the USB of the Blackmagic Probe to the host system (hitting
dmesgshould show that two new
/dev/ttyACMXDevices 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
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
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
Note: there are two popular options to skip finding your toolchain folder over and over again. One is to add it to the
PATHenvironment variable in the
~/.profilefile or link the binary somewhere with
ln -sin the
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) 18.104.22.16890703-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
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
#!/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
# 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 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: