nrf: Nordic Semiconductor nRF5340 and nRF52840 (nRF MDK)

This guide’s aim is to help you with using Contiki-NG for Nordic Semiconductor’s nRF5340 and nRF52840 SoCs (using nRF MDK).

This port supports the PCA10095 (nRF5340-DK), PCA10059 (nRF52840-DONGLE) and PCA10056 (nRF52840-DK) boards. It also provides the M33 application-core side of the nRF54L15 (PCA10156 DK and Seeed XIAO nRF54L15); see the nRF54L15 section below.

Port Features

The following features have been implemented:

  • Support for the 802.15.4 mode of the radio, including IPv6 using 6LoWPAN

  • Support for both TSCH and CSMA

  • No dependency on the nRF5 SDK

  • Contiki-NG system clock and rtimers

  • UART driver

  • Watchdog driver

  • RNG driver seeded from the hardware RNG

  • Temperature sensor driver

  • DK/Dongle LED and Button driver

Note that this port does not support BLE.

The port is organized as follows:

  • nRF CPU drivers are located in the arch/cpu/nrf folder.

  • The nrfx is located in the arch/cpu/nrf/lib/nrfx folder. This will be installed automatically as a git submodule.

  • nRF boards configuration are located in the arch/platform/nrf/<SoC>/<Board>/<Core (nRF5340 Exclusive)>/ folder.

    • SoC’s: nrf5340, nrf52840

    • Boards:

      • nrf5340: dk

      • nrf52840: dk, dongle

    • Cores:

      • nrf5340: application, network

Prerequisites and Setup

In order to compile for the nRF5340 and nRF52840 platforms you’ll need:

  • An ARM compatible toolchain

The toolchain used to build Contiki-NG is arm-gcc, also used by other arm-based Contiki-NG ports.

If you use the docker image or the vagrant image, this will be pre-installed for you. Otherwise, depending on your system, please follow the respective installation instructions (native Linux / native mac OS)

  • GNU make

  • nrfutil for programming the nRF5340 DK, nRF52840 DK and nRF52840 Dongle

nrfutil (the Rust-based binary, which replaces the end-of-life nrfjprog and the deprecated Python nrfutil from PyPI) can be downloaded from:

https://www.nordicsemi.com/Products/Development-tools/nRF-Util

After downloading the binary, install the required subcommands:

nrfutil install device

For flashing the nRF52840 Dongle, the nRF5 SDK tools are also needed:

nrfutil install nrf5sdk-tools
  • jq

The .upload targets use jq to select the attached device to program: filtering devkits by device family and looking up a device by PORT=<serial port> both require it. Without jq, uploads that need such a lookup fail with an error asking for an explicit NRF_UPLOAD_SN=<serial number>.

Getting Started

Once all tools are installed it is recommended to start by compiling and flashing examples/hello-world application. This allows to verify that toolchain setup is correct.

To compile the example, go to examples/hello-world and execute:

make TARGET=nrf

If the compilation is completed without errors flash the board:

make TARGET=nrf hello-world.upload

Examples

This target supports all the common IPv6 examples available under the examples/ folder.

Compilation Options

The Contiki-NG TARGET name for this port is nrf, so in order to compile an application you need to invoke GNU make as follows:

make TARGET=nrf

In addition to this port supports the following variables which can be set on the compilation command line:

  • NRF_UPLOAD_SN=<serial number>
    Allows to choose a particular DK by its serial number (printed on the label).
    This is optional when exactly one DK of the targeted device family is attached (devices of other families are ignored). With more than one matching device connected, the .upload target refuses to program and lists the attached serial numbers; select one with NRF_UPLOAD_SN=<serial number> or use the .upload-all target to flash all attached devices of the targeted family. The same applies to the nRF52840 Dongle: with several dongles attached, select one with NRF_UPLOAD_SN (the dongle keeps its USB serial number in both firmware and bootloader mode).

  • NRF_RECOVER=1
    Runs nrfutil device recover on the selected device immediately before programming. Use this to unlock a device that has enabled access port protection (e.g. locked itself). Warning: recovery performs a full chip erase of the selected core. It is therefore never done by default and only when NRF_RECOVER=1 is explicitly given on the make command line. Works with both the .upload and .upload-all targets.

  • PORT=<serial port>
    Selects the device to program by one of its serial ports (as listed by tools/motelist or make motelist-all), when NRF_UPLOAD_SN is not given. Works for both DKs and dongles. Since PORT is also used by the login target, the same variable selects the node for both programming and serial output. Only a PORT given on the make command line selects the device to program; a PORT from the environment is ignored for device selection (but still used by login).

  • BOARD={nrf5340/dk/application|nrf5340/dk/network|nrf52840/dk|nrf52840/dongle}
    Allows to specify if the which board and core (nrf5340 exclusive) is used. The default board is nrf5340/dk/application Dongle images are built with a bootloader-specific linker file and are flashed via the Nordic open bootloader (DFU) by the regular .upload target.

  • NRF_NATIVE_USB=<0,1>
    Enables or disables the native USB support on boards that have USB support. This will automatically change the debug and the slip from UART to USB.

Compilation Targets

Invoking make solely with the TARGET variable set will build all applications in a given folder. A particular application can be built by invoking make with its name as a compilation target:

make TARGET=nrf hello-world 

In order to flash the application binary to a single nRF5340 DK board in the application core use <application>.upload as make target, e.g.:

make TARGET=nrf hello-world.upload

In order to flash the application binary to all attached nRF5340 DK board in the application core use <application>.upload-all as make target, e.g.:

make TARGET=nrf hello-world.upload-all

The .upload-all target also works for nRF52840 Dongles: it triggers DFU mode on and flashes all attached dongles, e.g.:

make TARGET=nrf BOARD=nrf52840/dongle hello-world.upload-all

