There’s a spectrum of complexity in Embedded computing, from single board computers that can run Linux just like any other general purpose computer, down to tiny little microcontrollers with no room for anything but your application code. In the middle we have systems-on-a-chip like the ESP32, the Nordic nrf51 and nrf52 range, ST’s STM32 family, and a bunch of similar chips, that all run at a speed on the order of around 100mhz, with tens or hundreds of kBytes of ram, and a megabyte or four of flash memory. Too small for Linux, in most cases, but big enough to be quite powerful.
Some of these devices you can fit Linux on, like our home internet routers or many iot security cameras. And oddly enough, that’s where most of the horror stories about how “the S in IoT stands for security” come from. Securing a Linux system is tricky, and keeping it updated and secure is an ongoing effort. It’s not that Linux is by nature insecure, but rather that a Linux system consists of a huge number of parts interacting in complex ways that can have unintended consequences, and also that developers can lose focus and forget to clean up after their development shortcuts, leading to vulnerable devices in the field.
So what if we were to create a small, relatively simple operating system which makes it harder to fall victim to unexpected behaviour, and also provides a reliable field upgrade process?
A real-time operating system is one that is able to respond immediately to the needs of hardware (no spinning hourglass cursors!) by being monomaniacally focused on doing just a few things, well. It can often be expected to run for a long time without needing maintenance, and hopefully it can have a battery life measured in years, not hours.
So what’s out there in that space? You can cut down Linux and add a real time scheduling underkernel, you can choose from a number of commercial real time operating systems that aren’t too much unlike Linux, you can use whatever proprietary library-code your chip vendor provides, or you can use one or another of several Open-Source Real-Time Operating Systems such as Mynewt, or FreeRTOS, or Zephyr. At Accelerando, we’ve settled on Zephyr OS as our choice.
Some of the things that drew us to Zephyr were its association with the Linux foundation, its support for a wide number of chips (which gives us the option, if needed, to change silicon vendor with minimal disruption), the ease of adding support for new boards without needing to wait for vendor updates, and the fact that Zephyr has a LOT of built-in features and examples that cover common use cases.
Further bonuses of choosing Zephyr are that security and quality are a focus, and it’s a lot more convenient to debug and test than some other options.
Zephyr runs on most of the major chip families in use for IoT, including the recent Arduino boards, which means it’s an excellent choice for those who find themselves outgrowing the Arduino environment. Zephyr also runs on the ESP32 processor which we’ve used at Accelerando for many projects. Zephyr supports a heckton of different sensors and other peripherals out of the box, and its pretty easy to implement drivers for new peripherals.
The Bluetooth stack in Zephyr is good, and small. The OS is not opinionated about tools, you can generally use whichver IDE or editor you prefer, and there arent any black-box vendor code “blobs” that you have to blindly trust.
So you want to start coding for Zephyr? The compilers for different chips are mostly derived from the GNU Compiler Collection, the build system is Cmake, and there’s a Python wrapper that drives Cmake for you.
If that was just word-salad to you, Don’t Panic.
Installing all that stuff is only 4 steps, and you don’t really have to learn details about any of it.
After you’ve installed the necessities, building an application is just one command to build it, and one comannd to install it on your microcontroller. I can’t overstress how refreshing this all is compared to how embedded development has been in the past.
The Zephyr documentation at docs.zephyrproject.org is really good, and that’s where you should start to get yourself up and running.
The one page precis of getting started with Zephyr is:
Install Zephyr (you need to do this once only, and ongoing upgrades are easy, too):
pip3 install west west init ~/zephyrproject && west update pip3 install requirements.txt # download and install the compiler(s) (separate instructions for Linux, Mac, Windows)
When, in six months time, you want to upgrade to the next version of Zephyr, the upgrade procedure is:
cd ~/zephyrproject/zephyr && git pull cd ~/zephyrproject && west update
Build and run a project
(This example presumes you’re using SparkFun’s NRF52832 development board, which has the board name “nrf52_sparkfun”)
cd ~/zephyrproject/zephyr/samples/basic/blinky west build -b nrf52_sparkfun west flash