Skip to content

Instantly share code, notes, and snippets.

@ErezBinyamin
Forked from bertrandmartel/nRF51_linux_intall.md
Last active June 7, 2025 19:25
Show Gist options
  • Save ErezBinyamin/142a51d6984475e95eff5c127e71a269 to your computer and use it in GitHub Desktop.
Save ErezBinyamin/142a51d6984475e95eff5c127e71a269 to your computer and use it in GitHub Desktop.
nRF51 RE steps and Development Kit complete setup for Linux

nrf51822 RE

Reverse Engineering & Development tools for the Nordic nrf51822 arm chip

BOM

  • nrf51822
  • jumper wires
  • swd debugger (Flipper0)

nrf51822 Pinout

         ____________        
GND  21 |            | 18  20 
 22  23 |  nrf51822  | 17  19 
 24  25 |            | SWDIO SWCLK
 26  27 |            | 15  16
 28  29 |            | 13  14 
VDD GND |            | 11  12 
 30  00 |            | 09  10 
 01  02 |            | 07  08 
 03  04 |____________| 05  06

Instructions

1. Verify functional debugger/openocd installation

  1. Flipper0 -> Apps -> GPIO -> DAP Link
  2. Run command openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg
  3. Expected good output is:
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x0483:0x5740, serial=DAP_Olj1en
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: JTAG supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Serial# = DAP_Olj1en
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Error: Error connecting DP: cannot read IDR

2. Connect nrf51822 pins to Flipper0

  1. Careful! This process could fry chip
  2. Connect pins in order shown on table below
nrf51822 Flipper0 Comment
GND 18 GND
SWDIO 12 SIO
SWCLK 10 SWC
VDD 9 3V3 !! CAREFUL !!

3. Connect to nrf51822 over openocd

  1. Run command openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg
  2. Expected good output is:
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x0483:0x5740, serial=DAP_Olj1en
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: JTAG supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Serial# = DAP_Olj1en
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x0bb11477
Info : [nrf51.cpu] Cortex-M0 r0p0 processor detected
Info : [nrf51.cpu] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for nrf51.cpu on 3333
Info : Listening on port 3333 for gdb connections

4. Connect to nrf51822 over gdb

  1. Close out of openocd using Ctrl + c
  2. Run commands
$ openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg &>/dev/null &
$ gdb-multiarch
  1. From within gdb
(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) info reg
(gdb) dump binary memory dump.bin 0x00000000 0x00040000
  1. You have now won

5. Take a look at that elf

  1. Convert binary dump to an elf file (Get endiannes right):
arm-none-eabi-objcopy -I binary -O elf32-bigarm \
  --rename-section .data=.text \
  --redefine-sym _binary_dump_bin_start=_start \
  dump.bin dump.elf
  1. Take a look at the assembly: arm-none-eabi-objdump -D -m arm -M force-thumb dump.elf > dump.asm

Additional Resources

Mapping pinout from PCB to IC

  • LL: Left side / Left column
  • LR: Left side / right column
  • RL: Right side / left column
  • RR: Right side / right column
LL Pin IC pin LR Pin IC pin RL Pin IC pin RR Pin IC pin
GND P0.21 40 P0.18 26 P0.20 28
P0.22 41 P0.23 42 P0.17 25 P0.19 27
P0.24 43 P0.25 44 SWDIO 23 SWCLK 24
P0.26 45 P0.27 46 P0.15 21 P0.16 22
P0.28 47 P0.29 48 P0.13 19 P0.14 20
VDD 1 GND 2 P0.11 17 P0.12 18
P0.30 3 P0.00 4 P0.09 15 P0.10 16
P0.01 5 P0.02 6 P0.07 11 P0.08 14
P0.03 7 P0.04 8 P0.05 9 P0.06 10

Links to online resources

Extra Resources



nRF51 Development Kit complete setup for Linux

[Updated in 02/2020 - SDK 12.3.0]

