FreeRTOS, RT-Thread, and Zephyr are often compared as if they were the same kind of RTOS. They are not.
The better question is not “which RTOS is better”, but what your project actually needs: a small scheduling kernel, an RTOS with strong domestic MCU support, or a complete cross-platform embedded operating system.
At a high level:
- FreeRTOS is a widely used scheduling kernel, plus a set of AWS-maintained IoT libraries.
- RT-Thread is a kernel plus a richer component ecosystem, with strong Chinese documentation and long-tail domestic MCU support.
- Zephyr is a Linux Foundation hosted RTOS that emphasizes unified subsystems, device models, Devicetree, and cross-vendor application reuse.
Bottom line
If your project only needs tasks, queues, semaphores, timers, and a very small footprint, FreeRTOS remains one of the safest choices.
If you mainly use Chinese MCU vendors and want ready BSPs, Chinese community support, ENV tooling, and a larger RTOS component set, RT-Thread has real advantages.
If you need to reuse application code across chips, boards, and vendors, and your team can accept the learning curve of Kconfig, Devicetree, west, and Zephyr’s driver model, Zephyr is the more future-facing engineering path.
This is not a simple “which one replaces which” question. They sit at different abstraction levels.
FreeRTOS: small, familiar, deterministic
FreeRTOS is strongest when you need something small and predictable.
The FreeRTOS-Kernel repository focuses on the kernel, ports, and core RTOS mechanisms: scheduling, semaphores, queues, event groups, software timers, and memory allocation. In many real projects, this is exactly what teams use.
Its advantages are straightforward:
- Huge MCU coverage.
- The most examples and learning material.
- Easy integration into vendor SDKs.
- Good fit for resource-constrained systems.
- Short debugging paths because many teams already know it.
After AWS acquired FreeRTOS, it also maintained libraries such as coreMQTT, coreHTTP, OTA, Device Shadow, Jobs, and Defender. The FreeRTOS 202406 LTS release brings kernel and IoT libraries into a long-term support line.
The boundary is equally clear: FreeRTOS is not a complete OS platform. It does not define a unified cross-vendor model for GPIO, UART, I2C, boards, pin control, or HAL abstraction. Those parts come from vendor SDKs or your own architecture.
That is a design choice, not a flaw. It makes FreeRTOS flexible and easy to embed, but when you change vendors or boards, application code often gets pulled into the hardware migration.
RT-Thread: stronger domestic MCU coverage and components
RT-Thread is closer to a complete RTOS than FreeRTOS.
Besides the scheduler, it provides file systems, networking, device framework, USB, sensor framework, packages, and tooling. For many Chinese embedded teams, its Chinese documentation, ENV workflow, community, and BSP coverage are practical advantages.
It is especially useful for long-tail domestic MCUs such as AT32, HC32, N32, APM32, HT32, Luat, HPMicro, and similar families. Many projects do not use only the biggest international vendors, and RT-Thread often gives these projects a faster starting point.
RT-Thread fits when:
- You use many domestic MCUs.
- Chinese docs and community matter.
- You need more components than a bare FreeRTOS setup.
- You want file system, networking, shell, and device framework quickly.
- You do not want to build all board and driver abstractions yourself.
Its limitation is that many BSPs still remain board-specific and vendor-library-oriented. From the perspective of cross-vendor hardware description and application reuse, it does not have the same systematic model as Zephyr.
RT-Thread is therefore best understood as a practical RTOS ecosystem above a kernel, especially strong in the Chinese MCU world, but not the same kind of full engineering platform as Zephyr.
Zephyr: an embedded system engineering platform
Zephyr is often described as a more complex RTOS. That is partly true, but the complexity is not random feature bloat.
Zephyr tries to bring into one OS project many things that are usually scattered across vendor SDKs, BSPs, HAL code, custom drivers, configuration scripts, and application code.
Its key pieces are:
- Kconfig for feature and build configuration.
- Devicetree for board-level hardware description.
- Unified drivers for GPIO, UART, SPI, I2C, ADC, DMA, clock, reset, pinctrl, and more.
- Subsystems for networking, Bluetooth, USB, file systems, input, power management, logging, and settings.
- west and CMake for project, module, build, flashing, and debugging workflows.
- Board / SoC / shield abstractions to keep hardware differences in configuration layers.
Zephyr feels like an MCU-sized cousin of embedded Linux: it borrows many Linux engineering ideas, but moves expensive runtime probing into build-time generation.
Why Devicetree matters
Devicetree is central to Zephyr.
In Linux, DTS is compiled into DTB, passed to the kernel, and parsed at runtime for driver matching and probing. That is reasonable for MPU-class systems, but too heavy for many MCUs.
Zephyr processes DTS and overlays during the build, generates headers such as devicetree_generated.h, and exposes hardware information through DT_ macros. Most hardware selection is settled at compile time, so runtime discovery stays light.
This gives Zephyr several benefits:
- Hardware description is separated from application code.
- Board changes mainly touch DTS / overlay files.
- Drivers expose unified APIs.
- Unused drivers and subsystems can be trimmed.
- Application code does not need to know every register, pin, or vendor HAL detail.
For example, an LED or button in a traditional FreeRTOS + vendor HAL project may involve CubeMX configuration, GPIO init, interrupts, debounce logic, callbacks, and application code. In Zephyr, much of that can live in DTS and standardized subsystems, while application code handles events.
Why application code becomes cleaner
Traditional MCU projects often mix hardware init, pin numbers, interrupts, debounce, timers, state machines, UART redirection, event queues, and business logic in the same layer.
That is fast at the beginning, but it becomes painful when there are more peripherals, boards, and product variants.
Zephyr tries to separate them:
- Hardware wiring goes into DTS / overlays.
- Feature switches go into Kconfig /
prj.conf. - Drivers live in Zephyr mainline or modules.
- Applications handle business events.
For multi-board and multi-chip projects, the ideal is to change DTS instead of changing main.c.
Resource cost needs context
Zephyr may use more Flash than a minimal FreeRTOS project because it brings drivers, subsystems, and device objects. But that is infrastructure, not just overhead.
Once you add buttons, encoders, input devices, logging, or multiple drivers, that infrastructure is reused. FreeRTOS projects often start smaller, but every new peripheral may add custom state machines and glue code.
RAM also depends on configuration. FreeRTOS reports may include reserved heap and stacks; Zephyr often relies more on static objects and link-time trimming. The only fair comparison is with the same feature set and realistic configuration.
How to choose
Choose FreeRTOS when the hardware is fixed, resources are tight, the team knows the kernel well, and you only need scheduling primitives.
Choose RT-Thread when you need stronger domestic MCU support, Chinese documentation, ready BSPs, and a richer component ecosystem without taking on the full Zephyr learning curve.
Choose Zephyr when you need cross-board reuse, long-term maintainability, unified drivers, standardized subsystems, and a path closer to Linux-style embedded engineering.
When not to use Zephyr
Zephyr is not a silver bullet.
Avoid jumping into Zephyr when:
- The project has one fixed board and simple features.
- The team has no time to learn Kconfig and Devicetree.
- The target chip or board has weak upstream support.
- The product depends heavily on a vendor’s closed SDK.
- The project is already stable in production.
- The team is not ready for Zephyr’s build and debugging workflow.
A safer path is to start with a well-supported board, run LED, UART, GPIO, input, and I2C / SPI examples, then decide whether to migrate real projects.
Why reading good code matters in the AI era
AI can generate candidate code, but engineers still merge it, flash it, and ship it to customer devices.
The scarce ability is not typing more code, but judgment: why this abstraction exists, whether a driver interface is maintainable, whether a generated patch is production-safe, and whether a configuration change affects other boards.
Zephyr is valuable even if you do not use it immediately. Reading its subsystems, Devicetree bindings, Kconfig layout, and driver organization gives you an industrial embedded architecture reference.
Summary
FreeRTOS, RT-Thread, and Zephyr are not three interchangeable products.
FreeRTOS solves scheduling. RT-Thread adds a richer component ecosystem and strong domestic MCU support. Zephyr tries to reorganize MCU software engineering around unified subsystems, Devicetree, and application portability.
For a small fixed device, FreeRTOS may be the best answer. For domestic MCU product lines, RT-Thread is practical. For multi-platform, multi-board, long-lived products, Zephyr deserves serious investment.
References: