Zephyr RTOS development on OpenBSD

Background

In summary I think Zephyr RTOS development setup is extremely complicated. Compared to e.g. Arduino IDE it is just silly.

There are huge sets of dependencies "just" to develop for small embedded boards. Their quite ambitious goal to do it in a platform independent way, of course makes it more complicated, but I think something is off in the architecture of the whole solution.

They aim to make common abstractions for boards and supplementary drivers in a similar way as it is done in UNIX operating systems. But instead of automatic enumeration of architecuture and devices at boot time, the board is configured at compile time using KConfig tool and Device Tree configuration. As explained by Zephyr project ...

CMake is used to help create make files for the actual build.

These tools are used to help configure source code for a specific board, custom devices and configuration. Apart from these tools, a target compiler (SDK) is also need to build the source code as a target binary. Additionally you need tools for flashing and debugging on target (or in an emulated environment).

To handle this complex beast an additional tool called west has been developed that should help users to manage all the tasks involved in embedded development on Zephyr from the command line. There is also preliminary IDE support for development in VS Code.

But in general the whole environment seems like layers on top of layers of abstractions that makes the whole platform very complicated.

Select and Update OS

The setup should work for Ubuntu, macOs and Windows and is explained in quite good detail in Zephyr Getting Started Guide.

I first made an attempt to install on a macOS 10.13 (High Sierra), but that more or less failed to unsupported os for Homebrew. High Sierra was release 2017 with latest update in 2020 so its a bit dated.

Instead I made an attempt to install on latest OpenBSD 7.0 release which mostly succeeded. This is an explanation on this adventure ...

I mostly followed the Zephyr Getting Started Guide with some small modifications for OpenBSD.

Install dependencies

First install some dependencies. This is identical to macOS but its fast because of pre-compiled packages.

doas pkg_add cmake ninja gperf python3 ccache qemu dtc

Also install pip package manager and make make the python 3 version default python.

doas pkg_add py3-pip
doas ln -sf /usr/local/bin/pip3.8 /usr/local/bin/pip
doas ln -sf /usr/local/bin/pip3.8 /usr/local/bin/pip3
doas ln -sf /usr/local/bin/python3.8 /usr/local/bin/python

Check that everything went well so far.

$ ninja --version
1.10.2
$ gperf --version
GNU gperf 3.1
$ python3 --version
Python 3.8.12
$ pip3 --version
pip 20.3.4 from /usr/local/lib/python3.8/site-packages/pip (python 3.8)
$ ccache --version
ccache version 4.4.1
$ qemu-img --version
qemu-img version 6.1.0
$ dtc --version
Version: DTC 1.6.1

Get Zephyr and install Python dependencies

First install the meta tool, west.

pip3 install -U west
$ west --version
West version: v0.11.1

Get Zephyr source

west init ~/zephyrproject
cd ~/zephyrproject
west update

Export a Zephyr CMake package

west zephyr-export

Next Zephyr requires a huge number (38) of additional python dependencies defined in.

~/zephyrproject/zephyr/scripts/requirements.txt

But to avoid build issues for native dependencies use OpenBSD packages where available ...

doas pkg_add rust	
doas pkg_add py3-pyaml
doas pkg_add py3-elftools
doas pkg_add py3-pykwalify
doas pkg_add py3-packaging
doas pkg_add py3-progress
doas pkg_add py3-psutil
doas pkg_add py3-anytree
doas pkg_add py3-colorama
doas pkg_add py3-ply
doas pkg_add py3-protobuf
doas pkg_add py3-Pillow
doas pkg_add py3-coverage
doas pkg_add py3-tabulate
doas pkg_add py3-mock

Then it should be safe to install remaining dependencies via pip.

cd ~/zephyrproject
pip3 install -r ./zephyr/scripts/requirements-base.txt 

List the python3 packages ...

pip3 list

Install a Toolchain

As there is only a pre packaged Zephyr toolchain for Ubuntu I go for manual install of GNU ARM Embedded toolchain.

This is installed as followed ...

doas pkg_add gdb
doas pkg_add gdbm
doas pkg_add arm-none-eabi-gcc-linaro
doas pkg_add arm-none-eabi-binutils
doas pkg_add arm-none-eabi-gcc-linaro
doas pkg_add arm-none-eabi-gdb
doas pkg_add arm-none-eabi-newlib

You need to setup a few environment variables to enable the toolchain.

export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
export GNUARMEMB_TOOLCHAIN_PATH=/usr/local

Or check it

echo $ZEPHYR_TOOLCHAIN_VARIANT
gnuarmemb
echo $GNUARMEMB_TOOLCHAIN_PATH
/usr/local

Build the Blinky Sample

I had a nRF52840 Dongle to test on. So I build a sample app as follows.

cd zephyr
west build -p auto -b nrf52840dongle_nrf52840 samples/basic/blinky

Or to always rebuild ...

west build -p always -b nrf52840dongle_nrf52840 samples/basic/blinky

Flash the Sample

Normally you connect e.g. a JLINK Debug Probe to connect to a board to program it or the board will include JLINK to allow debugging over USB.

However this board need to be flashed using nrfutil.

So first install it using pip. But here I got into some problems.

pip3 install nrfutil
nrfutil version                                                                 

This installs a bit older version 5.2 which is not compatible with python 3.8.

I tried to force install of latest version.

pip3 install nrfutil==6.1.3

But that is missing dependency pc_ble_driver_py.

pip3 install nrfutil==6.1.3               
ERROR: Could not find a version that satisfies the requirement pc_ble_driver_py>=0.16.1 (from nrfutil)
ERROR: No matching distribution found for pc_ble_driver_py>=0.16.1
pip3 install pc_ble_driver_py==0.16.1     
ERROR: Could not find a version that satisfies the requirement pc_ble_driver_py==0.16.1
ERROR: No matching distribution found for pc_ble_driver_py==0.16.1

Finally I forced the installed version to use python2 as follows to make the older version work.

which nrfutil
head /home/peter/.local/bin/nrfutil                                             

#!/usr/local/bin/python2.7

# Replace default version ...
# # !/usr/local/bin/python3.8
...

After that I could generate a package to flash.

cd zephyr
nrfutil pkg generate --hw-version 52 --sd-req=0x00 \
--application build/zephyr/zephyr.hex \
--application-version 1 blinky.zip

Next step is to flash the package to the dongle. First set board in upgrade mode (DFU) by pressing reset button. Next flash the image using nrfutil.

dmesg 	# to see which device attached
nrfutil dfu usb-serial -pkg blinky.zip -p /dev/cuaU0  	# press reset on board

On macOS the device name is different e.g.

nrfutil dfu usb-serial -pkg blinky.zip -p /dev/tty.usbmodemFD131

I don't get this build to work correctly i.e. blink the LEDs.

You may try flash a prebuild application (hex file) to make sure the board hardware works. You may get the from here named blinky_pca10059_mbr.hex. Rebuild the blinky.zip using this hex file and reflash.

References