Language: EN

Getting started with Zephyr on Ubuntu

How I installed Zephyr RTOS on Ubuntu Linux and flashed my first app to an nRF5340 DK, coming from bare metal.

Firmware ·

  • Zephyr
  • RTOS
  • nRF5340
  • Embedded C
  • Linux

Key specs

BoardNordic nRF5340 DK
SoCnRF5340, two Arm Cortex-M33 cores (application + network)
ComputerUbuntu Linux
Toolswest, Zephyr SDK, CMake, Ninja
DebuggerSEGGER J-Link, built into the DK
First appBlinky (samples/basic/blinky)

Block diagram

Block diagram. My app, the board files and Zephyr go into west build, which uses CMake, Ninja and GCC to make zephyr.hex. west flash sends it to the nRF5340 DK through the J-Link over USB, and LED1 blinks.

Overview

For years I wrote firmware on bare metal. I had my own main loop, interrupts, and drivers written straight on the registers. I wanted to try Zephyr, the open-source RTOS that Nordic, NXP, ST and many others now support. Here is how I set it up on Ubuntu and got my first app running on an nRF5340 DK.

Installing Zephyr on Ubuntu

1. Install the system tools

$ sudo apt update && sudo apt upgrade
$ sudo apt install --no-install-recommends git cmake ninja-build gperf \
    ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \
    xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1

2. Create a Python environment and install west

west is Zephyr’s command-line tool. It downloads the code, builds and flashes. I keep it in its own Python environment, so it doesn’t mix with Ubuntu’s Python.

$ python3 -m venv ~/zephyrproject/.venv
$ source ~/zephyrproject/.venv/bin/activate
$ pip install west

Every new terminal needs this command again before using west.

$ source ~/zephyrproject/.venv/bin/activate

3. Download Zephyr

$ west init ~/zephyrproject
$ cd ~/zephyrproject
$ west update
$ west zephyr-export
$ west packages pip --install

west update takes a while. It downloads Zephyr and all its modules, including the vendor libraries.

4. Install the Zephyr SDK

The SDK holds the compilers (GCC for Arm and other architectures) and debugging tools.

$ cd ~/zephyrproject/zephyr
$ west sdk install

5. Install the tools to flash the nRF5340 DK

The DK has a SEGGER J-Link debugger on board. To flash it from Linux I installed two tools.

  • the J-Link Software and Documentation Pack from SEGGER (the .deb file for Ubuntu),
  • nRF Util from Nordic, then its device commands.
$ nrfutil install device

6. Build and flash Blinky

The nRF5340 has two cores. Apps run on the application core, cpuapp.

$ cd ~/zephyrproject/zephyr
$ west build -p always -b nrf5340dk/nrf5340/cpuapp samples/basic/blinky
$ west flash

LED1 on the board starts blinking.

7. See the serial output

The hello_world sample prints to the DK’s USB serial port.

$ west build -p always -b nrf5340dk/nrf5340/cpuapp samples/hello_world
$ west flash
$ sudo usermod -aG dialout $USER   # once, then log out and back in
$ screen /dev/ttyACM0 115200       # quit with Ctrl+A, then K

What I learned - bare metal vs Zephyr

Bare metal means my code is the only thing on the chip. There is a while (1) loop, interrupts for anything urgent, and drivers written against the registers. It’s small, fast and fully predictable, and I know every line that runs. For a simple product, like one sensor and one job, it’s still the right choice.

It gets hard as the project grows. With BLE, a display, logging and a sensor all at once, the main loop turns into a pile of flags and state machines, and one slow task delays all the others.

Zephyr gives me four things.

  • Threads with priorities. Each job gets its own thread, and the scheduler runs the most urgent one first. Mutexes, semaphores and message queues let threads share data safely.
  • Ready-made stacks. Bluetooth LE, USB, networking, file systems, logging and a shell are all included, maintained and tested.
  • Portable code. The hardware is described in the devicetree and features are switched on in Kconfig (prj.conf). The same Blinky builds for hundreds of boards by changing only -b.
  • Both cores handled. On the nRF5340, Zephyr can run the Bluetooth controller on the network core for me. On bare metal I would have to manage both cores and the communication between them myself.

There is a price. Zephyr takes more flash and RAM, the build system (west, CMake, devicetree, Kconfig) takes time to learn, and errors can be harder to trace back.

My rule of thumb. For a small, single-purpose device, I use bare metal. As soon as I need several things running at once, wireless connectivity, or code that should survive a change of chip, I use Zephyr.

← Back to all projects