What Is an RTOS (Real-Time Operating System)?
Last updated 26 June 2026 · 5 min read
Direct Answer
An RTOS (Real-Time Operating System) is a lightweight operating system designed for embedded systems that schedules multiple firmware tasks with deterministic, bounded timing — guaranteeing that a high-priority task runs within a defined deadline regardless of what other tasks are doing. Unlike general-purpose operating systems, an RTOS has a minimal footprint (often a few kB of flash) and no filesystem, graphics, or user-interface stack.
Detailed Explanation
The defining property of a real-time operating system is determinism — the guarantee that critical code runs within a bounded time after the event that triggered it. A desktop OS might delay a task by hundreds of milliseconds due to background processes; an RTOS ensures the highest-priority task preempts everything else and runs immediately.
How an RTOS schedules tasks
An RTOS kernel provides a scheduler that divides the CPU's time between software tasks. Each task is an independent function with its own stack, running in an infinite loop. The scheduler decides which task runs based on priority and state:
- Running — currently executing on the CPU.
- Ready — could run, waiting for the scheduler to give it CPU time.
- Blocked — waiting for an event (a timer expiry, a semaphore, data in a queue) and consuming no CPU cycles while waiting.
- Suspended — explicitly paused by the application.
In a preemptive RTOS (the common case), the scheduler can interrupt a lower-priority task at any time to run a higher-priority one that has just become ready — for example, when data arrives on a UART and unblocks a receiving task. This preemption is what delivers the timing guarantees.
Core RTOS primitives
| Primitive | Purpose |
|---|---|
| Task | Independent unit of execution with its own stack |
| Semaphore | Signal between tasks or ISRs (binary or counting) |
| Mutex | Mutual exclusion lock protecting a shared resource |
| Queue | Thread-safe FIFO for passing data between tasks |
| Timer | Software timer triggering a callback at a set interval |
| Event group | Bitfield that tasks can wait on or set |
These primitives replace the manual flag-polling and carefully ordered logic that bare-metal code requires to coordinate multiple activities. The RTOS kernel handles the synchronisation correctly, including blocking-with-timeout and priority inheritance for mutexes.
How much memory does an RTOS use?
FreeRTOS on a Cortex-M4 with a minimal configuration compiles to roughly 5–10 kB of flash and requires a small kernel heap. Each task adds its own stack — typically 256–2048 bytes depending on stack usage. A system with four tasks and their stacks might consume 4–8 kB of RAM total for the RTOS itself, before application data. On parts with 32 kB RAM or more, this is comfortable; on very small Cortex-M0 parts with 4–8 kB RAM, it may be too expensive, which is one reason bare-metal dominates on the smallest MCUs.
Soft real-time vs hard real-time
- Hard real-time: missing a deadline is a system failure. Example: automotive ABS control — if the wheel-speed interrupt response is late, braking is compromised.
- Soft real-time: missing a deadline degrades performance but is recoverable. Example: a wireless sensor reporting every 100 ms — a delayed transmission is acceptable as long as average timing is maintained.
Most embedded systems in IoT, industrial, and consumer electronics are soft real-time. True hard real-time systems often require safety-certified RTOS kernels with formal timing analysis.
Practical Examples
A BLE peripheral device typically runs several concurrent RTOS tasks:
- Radio task (highest priority): handles BLE protocol stack events with sub-millisecond response time.
- Sensor task: reads an IMU or temperature sensor over I2C at a fixed 100 Hz rate.
- Storage task: writes samples to SPI flash, blocking on each write, without impacting the sensor task's timing.
- Command task: processes commands arriving over BLE, updating configuration stored in flash.
Without an RTOS, managing these four activities in a single main loop — while ensuring the BLE stack always gets CPU time first — requires complex, brittle priority logic that an RTOS kernel handles cleanly.
Design Considerations
- Tick rate and interrupt latency: the RTOS tick timer generates interrupts (typically 1 kHz, i.e. 1 ms resolution) and adds a small overhead. Time-critical code that needs microsecond precision still belongs in an interrupt service routine, not an RTOS task.
- Stack sizing: each task needs its own stack. Too small and you get a stack overflow (often resulting in a hard fault or silent data corruption); too large and you waste RAM. Measure with a high-water-mark check during development.
- Priority inversion: if a low-priority task holds a mutex that a high-priority task needs, the high-priority task is effectively blocked by the low-priority one. Use mutexes with priority-inheritance support (FreeRTOS offers this) to avoid the classic priority-inversion deadlock.
- Bare-metal vs RTOS: choosing the right firmware architecture for your application depends on complexity, concurrency requirements, and team experience — the bare-metal vs RTOS comparison covers the decision in detail.
- Hardware watchdog integration: in RTOS firmware, a dedicated watchdog task should verify that all application tasks complete their work cycles before kicking the hardware watchdog — a task hang that would be invisible to a single kick point becomes detectable. See how watchdog timers work in RTOS firmware for the flag-based task-monitoring pattern.
- Production firmware with an RTOS benefits from careful validation of stack sizes, task priorities, and inter-task synchronisation patterns. Zeus Design's embedded software team develops production RTOS firmware across FreeRTOS, Zephyr, and bare-metal architectures for STM32, ESP32, and nRF platforms.
Common Mistakes
- Calling blocking functions from ISRs: interrupt service routines must be non-blocking. Calling RTOS queue-send or semaphore-give from an ISR requires using the ISR-safe variants (e.g.
xQueueSendFromISRin FreeRTOS), not the standard blocking call. - Making all tasks the same priority: if every task has equal priority, the scheduler round-robins between them. Time-critical tasks will be delayed by non-critical ones. Assign priorities to reflect real timing requirements.
- Forgetting to start the scheduler: RTOS task creation only registers tasks;
vTaskStartScheduler()(FreeRTOS) must be called to begin execution. Code after that call never runs in the main thread. - Adding an RTOS to avoid thinking: an RTOS does not simplify inherently messy firmware — if the application logic is poorly structured, an RTOS adds complexity without fixing the underlying problem. For a single-purpose task with no concurrency, bare-metal is simpler and easier to debug.
Frequently Asked Questions
- What is the difference between an RTOS and a general-purpose OS like Linux?
- A general-purpose OS (Linux, Windows) prioritises throughput and fairness across many processes, and can tolerate a task being delayed by tens of milliseconds. An RTOS prioritises timing predictability: a hard real-time system guarantees that a high-priority task runs within a fixed deadline — typically microseconds to low milliseconds — every single time. RTOSes also have much smaller memory footprints (kilobytes, not gigabytes) and run directly on microcontrollers without virtual memory or filesystem dependencies.
- Is FreeRTOS the only RTOS option?
- No. FreeRTOS is the most widely used open-source RTOS on ARM Cortex-M parts, but alternatives include Zephyr (Linux Foundation, strong Bluetooth/Ethernet support), ThreadX (Microsoft Azure RTOS, safety-certified versions), Mbed OS (ARM), and CMSIS-RTOS (a standard API that sits over FreeRTOS or other kernels). Commercial options like VxWorks and QNX are used in safety-critical and aerospace applications.
- Does every embedded system need an RTOS?
- No. Simple single-purpose firmware with one or two tasks and no strict concurrency requirements often runs cleanly as bare-metal code with a main loop and interrupt handlers. An RTOS adds real value when you have multiple independent tasks with different priorities and timing requirements that would be complex to manage manually.
References
Related Questions
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.
What Is a Microcontroller (MCU)?
A microcontroller (MCU) combines a CPU, flash, RAM, and peripherals on one chip. Learn how MCUs work and how they differ from microprocessors and FPGAs.
What Are Interrupts in Embedded Systems and How Do They Work?
Interrupts let a microcontroller respond to hardware events instantly without polling. Learn how ISRs, NVIC priority, and interrupt latency work.
How Do You Choose the Right Microcontroller for Your Project?
Choosing the right MCU comes down to peripherals, memory, power, wireless needs, and toolchain. This guide walks through every factor with concrete examples.
Related Forum Discussions
STM32 GPIO interrupt configured but ISR never fires — what am I missing?
Trying to use a button on PA0 to trigger an interrupt on an STM32F411 Nucleo board. Using HAL, generated the init code with CubeMX. The GPIO
Can't decide between FreeRTOS and bare-metal for a simple sensor node — what's the tipping point?
Working on a temperature and humidity monitoring node — STM32F103 target, BME280 over I2C, reports data every 60 seconds over UART to a Rasp