Introduction to Zephyr RTOS: Features, Examples, Benefits and Challenges

Igal Zeifman
Igal Zeifman

5  min read | min read | 03/04/2023

Introduction to Zephyr RTOS: Features, Examples, Benefits and Challenges

Zephyr is an operating system designed for embedded devices, from small microcontrollers to full-fledged servers. Recently we witnessed it gaining a lot of traction with our current and potential customers. With that in mind, we decided to write this “Zephyr 101” post to help spread the word about its basic features, key benefits, and challenges.

What Is Zephyr RTOS?

Zephyr is a real-time operating system (RTOS) praised for its flexible support of multiple architectures and ability to provide features like preemptive multitasking, support for a variety of communication protocols, and real-time scheduling.

Zephyr is purpose-built for embedded devices; as such, it’s designed to be portable and modular, with a small footprint and low overhead. For that, Zepyr is written in C and C++ and built using the CMake build system.

As mentioned, Zephyr is an open-source project, and it is backed by the Linux Foundation and licensed under the Apache 2.0 license.

To learn more about the project and the community behind it, you should visit the Github page, the (very active) community Discord or this official site.

10 Key Features

  1. Preemptive multitasking: Zephyr supports preemptive multitasking, which means that tasks can be interrupted and resumed as needed to ensure that the most important tasks are always given priority.
  2. Real-time scheduling: Zephyr supports a range of real-time scheduling algorithms, including rate-monotonic scheduling and earliest-deadline-first scheduling, to ensure that tasks are executed on time.
  3. Support for multiple architectures: Zephyr supports a wide range of hardware architectures, including Arm Cortex-M, Intel x86, and RISC-V.
  4. Modular design: Zephyr is designed to be modular, with a range of optional features that can be included or excluded as needed. This makes it easy to customize the RTOS to meet the specific needs of a given application.
  5. Communication protocols: Zephyr supports a range of communication protocols, including TCP/IP, Bluetooth Low Energy, and USB, to enable communication between devices.
  6. Interrupt handling: Zephyr has a fast interrupt handling mechanism to ensure that critical tasks are given priority.
  7. Memory allocation and protection: Zephyr provides services for dynamic allocation. It also supports memory protection to prevent rogue tasks from accessing sensitive data or disrupting the operation of other tasks.
  8. Small footprint: Zephyr is designed to be efficient and has a small memory footprint, making it well-suited for use on resource-constrained devices. It also supports power management, allowing it to optimize the use of power on devices with limited power resources.
  9. Compile-time resource definition: Many aspects of the operating system, such as memory layout and the set of available drivers and libraries, are defined at compile time. This helps to reduce the overhead of the operating system and makes it easier to tailor the RTOS to the specific needs of a given application.
  10. Amazing documentation: The importance of documentation should not be underscored. Luckily, the online documentation for Zephyr holds a wealth of knowledge, making it easy for new developers to take their first steps with the project, serving as clear evidence of the support it’s receiving from the Linux Foundation and the community.

Zephyr Benefits and Challenges

Let’s start with the benefits:

  • Portability: Zephyr supports a wide range of hardware architectures and communication protocols and has a modular design that allows it to be customized for specific applications. This makes it easy to port the RTOS to new platforms and reuse it in different projects.
  • Scalability: A small footprint and low overhead make it well-suited for use on resource-constrained devices. It can also be extended with additional features as needed to support more complex applications.
  • Ecosystem: Zephyr is backed by the Linux Foundation and has a large and active community of contributors. This provides a wealth of resources and support for users of the RTOS.
  • Open source: Users can freely modify and distribute the RTOS as needed. This makes it a good choice for projects that require the ability to customize the RTOS or integrate it with other open-source software.