Flashing a single nRF52840 Dongle uses the regular .upload target, e.g.:

make TARGET=nrf BOARD=nrf52840/dongle hello-world.upload

The upload automatically triggers the DFU bootloader on a dongle running Contiki-NG firmware. For a dongle running other firmware, the bootloader can be activated manually by pressing the RESET button once, until the red LED begins to pulse. With more than one dongle attached, select one with NRF_UPLOAD_SN=<serial number> or PORT=<serial port>.

Notes when using the nRF dongle:

  • The serial output from the dongle can be accessed by attaching a USB to Serial converter to the pins described on the back of the board.

  • If nrfutil returns an error such as LIBUSB_ERROR_ACCESS when attempting to perform a DFU trigger the following udev rules might be required:

## Set /dev/bus/usb/*/* as read-write for all users (0666) for Nordic Semiconductor devices
SUBSYSTEM=="usb", ATTRS{idVendor}=="1915", MODE="0666"

To remove all build results invoke:

make TARGET=nrf clean

nRF5340

The nRF5340 is a dual-core SoC with two ARM Cortex-M33 processors known as the application core and the network core. Only the network core has access to the 802.15.4 radio peripheral.

TrustZone Secure Radio

The IPC radio driver can optionally run in the ARM TrustZone secure world, providing a hardware-enforced security boundary for radio communication. In this mode, the normal world accesses the radio through Non-Secure Callable (NSC) entry points that validate all pointers via CMSE. This enables communication policies to be enforced in the secure world.

Building for TrustZone:

  1. Build the secure world and the network core radio service:

     make -C examples/platform-specific/nrf/trustzone/secure-world
     make -C examples/platform-specific/nrf/ipc-radio-service TARGET=nrf BOARD=nrf5340/dk/network
    
  2. Build the normal-world application:

     make -C examples/rpl-udp TARGET=nrf BOARD=nrf5340/dk/application \
          TRUSTZONE_SECURE_BUILD=0 \
          TRUSTZONE_SECURE_WORLD_PATH=../../examples/platform-specific/nrf/trustzone/secure-world \
          udp-server
    

    The tz_radio_driver is selected automatically in the normal-world build.

  3. Merge the secure and normal world hex files:

     srec_cat \
       examples/platform-specific/nrf/trustzone/secure-world/build/nrf/nrf5340/dk/application/secure-world-example.hex -Intel \
       examples/rpl-udp/build/nrf/nrf5340/dk/application/udp-server.hex -Intel \
       -o merged.hex -Intel
    
  4. Flash the network core and merged application core.

See examples/platform-specific/nrf/ipc-radio-service/README.md for the complete step-by-step instructions.

GPIO Forwarding (Legacy)

An alternative approach is to run the full OS on the network core and use the application core only to start the network core and forward GPIO pins. This is provided by the start-network-core example:

make TARGET=nrf BOARD=nrf5340/dk/application start-network-core.upload

Once the application core contains this example, a Contiki-NG application can be uploaded to the network core:

make TARGET=nrf BOARD=nrf5340/dk/network hello-world.upload

The start-network-core example forwards UART, buttons, and LEDs. If extra GPIOs are needed on the network core, they must be forwarded in start-network-core.

nRF54L15

The nRF54L15 is an ARM Cortex-M33 SoC (128 MHz, 1536 KB RRAM, 256 KB RAM) with a 2.4 GHz radio supporting 802.15.4 and Bluetooth LE 5.4. As with the other boards in this port, its application core runs the full Contiki-NG networking stack — 802.15.4, 6LoWPAN/IPv6, RPL, and CSMA — so the standard IPv6 examples build and run on it. (As elsewhere in this port, BLE is not supported.) The SoC also carries a RISC-V coprocessor, the FLPR, with its own Contiki-NG port; see FLPR coprocessor below.

Two boards are supported, selected with BOARD:

  • nrf54l15/dk — nRF54L15-DK (PCA10156)

  • nrf54l15/xiao — Seeed XIAO nRF54L15

Build and flash any standard example as usual:

make TARGET=nrf BOARD=nrf54l15/xiao hello-world.flash

Radio submodule. The 802.15.4 driver wraps Nordic’s nrf_802154 library, which ships in the sdk-nrfxlib git submodule. Initialise submodules before building or the link fails with missing networking symbols:

git submodule update --init --recursive

Flashing. Unlike the nRF5340/nRF52840 DKs (which use nrfjprog/J-Link), the two nRF54L15 boards are flashed with the .flash target:

  • nrf54l15/xiao — over its onboard CMSIS-DAP using stock OpenOCD 0.12.0+. No nRF54L15-specific OpenOCD flash driver is required: the board config writes RRAM with load_image and never invokes an OpenOCD flash driver. The board-specific openocd.cfg is selected automatically by the Makefile.

  • nrf54l15/dk — over its onboard SEGGER J-Link.

Current limitations. Low-power modes, the watchdog driver, and the temperature sensor are not yet supported on the nRF54L15.

FLPR coprocessor

The FLPR (Fast Lightweight Peripheral Processor) is a RISC-V VPR coprocessor (RV32EMC) on the nRF54L15. It has its own Contiki-NG port, built with a separate nrf-vpr target: the M33 image embeds and launches a small FLPR kernel (process scheduler, etimer/ctimer, GRTC-driven clock_time(), GPIO output) while the 802.15.4 radio stays on the M33.

For the full guide — toolchain setup (the FLPR needs an RV32EMC RISC-V GCC), build/deploy steps, the boot sequence, and the hello-vpr / flpr-host examples — see the nrf-vpr platform documentation.

Support

For bug reports or/and suggestions please open a github issue.

License

All files in the port are under BSD license. The nrfx is licensed on a separate terms.

Resources