I’ve recently started programming BLE Chips and found it to be quite complicated to setup on my Ubuntu. On Windows you’ve got Keil and nRFgo and nice installers for all the tool you need and you’re ready to go in less than an hour. On Linux you can use mbed, if your devices support it. If they’re not mbed-enabled you still can only use the mbed online-compiler, which is worth a look. But let’s get to the good part:
Hardware
I use two devices, a PCA10001 Development Dongle and a breakout-board like this, both with a nRF51822 SoC. To flash these SoCs I use Seggers J-Link interface. It’s the standard interface for Nordic devices and most of them already have it on chip (like my dongle or the nRF Development Kit board). The breakout-board doesn’t, so I used a debug probe which was part of a nRF Starter Kit. You can’t buy those standalone but there are cheap alternatives like the EDU-model from Segger. You can also flash these breakout-boards with the nRF-DK (is has SWD output for that purpose) or use something lika a buspirate (follow Florian Echtlers tutorial for that).
The Segger J-Link Lite Cortex9 i use has a 9-pin SWD out. Since these pins are to small so solder (or connec to to a breadboard) i plugged it into a SWD-JTAG converter. The following table shows you how to wire the devices correctly:
SWD | JTAG | nrf51 | 3.3V source |
VCC | VTREF | — | + 3.3V |
SWDIO | TMS | SWDIO | — |
SWDCLK | TCK | SWDCLK | — |
GND | GND | GND (both) | GND |
On some boards SWCLK is wrongly labeled SWO, don’t get confused by that.
Tools setup
As mentioned earlier i used Ubuntu 14.04 LTS. To flash and debug the SoC you always need the Nordic SDK, GNU tools (which can be ignored since Linux has them anyways) and the ARM gcc tools. Additionally you need the J-Link software if you use J-Link to flash your SoC.
Download the SDK from Nordic, the ARM tools and the J-Link software and documentation pack and extract them somewhere you like:
sudo tar -xzf ./nRF51_SDK_8.1.0_b6ed55f.zip -C /opt/ble sudo tar -xzf ./JLink_Linux_V510u_i386.tgz -C /opt/ble sudo tar -xzf ./gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2 -C /usr/local
Change permissions so you can access and execute them and link these files to /usr/bin and copy the usb permissions file:
sudo ln -s /opt/ble/JLink/JLinkGDBServer /usr/bin/JLinkGDBServer sudo ln -s /opt/ble/JLink/JLinkExe /usr/bin/JLinkExe sudo cp 99-jlink.rules /etc/udev/rules.d/
Before we can start compiling we need to connect the arm-gcc to the Nordic SDK. Go to /opt/ble/nRF51_SDK_/components/toolchain/gcc/ and edit the Makefile.posix:
GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_9-2015q3 GNU_VERSION := 4.9.3 GNU_PREFIX := arm-none-eabi
Get an example running
Since we now got all the tools we need, its time to get something on the chip. First we need to check the connection and flash the softdevice afterwards. Open a terminal and start the JLink interface and connect:
~$ JLinkExe -device nrf51822 -speed 1000 -if swd >connect 1
This should give you an output like this one to confirm you can communicate with the target device:
The softdevice is something like an OS to enable the devices BLE-capabilities. Without, you can only run non-BLE ARM code on your SoC. It’s included in a handy, precompiled hex-file in the SDK. Connect to JLink again, completely erase the device.
~$ JLinkExe -device nrf51822 -speed 1000 -if swd > w4 4001e504 2 > w4 4001e50c 1 > sleep 100 > r
and flash /opt/ble/nRF51_SDK_/components/softdevice/s110/hex/s110_softdevice.hex:
> w4 4001e504 1 > loadfile ./s110_softdevice.hex > r > g
If you got no errors, everything worked out. There is a different softdevice for each device-role: s110 for ble-peripheral only, s120 for ble-central and s130 for both in one. Now you can flash one of Nordics sample projects on top of it.
Change to ./examples/ble_peripheral/ble_app_hrs/pca10028/s110/armgcc. You’ll find two files there, a makefile and a linker-script. Edit the makefile and change
CFLAGS += -Wall -Werror -O3 to CFLAGS += -Wall -Werror -O0 -g3
CFLAGS += -fno-builtin --short-enums to CFLAGS += --short-enums
add OUTPUT_FILENAME = nrf51422_xxac_s110 right below OBJECT_DIRECTORY
below flash: find $(OUTPUT_BINARY_DIRECTORY)/$<.hex and replace the $< with $(OUTPUT_FILENAME)
This allows us to establish a debugging connection later on. The linker script contains information about where to place the program in the flash an where and how much ram is left for it. My nRF51822 has 256 Kbytes of flash (0x40000) and 16 Kbytes of RAM (0x4000). The s110 softdevice in SDK 8.1.0 takes up 0x18000 of flash and 0x2000 of RAM, so we need to tell the compiler where to put the program. You can check how much RAM and flash your device has by checking the chip marking.
Edit the following lines to:
FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x28000
RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000
Change into the directory where the makefile is and „make“. This will generate a directory called _build, containing the compiled code of the example. Now you can flash the hex-file with the program code:
~$ JLinkExe -device nrf51822 -speed 1000 -if swd > r > loadfile ./nrf51422_xxac_s110-hex > r > g
You should now be able to connect to the device using a ble-central eg. Android(-clone) app for ble like the Nordic Toolbox.
Setup an actually usable environment (in Eclipse)
The first thing you want to get rid of is typing in the commands to flash manually. This is quite easy since we can put the JLink commands in a shell script (take mine). Link this script to /usr/bin
, you’ll need it later:
~$ sudo ln -s "./nrfjprog.sh" "/usr/bin/nrfjprog"
Download the Eclipse C++ IDE for Linux. I use the Luna release. Extract and start the IDE. After that, go to the marketplace and install the „GNU ARM Eclipse“-Plugin. If you encounter any problems, check the official documentation.
Go to Window -> Open Perspective -> Other and open the Packs-view. Press the Update-button (the yellow one at the top-right side) and go get a snack. Once the update is finished, you can select Nordic Semiconductor - nRE51
from the list on the left hand side and install the nRF_DeviceFamilyPack.
Go to Window -> Preferences -> C/C++ -> Global Tools Path. Build tools folder should be the path to make
and Toolchain folder should be the path to the arm-gcc tools.
Go to Window -> Preferences -> Run/Debug -> Segger J-Link. Executable should be JLinkGDBServer
and Folder the place where you extracted the Segger tools to (alternatively /usr/bin
if you linked it).
Now we want to import a project. Select: New -> Makefile Project with Existing Code. Enter a name and browse to the directory containing the makefile (you can use the hrs-app from above). Select Cross ARM GCC
as toolchain. Your new project should contain the makefile and the linker script. You need to make the same modifications to them as in the manual part (if you didn’t already). If you want to see the source files, you need to add them using virtual folders. To get rid of all the errors and warnings, you can go to Project Properties -> C/C++ General -> Path and Symbols, select the „Includes“ tab and add at GNU C all files that are added to INC_PATHS
in the makefile (but you don’t have to, it will compile anyways).
To flash directly from the IDE, change the following compiler settings:
Go to Project Properties -> C/C++ Build, Builder Settings tab and change the build-command to make
.
Go to C/C++ General -> Preprocessor Include, Providers tab. Select „CDT GCC Build Output Parser“ and change „Compiler command pattern“ to (arm-none-eabi-gcc)|([gc]++)|(clang)
. Select CDT Built-in Compiler Settings Cross ARM
and change Command to get compiler spect
to arm-none-eabi-gcc ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}
Now you can create make targets
to flash the target device with the push of a button. Open the C/C++ perspective and open the Make Target
view on the right hand side. These make targets will call commands from the makefile, so you can create new ones if you need them later on. Now create four new targets: clean, flash, flash_softdevice and nrf51422_xxac_s110
. As build command enter make
. You need to change a last thing in the makefile so it works with our custom nrfjprog. Open the makefile and scroll down to the bottom. There you’ll find flash: and flash_softdevice:
. Change the options for nrfjprog from --reset --program
to --flash and --flash_softdevice
respectively. „Clean“ will remove all compiled files from the project, nrf51422_xxaac_s110 will compile it and flash does exactly what you think it does.
Please note: you only need to flash_softdevice once. At least if you’re using J-Link. If you don’t, check the references at the bottom of this page.
Debugging nRF51s
There are multiple ways to debug your apps. The most basic one is just to connect to your device via Android and check if it does what it should do. I recommend using the Nordic Toolbox or the Nordic Master Control Panel. Android weirdly caches BLE devices, so if connect to them and then reflash, most of the general ble-apps just break and you need to kill them (or even restart ble/your phone).
A somewhat more powerful way is to use UART. It’s a protocol to exchange messages from a peripheral to a central device and even to a connected PC. If you have a J-Link connected for example, you can connect your terminal to a UART COM-port and connect your smartphone and chat with yourself using the Nordic Toolbox app and the UART example project. A similar but less resource-consuming approach is RTT-debugging but i haven’t tested this jet so I’m just going to link it here.
The last-resort option is to read out the target devices registers. You can do this by setting up debugging in Eclipse using JLinkGDBServer and setting breakpoints. There is a really good tutorial by Javier Montaner you should check out if you want to try this.
References
If you can use Windows, do it. Nordic has excellent tools (like nRFGo Studio and Keil), installers and documentation for you.
If you want to go deeper into reading out registers check out the EmbSysRegView Plugin for Eclipse (you may need this).
As you might have guessed, nrfjprog is originally a different tool contained in the nRF5x Command Line Tools. It’s necessary for Windows, but I deem it unnecessary clutter on my setup. BUT if you’re not using J-Link, you’ll need it. It contains a program called mergehex
, which combines softdevice and program into one hex-file.
My next article in this series will be about programming basic ble functionality and pin-I/O on the chip. Follow me on Twitter @Leavesified to know when its done.
If you have any questions, problems, remarks or suggestions you’re welcome to leave a comment.
awesome post, thanks! ive been bashing my head at outdated information for a few hours before i found this.
LikeLike
Hello I am trying to setup a linux development environment for the same hardware setup. This tutorial is amazing thank you very much for the work you have done so people like me can easily setup the nordic sdk into eclipse.
I only have one question for now can you please add again the download link for the nrfjprog.sh (the link isnot working)
Thank you.
LikeLike
Here you go: http://leavesified.com/uploads/nrfjprog.sh
LikeLike
Thank you very much
LikeLike
Sehr gut ! 🙂 I am from Romania. This helped me from A to Z. GREAT POST on linux development. Spot on ! In 20 minutes I was able to program my nrf51822. Great !
LikeLike
Hi,
I wrote a quick guide for a newer environment for nRF52832 (in Linux).
https://bus710.gitbooks.io/nrf-development-in-linux/content/
Hope this can be a little help.
Thanks,
LikeLike