Zephyr - an OS for IoT
IoT OS Landscape
These days there's no lack of operating systems to choose from for embedded systems; Wikipedia counts about 100 of them. The Eclipse survey still shows Linux leading the pack, with Windows, FreeRTOS and Mbed OS being widely used as well.
For devices that have the necessary resources, full-blown operating systems like Linux (Android) or Windows dominate the field, but for more constrained devices, there's a wide range of systems being used.
The Eclipse IoT Developer Survey 2019 shows more use of actual operating systems in IoT device firmware, as opposed to bare-metal programming or building on top of a minimal kernel.
For a summary of the current landscape, you can scroll through the table below:
Name | Org | License | (*) | Platforms |
---|---|---|---|---|
FreeRTOS | Amazon AWS | MIT | 19% | ARM, AVR, AVR32, ColdFire, ESP32, HCS12, IA-32, Cortex-M3-M4-M7, Infineon XMC4000, MicroBlaze, MSP430, PIC, PIC32, Renesas H8/S, RX100-200-600-700, 8052, STM32,TriCore,EFM32 |
Mbed OS | ARM | Apache 2.0 | 6% | Cortex-M, Cortex-R, Cortex-A |
embOS | Segger | Proprietary | 6% | ARM7/9/11, ARM Cortex-A/R/M, AVR, AVR32, C16x, CR16C, ColdFire, H8, HCS12, M16C, M32C, MSP430, NIOS2, PIC18/24/32, R32C, R8C, RISC-V, RL78, RH850, RX100/200/600/700, RZ, SH2A, STM8, ST7, V850, 78K0, 8051 |
Contiki | contiki-os.org | BSD | 5% | MSP430, AVR, ARM |
RIOT | riot-os.org | LGPL | 5% | ARM, MSP430, AVR, x86 |
TinyOS | TinyOS Alliance | BSD | 5% | Atmel ATMega128, Intel XScale PXA271, TI MSP430, CC100/CC2500, CC2420 |
VxWorks | WindRiver | Proprietary | 5% | ARM, IA-32, Intel 64, MIPS, MIPS, PowerPC, SH-4, StrongARM, xScale |
LiteOS | Huawei | BSD | 5% | ARM (M0/3/4/7, A7/17/53, ARM9/11), X86,RISC-V |
QNX | QNX | Proprietary | 3% | IA-32, MIPS, PowerPC, SH-4, ARM, StrongARM, XScale |
Zephyr | Linux Foundation | Apache 2.0 | 3% | ARM (Cortex-M0, Cortex-M3, Cortex-M4, Cortex-M23, Cortex-M33, Cortex-R4, Cortex-R5),x86,x86-64, ARC,RISC-V,Nios II,Xtensa |
Others | 6% | |||
Mynewt | Apache | Apache 2.0 | ARM Cortex-M, MIPS32, Microchip PIC32, RISC-V | |
MicroC/OS | Micrium | Proprietary | ARM7-9-11/Cortex-M1-3-4-A8/9, AVR, HC11/12/S12, ColdFire, Blackfin, MicroBlaze, NIOS, 8051, x86, Win32, H8S, M16C, M32C, MIPS, 68000, PIC24-dsPIC33-PIC32, MSP430, PowerPC, SH, StarCore, RenesasRX100-200-600-700, RL; STM32, … | |
RTX Keil | ARM | Proprietary, royalty free | ARM | |
ThreadX | Microsoft Expresslogic | Proprietary | ARC, ARM/Thumb, AVR32, BlackFin, 680x0-ColdFire, H8-300H, Luminary Micro Stellaris, M-CORE, MicroBlaze, PIC24-dsPIC, PIC32, MIPS, V8xx, Nios II, PowerPC, RenesasRX100, RX200, RX600, RX700, Synergy, SH, SHARC, StarCore, STM32, StrongARM, TMS320C54x, TMS320C6x, x86/x386, XScale, Xtensa/Diamond, ZSP | |
TI-RTOS | TI | BSD | TI MSP430-432, C2000-5000-6000, TI's ARM families (Cortex M3-4F-R4-A8-A15), TI CC2xxx-CC3xxx |
(*) Eclipse IoT Developer Survey results.
Linux is widely used for IoT applications, but requires at least a Cortex-A MCU (or equivalent), and is not the preferred choice for more limited systems, such as Cortex-M.
FreeRTOS is quite popular in the embedded world and gets more support after the acquisition by Amazon in 2017. However, FreeRTOS is a bare operating system. Everything else such as drivers, file systems, crypto modules, network stacks, middleware, and a bootloader must be added from other sources.
ARM's Mbed OS has the out-of-the-box integration with ARM’s Pelion Device Management going for it, making it a great choice to learn about IoT device provisioning, connection and management through LwM2M. Provided by ARM, it obviously does not support popular IoT platforms like ESP32 or RISC-V.
Mynewt has everything you could wish for in an operating system for resource constrained IoT devices, but the BSP support is fairly limited.
Zephyr originated from the Virtuoso DSP operating system which initially got rebranded as "Rocket" kernel, following its acquisition by Wind River Systems, but became Zephyr in 2016 when it became a Linux Foundation hosted Collaborative Project. Major sponsors and contributors of this open source collaborative effort include Intel, Nordic Semiconductor, NXP, SiFive, Synopsys and TI.
Like many other operating systems, Zephyr provides:
- Secure bootloader (MCU Boot)
- Kernel
- Network stacks
- File systems (NFFS, LittleFS, NVS)
- Middleware (including the MCUmgr OTA mechanism and LwM2M client functionality)
- Device drivers
Zephyr Licensing
Zephyr is mostly licensed under the Apache 2.0 license, but drivers from Nordic and NXP are licensed under the permissible BSD-Clause-3 version, although some of the build tooling is GPLv2.
Example Project
An example Zephyr firmware project can be found on https://github.com/bcdevices/ly10-zephyr-fw
This project is a demonstration firmware for our nRF52-based "LY10" demo board, which we ship with our Production Line Tool.
Clone
Use the following Terminal command to obtain a local copy of this example project.
git clone https://github.com/bcdevices/ly10-zephyr-fw.git
Building
To simplify building the firmware, we've setup this project with Docker-based build scripts, avoiding the need to install anything else than Docker itself.
To build:
make docker
$ make docker
install -d /home/user/src/GIT/ly10-zephyr-fw/dist
docker build --network=host -t "bcdevices/ly10-zephyr-fw" .
Sending build context to Docker daemon 66.05kB
Step 1/3 : FROM bcdevices/zephyr-west:zephyr-1.14.1-1
---> adce8e0e4d50
Step 2/3 : WORKDIR /usr/src/
---> Using cache
---> 30a0b745f2e6
Step 3/3 : COPY . /usr/src
---> Using cache
---> aefbd1076651
Successfully built aefbd1076651
Successfully tagged bcdevices/ly10-zephyr-fw:latest
docker run --network=none --name "ly10-zephyr-fw-0.2.3-1-g3413f54"
-t "bcdevices/ly10-zephyr-fw" \
/bin/bash -c "make build dist"
source /usr/src/zephyrproject/zephyr/zephyr-env.sh && \
cd app && \
west build --pristine auto --board "ly10demo" -- -DBOARD_ROOT="/usr/src"
source directory: /usr/src/app
build directory: /usr/src/app/build (created)
BOARD: ly10demo
Zephyr version: 1.14.1
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.6.8",
minimum required is "3.4")
-- Selected BOARD ly10demo
-- Found west: /usr/local/bin/west (found suitable version "0.5.7",
minimum required is "0.5.6")
-- Loading /usr/src/boards/arm/ly10demo/ly10demo.dts as base
-- Overlaying /usr/src/zephyrproject/zephyr/dts/common/common.dts
Parsing Kconfig tree in /usr/src/zephyrproject/zephyr/Kconfig
Loading /usr/src/boards/arm/ly10demo/ly10demo_defconfig as base
Merging /usr/src/app/prj.conf
Configuration written to '/usr/src/app/build/zephyr/.config'
-- Cache files will be written to: /root/.cache/zephyr
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
-- Performing Test toolchain_is_ok
-- Performing Test toolchain_is_ok - Success
Including module: tinycbor in path: /usr/src/zephyrproject/modules/lib/tinycbor
-- Configuring done
-- Generating done
-- Build files have been written to: /usr/src/app/build
[1/168] Preparing syscall dependency handling
[163/168] Linking C executable zephyr/zephyr_prebuilt.elf
Memory region Used Size Region Size %age Used
FLASH: 91809 B 512 KB 17.51%
SRAM: 15912 B 64 KB 24.28%
IDT_LIST: 152 B 2 KB 7.42%
[168/168] Linking C executable zephyr/zephyr.elf
rm -rf /usr/src/dist
install -d /usr/src/dist
install -m 666 app/build/zephyr/zephyr.hex dist/ly10-zephyr-fw-0.2.3-1-g3413f54.hex
install -m 666 app/build/zephyr/zephyr.elf dist/ly10-zephyr-fw-0.2.3-1-g3413f54.elf
install -m 666 app/build/zephyr/zephyr.map dist/ly10-zephyr-fw-0.2.3-1-g3413f54.map
sed 's/{{VERSION}}/0.2.3-1-g3413f54/g' test-suites/suite-LY10-zephyr.yaml.template
> dist/suite-LY10-zephyr-0.2.3-1-g3413f54.yaml
docker cp "ly10-zephyr-fw-0.2.3-1-g3413f54:/usr/src/dist"
/home/user/src/GIT/ly10-zephyr-fw
The resulting ly10-zephyr-fw-VERSION.hex file can be programmed through the west tool (if you've installed the Zephyr tooling locally), or use target-specific Vendor tools (nRF Connect Programmer).
Source Code
The demo firmware source code is very simple, contained in the src/app folder:
- main.c: Main controller
- app_ble.c: BLE adapter
- app_buzzer.c: Control PWM-driven piezo buzzer
- app_ledstrip.c: Control APA102 LED strip
- app_sensor.c: Read out SHT3XD sensor
Board Definitions
Building for one of the target boards directly supported by zephyr is a matter of specifying the correct board name.
Since the LY10 is a custom board that is not defined in the upstream Zephyr project, we're defining a custom board in boards/arm/ly10demo:
- board.cmake : cmake build file, specifying programming adapters to use.
- Kconfig : system-wide Kconfig settings affected by the LY10 board
- Kconfig.board : board-specific Kconfig settings
- Kconfig.defconfig : Kconfig defaults when building for an LY10 board
- ly10demo_defconfig : devicetree defaults when building for an LY10 board
- ly10demo.dts : board devicetree source
- ly10demo.yaml : YAML definition
References
- Zephyr RTOS Project, Linux Foundation hosted Collaboration Project
- Zephyr 2.0.0 Release Notes, Zephyr Project (September 2019)
- IoT Developer Survey 2019, Eclipse Foundation (April 2019)
- Zephyr Now Supports OMA LwM2M Protocol! What Can it Do for Me?, Zephyr Project (March 2018)
- Mynewt MCUmgr
About the Author
Ivo Clarysse is CTO at Blue Clover Devices. At heart, he is a software engineer with extensive experience working on embedded systems software and linux device drivers.
Leave a comment