Installation Steps

Toolchain

SDK

store the SDK path under NRF51_SDK_DIR :

export NRF51_SDK_DIR=$PWD/your-sdk-folder/nRF5_SDK_12.3.0_d7731ad
  • edit Makefile config : vi $NRF51_SDK_DIR/components/toolchain/gcc/Makefile.posix :
GNU_INSTALL_ROOT := <path_to_toolchain>
GNU_VERSION := 5.2.1
GNU_PREFIX := arm-none-eabi

Replace your toolchain path + your GNU version

For example :

GNU_INSTALL_ROOT := /home/user/adafruit-oled-st7735-dk51/gcc-arm-none-eabi-5_2-2015q4
GNU_VERSION := 5.2.1
GNU_PREFIX := arm-none-eabi

Uploader

get the nrf uploader :

Segger

Build

cd $NRF51_SDK_DIR/examples/peripheral/blinky/pca10028/blank/armgcc
make

Upload

make flash

Your blink example should be running

Debug your code (for manual testing using the makefiles)

I don't use the Segger files from the external folder in the SDK. I use the one from this gist : https://gist.github.com/bertrandmartel/25a566178766c7d0a7e04a18b341a732.

clone the gist and copy the folder under segger_rtt in the path below :

git clone https://gist.github.com/25a566178766c7d0a7e04a18b341a732.git
mkdir -p $NRF51_SDK_DIR/components/drivers_ext/segger_rtt
cp ./25a566178766c7d0a7e04a18b341a732/* $NRF51_SDK_DIR/components/drivers_ext/segger_rtt/

Update the blink example with #include "SEGGER_RTT.h" and SEGGER_RTT_printf(0, "Hello world!\n"); in the loop

Update the Makefile :

sed -i -e 's/external\/segger_rtt/components\/drivers_ext\/segger_rtt/g' $NRF51_SDK_DIR/examples/peripheral/blinky/pca10028/blank/armgcc/Makefile
sed -i '/RTT_Syscalls_GCC.c/d' $NRF51_SDK_DIR/examples/peripheral/blinky/pca10028/blank/armgcc/Makefile

Compile & upload:

make
make flash

start debug :

JLinkExe  -device  nRF51422_xxAC -speed 4000 -if SWD
> connect

In another terminal :

JLinkRTTClient

You should now see Hello world! in the client

Note: I used different Segger sources because I didn't find a good example how to compile properly the Segger files from the SDK. The only difference between the one of my gist & the SDK is SEGGER_RTT_Conf.h which is much simpler

CI script

A working CI script for DK 51 :

#!/bin/bash

wget -q https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
bzip2 -q -dc gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 | tar xf -
rm gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2
chmod +x $PWD/gcc-arm-none-eabi-5_2-2015q4/bin/*
ls -al $PWD/gcc-arm-none-eabi-5_2-2015q4/bin
mkdir -p sdk
wget -q https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/Binaries/nRF5SDK1230.zip -O sdk.zip
unzip -qq sdk.zip -d ./sdk
rm sdk.zip
export NRF51_SDK_DIR=$PWD/sdk/nRF5_SDK_12.3.0_d7731ad
echo "GNU_INSTALL_ROOT := `pwd`/gcc-arm-none-eabi-5_2-2015q4"$'\r\n'"GNU_VERSION := 5.2.1"$'\r\n'"GNU_PREFIX := arm-none-eabi"$'\r\n' > ${NRF51_SDK_DIR}/components/toolchain/gcc/Makefile.posix
mkdir -p $NRF51_SDK_DIR/components/drivers_ext/segger_rtt
git clone https://gist.github.com/25a566178766c7d0a7e04a18b341a732.git
cp ./25a566178766c7d0a7e04a18b341a732/* $NRF51_SDK_DIR/components/drivers_ext/segger_rtt/
echo $NRF51_SDK_DIR
echo $PATH
make

Sample projects

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment