From Bare Metal to Zephyr: How RTOSes Power Embedded Systems
(Source: Cheewynn/stock.adobe.com; generated with AI)
Many developers started their embedded development journeys writing firmware that ran directly on the bare metal of a microcontroller. It was straightforward and efficient, at least memory-wise. For single-purpose built applications, say flashing an LED, this was fine. In fact, writing firmware was a considerable shift from building systems with just hardware (for example, incorporating a 555 timer). Developers could now change code and modify behaviors with relative ease, as opposed to rewiring a circuit.
Today, embedded systems are everywhere, from smartwatches and vehicles' electronic control units (ECUs) to smart fridges and medical devices. The increasing complexity of modern embedded applications has led to the widespread adoption of real-time operating systems (RTOSes). In this article, we will define RTOSes and explore some of the features of the popular RTOS Zephyr.
RTOS in a Nutshell
An RTOS is specialized software that manages hardware resources and allows multiple tasks to run concurrently in a predictable and timely manner. Unlike general-purpose operating systems like Windows or Linux, an RTOS prioritizes deterministic behavior, which means it guarantees that certain operations will be completed within a defined time frame. However, "time frame" in this sense does not mean "poll this sensor every Thursday at 3 p.m." Instead, it means something more akin to "poll this sensor every 500ms."
RTOSes are built to meet the specific needs of systems that require deterministic and predictable timing behavior. In most embedded real-time systems (e.g., medical devices, avionics, automotive ECUs), applications often need tasks to be executed within precise time windows. Thus, RTOSes are designed to ensure real-time guarantees (i.e., tasks that meet strict timing deadlines) and low latency (i.e., fast response to interrupts and events).
While it's possible to write firmware that can do this without using an RTOS, developers would be reinventing the wheel and building a subset of what a modern RTOS offers. The overhead of an RTOS will typically be outweighed by the utility it provides, except for the most resource-constrained of projects, such as those using 8-bit AVR or PIC microcontrollers.
Essentially, an RTOS is ideal in systems that require precise timing (e.g., motor control, audio processing) or that handle multiple tasks at once (e.g., a device that simultaneously uses Bluetooth® connectivity, a user interface, and sensor data). An RTOS makes sense for developers that want modular, reusable code that is easy to maintain as the project grows, and when efficient power management is critical to maximize battery life.
Bare-metal firmware is best for simple applications, such as blinking an LED or reading a sensor. It's also ideal for working with extremely limited memory or for complete control over low-level hardware timing.
Anatomy of an RTOS
RTOSes are designed to handle tasks with predictable timing and deterministic behavior, critical for embedded systems, robotics, automotive software, and industrial controls. While implementations can vary in complexity, most modern RTOSes are built around a standard set of foundational elements, including kernels, tasks and threads, schedulers, inter-process communication (IPC), memory management, and timers. Each plays a vital role in enabling concurrent execution, time-sensitive responsiveness, and system reliability.
Kernel
At the heart of any RTOS is the kernel, a lightweight and deterministic core designed to ensure that critical tasks execute with minimal and predictable delay. The kernel manages the system's essential low-level operations, including the following:
- Scheduling and dispatching tasks to determine when to run which task.
- Handling interrupts to respond immediately to external events.
- Performing context switching to swap between tasks efficiently.
- Providing synchronization and communication services so tasks can coordinate and share data safely.
Tasks/Threads
Tasks (also known as threads) are the basic units of execution in an RTOS. Each task represents an independent control flow with its own stack for managing local data, a defined priority level that determines when it runs, and a clear state—such as ready, running, blocked, or suspended—that changes as the RTOS manages execution. Tasks can be preemptive, allowing higher-priority tasks to interrupt lower ones, or cooperative, where tasks voluntarily yield control. In either case, the RTOS ensures that the highest-priority task that is ready always receives CPU time.
Scheduler
The scheduler acts as the brain of the RTOS, determining which task runs at any given moment. Schedulers are usually priority-based and can be preemptive, cooperative, or a hybrid of both approaches. Many RTOSes allow configuration for specific algorithms such as rate monotonic scheduling for periodic tasks, round-robin scheduling for time-sharing, or earliest-deadline-first for deadline-driven workloads. Regardless of the method, the scheduler's main goal is determinism—making sure that task execution occurs within known, guaranteed time bounds, which is vital for real-time performance.
Inter-Process Communication
To keep multiple tasks running smoothly and in sync, an RTOS provides IPC mechanisms that enable safe data sharing and coordination. These tools help prevent race conditions and deadlocks, ensuring tasks interact reliably. Common IPC features include semaphores for signaling and mutual exclusion (either binary or counting), mutexes that offer mutual exclusion and priority inheritance to prevent priority inversion, message queues that act as first-in–first-out (FIFO) buffers for sending structured data between tasks, and event flags that use lightweight bit masks for efficient synchronization.
Memory Management
An RTOS must handle memory in a way that balances flexibility with predictability. Some systems rely on static memory allocation fixed at compile time to maintain consistent behavior, while others also support dynamic allocation that uses a heap or memory pools when runtime flexibility is needed. Many RTOSes include safety features such as stack overflow detection to catch errors early, memory partitioning to keep different regions separate, thread-safe allocators to avoid conflicts, and hardware-backed memory protection if supported by a memory management unit (MMU). Some real-time systems avoid dynamic memory altogether to ensure timing remains predictable and fragmentation does not occur.
Timers
Precise timing is critical in real-time applications, and an RTOS typically provides both software timers and integration with hardware timers to make this possible. Timers allow tasks to execute at exact intervals or after specified durations. They are essential for delaying tasks, implementing timeouts to handle unexpected delays, and triggering periodic operations that must run on a strict schedule to maintain real-time performance.
Zerphyr Overview
One RTOS that has experienced rapid growth in recent years is Zephyr. In fact, Arduino has chosen the open-source, feature-rich, modular Zephyr for its next-generation hardware cores, following the sunset of Mbed.
Zephyr began in 2016 as a spin-off of the Virtuoso Nano microkernel. It was initially developed by Wind River Systems, the same company behind VxWorks, one of the most established commercial RTOSes. Zephyr's stated goal is to provide a vendor-neutral, open source, and security-first RTOS for Internet of Things (IoT) and embedded devices.
Zephyr's architecture is built around a preemptive, priority-based microkernel design. The modular kernel is configurable at compile time, which keeps the footprint minimal. This allows developers to use Zephyr for everything from tiny 8-bit MCUs to 64-bit embedded processors.
Zephyr uses the Kconfig system (from the Linux kernel) and the CMake build system, allowing developers to configure the entire OS for a specific use case or board. The kernel, drivers, stacks, and middleware are divided into components developers can enable and disable selecting only the necessary modules such as networking and power management.
As of this writing, Zephyr supports 800+ boards from manufacturers such as Nordic Semiconductor, NXP, STMicroelectronics, Texas Instruments, Intel®, Microchip Technology, and SiFive (RISC-V).[1]
Zephyr includes built-in support for essential connectivity options such as Bluetooth Low Energy, Ethernet, Thread, CAN, and Wi-Fi®, so embedded developers can spend less time writing drivers and more time building their applications. The RTOS provides security through lightweight, integrated cryptography libraries like TinyCrypt and mbedTLS. For safety-critical automotive and industrial systems, Zephyr's certifications such as ISO 26262 and IEC 61508 can help designers meet strict regulatory standards. Zephyr also provides drivers for LCDs, OLEDs, touch panels, and e-ink screens, and works seamlessly with Light and Versatile Graphics Library (LVGL) for designing graphical user interfaces (GUIs).
The Zephyr development ecosystem is also solid and well-rounded. At its core is West, a versatile command-line tool that collects CMake, Git, and flashing or debugging commands in a single interface. The Zephyr SDK comes bundled with prebuilt toolchains, QEMU for virtualized testing, and other development tools that help developers get up and running quickly. Zephyr integrates well with popular environments like Visual Studio Code, SEGGER Embedded Studio, and traditional command-line workflows, giving developers flexibility in how they work. For debugging, developers have a range of options at their disposal, including GDB, OpenOCD, J-Link, and pyOCD.
Conclusion
RTOSes are powerful tools that help embedded developers meet the demanding requirements of modern applications, where precision, reliability, and scalability are non-negotiable. Zephyr, with its modular architecture, rich ecosystem, and strong industry support, represents a compelling choice for projects ranging from home automation IoT devices to safety-critical automotive systems. As embedded systems continue to evolve in complexity, leveraging an RTOS like Zephyr allows developers to focus on innovation rather than reinventing the wheel. Whether building the next generation of wearable devices or industrial controllers, Zephyr provides the flexibility and confidence to bring designs to life.
Sources