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:

    Operating Systems for constrained IoT devices
    Name Org License Official website (*) Platforms
    FreeRTOS Amazon AWS MIT freertos.org 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 os.mbed.com 6% Cortex-M, Cortex-R, Cortex-A
    embOS Segger Proprietary segger.com/embos.html 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 contiki-os.org 5% MSP430, AVR, ARM
    RIOT riot-os.org LGPL riot-os.org/ 5% ARM, MSP430, AVR, x86
    TinyOS TinyOS Alliance BSD tinyos.net 5% Atmel ATMega128, Intel XScale PXA271, TI MSP430, CC100/CC2500, CC2420
    VxWorks WindRiver Proprietary windriver.com/products/vxworks 5% ARM, IA-32, Intel 64, MIPS, MIPS, PowerPC, SH-4, StrongARM, xScale
    LiteOS Huawei BSD huawei.com/minisite/liteos/en/about.html 5% ARM (M0/3/4/7, A7/17/53, ARM9/11), X86,RISC-V
    QNX QNX Proprietary qnx.com 3% IA-32, MIPS, PowerPC, SH-4, ARM, StrongARM, XScale
    Zephyr Linux Foundation Apache 2.0 zephyrproject.org 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 mynewt.apache.org   ARM Cortex-M, MIPS32, Microchip PIC32, RISC-V
    MicroC/OS Micrium Proprietary micrium.com/rtos   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 keil.com/arm/rl-arm/kernel.asp   ARM
    ThreadX Microsoft Expresslogic Proprietary rtos.com/solutions/threadx   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.com/tool/sysbios   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:

    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:


    References


    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

    Please note, comments must be approved before they are published