What Is Zephyr RTOS, and How Is It Different from FreeRTOS?
Last updated 3 July 2026 · 7 min read
Direct Answer
Zephyr is an open-source, Linux Foundation-hosted RTOS that provides not just a preemptive multitasking kernel (like FreeRTOS) but a complete embedded OS: a hardware description system (device tree), a build-time configuration system (Kconfig, the same language used by the Linux kernel), a driver model with subsystem APIs (GPIO, I2C, SPI, sensors) that firmware can call generically across different silicon, and built-in networking, Bluetooth, and USB stacks. Where FreeRTOS is a small scheduler that leaves hardware abstraction, drivers, and connectivity stacks to vendor SDKs, Zephyr bundles all of it in one framework — which is why silicon vendors with heavy connectivity requirements (Nordic's nRF Connect SDK, Espressif's Zephyr support, and NXP, among others) standardise application development on it rather than on a bare vendor HAL plus FreeRTOS.
Detailed Explanation
FreeRTOS and Zephyr are often compared as if they're interchangeable choices for "which RTOS should I use," but they solve different-sized problems. FreeRTOS is a preemptive multitasking kernel — tasks, queues, semaphores, mutexes — and nothing else; hardware drivers, board configuration, and any networking or wireless stack are entirely up to the vendor SDK layered on top of it. Zephyr is a full embedded operating system: the kernel is one part of a framework that also standardises how hardware is described, how build-time software features are selected, how drivers expose themselves to application code, and how common subsystems (Bluetooth, IP networking, USB, filesystems) are implemented once and reused across every supported chip.
That extra scope is why Zephyr has two concepts with no FreeRTOS equivalent at all — device tree and Kconfig — and why understanding them is the actual learning curve, not the kernel API itself.
Device Tree: Describing Hardware Outside of Source Code
In a typical FreeRTOS + vendor-HAL project, which pins a peripheral uses, which I2C bus a sensor sits on, and what its interrupt line is are usually hardcoded in #defines or initialisation function calls scattered through application source. Zephyr moves all of that into device tree — a hardware description, written in a dedicated syntax (inherited from the Linux kernel's device tree), that lives in .dts/.dtsi/.overlay files separate from application C code.
/* Example: a device tree overlay adding a sensor on I2C1 */
&i2c1 {
status = "okay";
bme280: bme280@76 {
compatible = "bosch,bme280";
reg = <0x76>;
status = "okay";
};
};
Application code then retrieves a handle to that hardware via a device tree macro, not a hardcoded address:
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
const struct device *bme280 = DEVICE_DT_GET(DT_NODELABEL(bme280));
if (!device_is_ready(bme280)) {
/* Device tree resolved a node, but the driver failed to initialise */
return -ENODEV;
}
The payoff: retargeting the same application to different hardware (a new board revision that moves the sensor to I2C0, or an entirely different chip) is a device tree overlay change, not a source code change — provided a driver for that peripheral class already exists in Zephyr.
Kconfig: Build-Time Feature Configuration
Zephyr uses Kconfig — the same configuration language the Linux kernel uses — to select which subsystems, drivers, and kernel features are compiled into a given build. Options are set in prj.conf files (or via the menuconfig/guiconfig interactive tools) rather than editing a header file like FreeRTOS's FreeRTOSConfig.h:
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_SENSOR=y
CONFIG_PM=y
CONFIG_LOG=y
Kconfig options have dependencies on each other — enabling CONFIG_BT_PERIPHERAL implicitly requires CONFIG_BT, and Zephyr's Kconfig system enforces these dependencies at configure time rather than failing at compile time with an obscure linker error, which is a meaningfully better failure mode than a missing FreeRTOS feature macro silently compiling with default (and possibly wrong) behaviour.
The Kernel: Threads and Synchronisation
Underneath device tree and Kconfig, Zephyr's kernel is conceptually close to FreeRTOS — preemptive, priority-based scheduling of threads with their own stacks:
#include <zephyr/kernel.h>
#define STACKSIZE 1024
#define PRIORITY 5
void sensor_thread(void *p1, void *p2, void *p3)
{
while (1) {
/* read sensor, process, etc. */
k_sleep(K_MSEC(100));
}
}
K_THREAD_DEFINE(sensor_tid, STACKSIZE, sensor_thread, NULL, NULL, NULL,
PRIORITY, 0, 0);
The synchronisation primitives map closely to FreeRTOS's, with Zephyr generally offering a superset — see the FAQ below for the full correspondence. One important difference worth calling out on its own: priority numbering is inverted relative to FreeRTOS. In FreeRTOS, higher numbers mean higher priority (the idle task is priority 0). In Zephyr, lower numbers mean higher priority, and priorities can be negative: negative priorities are cooperative threads (never preempted except by an even-higher-priority cooperative thread), while zero and positive priorities are preemptible threads, with a lower magnitude still meaning higher priority within that band. An engineer moving from FreeRTOS who assumes "bigger number = more important" in Zephyr will assign priorities backwards.
Built-In Subsystems
Where FreeRTOS requires sourcing a separate BLE stack, IP stack, or USB stack from the silicon vendor (or a third party) and integrating it, Zephyr ships these as first-class subsystems using the same kernel, device tree, and Kconfig conventions as everything else:
- Bluetooth — Zephyr's own BLE host and controller stack, used directly by Nordic's nRF Connect SDK for GATT peripheral/central roles. See How Do You Implement a BLE Peripheral with Custom GATT Services on nRF52 Using Zephyr?.
- Networking — a full IP stack (IPv4/IPv6), 6LoWPAN, and OpenThread integration, which is why Zephyr underpins most of this site's Thread and Matter implementation coverage — see How Do You Implement a Matter Device on the nRF Connect SDK?.
- Power management — the
CONFIG_PM/CONFIG_PM_DEVICEsubsystem drives automatic CPU and device low-power state selection from the kernel idle thread; see the Zephyr power management usage in nRF52 Power Optimisation. - USB, filesystems, settings storage — a USB device stack, LittleFS/FAT filesystem support, and a non-volatile settings API for persisting configuration across reboots, all built on the same device driver model.
Design Considerations
- Choose Zephyr when the platform's SDK already standardises on it. Nordic's nRF Connect SDK, and increasingly Espressif's and NXP's connectivity-focused offerings, are built on Zephyr — for these platforms, Zephyr isn't really an alternative to a vendor HAL, it is the vendor SDK. See How Do You Set Up the nRF Connect SDK and Zephyr RTOS for nRF52 Development? for the practical project setup workflow.
- Choose FreeRTOS for simpler products or an existing bare-metal codebase. A single-purpose device with modest connectivity needs, or a product already built on a vendor HAL plus FreeRTOS, usually isn't well served by a full Zephyr migration — the device tree and Kconfig learning investment pays off most clearly on connectivity-heavy, multi-board, or multi-vendor-silicon products.
- Device tree overlays are the mechanism for board-specific hardware changes, not source code edits — plan custom hardware bring-up around writing an overlay for the new board, not modifying driver source.
- Budget real onboarding time for device tree and Kconfig, separate from RTOS kernel concepts — teams new to Zephyr consistently underestimate this as "just another RTOS to learn" and are surprised by the additional build-system layer.
Common Mistakes
- Assuming FreeRTOS priority conventions apply. As covered above, Zephyr's priority numbering is inverted (lower number = higher priority, with negative numbers for cooperative threads) relative to FreeRTOS. Porting a priority scheme numerically without re-deriving it against Zephyr's convention silently inverts task importance.
- Editing driver source to change hardware configuration instead of writing a device tree overlay. This defeats the entire portability benefit device tree provides and creates a fork that has to be manually re-applied on every Zephyr SDK update.
- Enabling a Kconfig option without checking its dependencies and cost. Some subsystems (full networking, for instance) pull in a meaningfully larger flash and RAM footprint than a minimal build; check
west build -t ram_report/rom_reportafter enabling major subsystems on flash- or RAM-constrained parts, rather than discovering the overrun at link time. - Treating
westas optional tooling. Zephyr's multi-repository structure (kernel, HAL modules, and — for nRF Connect SDK — Nordic's own repositories) is managed bywest; attempting to clone and build the tree manually withoutwest init/west updateproduces a workspace with inconsistent module versions. - Expecting third-party FreeRTOS libraries to work unmodified. A library written against FreeRTOS's API (
xTaskCreate,xQueueSend, etc.) does not run on Zephyr without porting to the equivalentk_thread/k_msgqcalls — the two kernels are API-incompatible despite solving the same class of problem.
Frequently Asked Questions
- Is Zephyr harder to learn than FreeRTOS?
- For a first "blink an LED and create two tasks" project, Zephyr has a steeper initial learning curve because of device tree and Kconfig — two additional systems FreeRTOS simply doesn't have, since FreeRTOS leaves hardware configuration entirely to the vendor HAL. Once a developer understands device tree (describing hardware) and Kconfig (configuring software features), Zephyr's kernel API is comparably straightforward to FreeRTOS's, and the payoff is that the same application code and drivers port across supported silicon far more readily than FreeRTOS-plus-vendor-HAL code does.
- Can I use Zephyr without Nordic's nRF Connect SDK?
- Yes. Zephyr is a general-purpose, vendor-independent RTOS project with mainline support for hundreds of boards across many silicon vendors — Nordic, STMicroelectronics, Espressif, NXP, Raspberry Pi (RP2040/RP2350), and others. The nRF Connect SDK is Nordic's own distribution of Zephyr with Nordic-specific drivers, samples, and connectivity stacks layered on top, but plain upstream Zephyr (`zephyrproject-rtos/zephyr` with the `west` tool) builds and runs on non-Nordic hardware independently of any vendor SDK.
- Does Zephyr support the same inter-task primitives as FreeRTOS?
- Zephyr's kernel provides equivalents for every FreeRTOS primitive, generally with a superset of options: `k_sem` (semaphore, equivalent to FreeRTOS's binary/counting semaphore), `k_mutex` (mutex with priority inheritance, equivalent to FreeRTOS's priority-inheritance mutex), `k_msgq` (message queue, equivalent to FreeRTOS's queue), `k_poll` (waiting on multiple conditions, similar in purpose to FreeRTOS event groups), and `k_work`/workqueues (deferred work items processed by a dedicated thread, a pattern FreeRTOS doesn't provide natively). The naming and exact semantics differ enough that porting FreeRTOS application code to Zephyr requires re-implementing the synchronisation logic against the Zephyr API, not just renaming function calls.
References
Related Questions
What Is an RTOS (Real-Time Operating System)?
An RTOS is a lightweight operating system that gives embedded firmware deterministic task scheduling. Learn how RTOSes work and when you actually need one.
Bare-Metal vs RTOS: Which Should You Use for Your Firmware?
Bare-metal firmware and RTOS suit different embedded projects. Learn the trade-offs — timing, RAM overhead, complexity — and how to choose.
How Do You Create and Schedule Tasks in FreeRTOS?
Learn how to create FreeRTOS tasks with xTaskCreate, configure task priorities, size stacks safely, and start the scheduler on ARM Cortex-M MCUs.
How Do FreeRTOS Queues, Semaphores, and Mutexes Work?
How to use FreeRTOS queues, semaphores, and mutexes for inter-task communication — including ISR-safe variants, task notifications, and event groups.
How Do You Set Up the nRF Connect SDK and Zephyr RTOS for nRF52 Development?
Set up nRF Connect SDK (NCS) for nRF52 development: install tools, create a west workspace, configure Kconfig, build a Zephyr project, and flash with J-Link.
How Do You Implement a Matter Device on the nRF Connect SDK?
How to implement a Matter device on Nordic's nRF Connect SDK: dual-core nRF5340 architecture, Zephyr Matter samples, chip-tool, and certification.