Here are some potential challenges that users of Zephyr may encounter:

  • Relative complexity: Zephyr is a full-featured real-time operating system and may be more complex than some other RTOSes, which could make it more challenging to learn and use.The amazing documentation we mentioned above helps to compensate for that. However, the initial learning curve might still feel a bit steep for some.
  • Dependence on third-party libraries: Like many other embedded OSs, Zephyr relies on several third-party libraries for certain features, such as networking and cryptography. This is not new, but still, something that opens the door to software supply chain vulnerabilities.

Examples of Basic Zephyr Operations

To illustrate day to day use of Zephyr, let’s here are examples of basic operations.

Creating a Task

Here is how to create a task in Zephyr:

1. Open a terminal window and navigate to the root directory of your Zephyr project.

2. Create a new directory for your task source files. For example:

$ mkdir src/my_task

3. In the my_task directory, create a new file called my_task.c with the following content:

#include <zephyr.h>
#include <sys/printk.h>

void main(void)
{
    while (1) {
        printk("Hello from my task!\n");
        k_sleep(K_SECONDS(1));
    }
}

4. In the my_task directory, create a new file called CMakeLists.txt with the following content:

add_executable(my_task my_task.c)
target_link_libraries(my_task PRIVATE zephyr_interface)

5. Open the CMakeLists.txt file in the root directory of your project and add the following line to the end of the file:

add_subdirectory(src/my_task)

From the root directory of your project, run the following commands to build your task:

$ mkdir build
$ cd build
$ cmake -GNinja -DBOARD= <your_board>..
$ ninja

Use the ninja command to flash your task to your board:

$ ninja flash

Your task should now be running on your board. You should see the message “Hello from my task!” printed to the console every second.

Creating and Using a Semaphore

The following code defines a semaphore using K_SEM_DEFINE, creates a thread that waits on the semaphore using k_sem_take, and signals the semaphore using k_sem_give.

#include <zephyr.h>
#include <stdio.h>

K_SEM_DEFINE(my_sem, 0, 1);
#define MY_STACK_SIZE 500
extern void my_entry_point(void *, void *, void *);

K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);
struct k_thread my_thread;

void main(void)
{
    k_tid_t my_tid = k_thread_create(
        &my_thread,
        My_stack_area,
        K_THREAD_STACK_SIZEOF(my_stack_area),
        My_entry_point,
        NULL,
        NULL,
        NULL,
        3,
        0,
        K_NO_WAIT);
    k_thread_start(my_tid);
    k_sem_give(&my_sem);
    k_sleep(K_FOREVER);
}

Using a Work Queue

In Zephyr, a work queue is a set of APIs used to submit work items for execution. The following code defines a work item using K_WORK_DEFINE, and a function my_work that prints “Hello, world!”. It submits the work item using k_work_submit. When the work item is executed, it calls my_work. This example shows how Zephyr can be used to run background tasks on a work queue.

#include <zephyr.h>
#include <stdio.h>

void my_work(struct k_work *work)
{
    printf("Hello, world!\n");
}

K_WORK_DEFINE(my_work_item, my_work);

void main(void)
{
    k_work_submit(&my_work_item);
    k_sleep(K_FOREVER);
}

Zephyr Security and Observability with Sternum

Zephyr comes in with a set of built-in security features, and Sternum enhances those by providing additional runtime protection and monitoring capabilities.

Runtime Protection

Our platform provides agentless runtime protection and prevents all memory and code manipulation attempts with no impact on device performance.

The solution is powered by our patented EIV™ (embedded integrity verification) technology. To learn more about it, check out these case studies of how it was used to:

Help a Fortune 500 company catch vulnerabilities in pre-production (Zephyr device)
Uncover vulnerabilities in 80,000 QNAP devices

Continuous Monitoring

Leveraging its on-device presence, our platform provides product, business, and engineering teams with a way to track every aspect of the device activity. This enables easy access to live insights, historical data, predictive analytics, tools for contextual root cause analysis, and more.

To learn more, check out this video below to see how it can be used to deploy traces and alerts to start shaping your data strategy:

Related content: Read our guide to Zephyr RTOS

 

JUMP TO SECTION

Enter data to download case study