EmbeddedRelated.com

FreeRTOS

Category: Rtos

FreeRTOS is an open-source, real-time operating system kernel widely used in embedded systems, providing preemptive multitasking (with cooperative scheduling available as a configuration option), inter-task communication primitives (queues, semaphores, mutexes, event groups), software timers, and memory management schemes across a broad range of MCU architectures.

In practice

FreeRTOS is typically integrated directly into a firmware project as source files (tasks.c, queue.c, timers.c, and a port-specific port.c plus portmacro.h). There is no separate OS binary to link against; the kernel compiles alongside application code. Configuration is done through a single header, FreeRTOSConfig.h, where parameters such as configCPU_CLOCK_HZ, configTICK_RATE_HZ, configMAX_PRIORITIES, and configTOTAL_HEAP_SIZE are set for the target hardware.

The scheduler runs tasks based on priority. With preemption enabled (configUSE_PREEMPTION = 1), the highest-priority ready task always runs; equal-priority tasks can share CPU time through round-robin if configUSE_TIME_SLICING is enabled. Tasks block on queues, semaphores, or event groups rather than spinning, which allows the idle task to execute low-power hooks on MCUs that support sleep modes. The blog post "From bare-metal to RTOS: 5 Reasons to use an RTOS" covers common motivations for making this transition from a superloop design.

A frequent source of bugs is misuse of the dual API sets: functions ending in FromISR() (e.g., xQueueSendFromISR()) must be called from interrupt context, while the non-ISR variants must not be. On ARM Cortex-M3/M4/M7 targets, FreeRTOS uses the PendSV and SysTick exceptions for context switching and tick generation (this is port-specific behavior, not a general FreeRTOS property); the interrupt priority of any ISR that calls a FreeRTOS API must be numerically greater than or equal to configMAX_SYSCALL_INTERRUPT_PRIORITY (i.e., lower urgency), or the call is unsafe and may corrupt kernel state.

Memory management is handled by one of several heap_N.c schemes (heap_1 through heap_5). heap_1 never frees memory; heap_4 is the most commonly used general-purpose allocator with first-fit merging; heap_5 allows the heap to span non-contiguous memory regions, which is useful on parts with both SRAM and external PSRAM. Stack overflows are a persistent issue: FreeRTOS provides optional stack overflow checking (configCHECK_FOR_STACK_OVERFLOW modes 1 and 2) and the high-water mark API (uxTaskGetStackHighWaterMark()) to tune per-task stack sizes. The book "Review: Hands-On RTOS with Microcontrollers" offers practical guidance on sizing and debugging these issues.

Discussed on EmbeddedRelated

Frequently asked

Does FreeRTOS guarantee hard real-time behavior?
FreeRTOS provides deterministic scheduling in the sense that the highest-priority ready task is always chosen, and critical sections have bounded latency. Whether the resulting system meets hard real-time deadlines depends on interrupt latency of the target hardware, ISR execution time, and application design. The blog post 'Can an RTOS be really real-time?' discusses the distinction between the scheduler's guarantees and true hard real-time behavior. FreeRTOS does not perform schedulability analysis; that remains the developer's responsibility.
When should I choose FreeRTOS over a bare-metal superloop or round-robin scheduler?
FreeRTOS becomes useful when the application has multiple concurrent activities with different priorities or timing requirements that are difficult to manage in a single loop, or when blocking on I/O (UART, SPI, network) would otherwise require complex state machines. For simple, single-concern firmware, the overhead of the RTOS (stack RAM per task, scheduler tick interrupt, added complexity) may not be justified. The blog posts 'Round-robin or RTOS for my embedded system' and 'You Don't Need an RTOS (Part 3)' are worth reading before committing to an RTOS.
What is the RAM cost of running FreeRTOS?
The kernel itself compiles to roughly 5-10 KB of flash on a Cortex-M3 with a typical configuration, though this figure is highly dependent on compiler, optimization level, and which features are enabled. RAM cost scales primarily with the number of tasks: each task requires its own stack (user-defined, often 128-512 words minimum) plus a task control block (TCB) of around 100-200 bytes depending on configuration options. On parts with 2-8 KB of SRAM, like many 8/16-bit MCUs, this overhead is often prohibitive. On Cortex-M0+ parts with 16-32 KB SRAM and above, it is generally manageable.
What is the difference between FreeRTOS and AWS FreeRTOS (now FreeRTOS IoT Libraries)?
The FreeRTOS kernel is the core scheduler and IPC library. AWS FreeRTOS (subsequently rebranded under the FreeRTOS umbrella as a set of IoT-focused libraries) is a collection of add-on libraries layered on top of the kernel, including MQTT, TLS, OTA update, and device shadow clients targeting AWS IoT Core. The kernel can be used entirely independently of any AWS services or libraries.
How do I safely call FreeRTOS APIs from an interrupt service routine?
FreeRTOS provides FromISR variants of most blocking APIs (xQueueSendFromISR(), xSemaphoreGiveFromISR(), xTaskNotifyFromISR(), etc.). These must be used in any ISR context. After calling them, you must check the pxHigherPriorityTaskWoken output parameter and, if it is set to pdTRUE, call portYIELD_FROM_ISR() (or portEND_SWITCHING_ISR() on some ports) to trigger an immediate context switch. On Cortex-M targets, the ISR's NVIC priority must be set numerically at or above configMAX_SYSCALL_INTERRUPT_PRIORITY; failing this causes hard faults or silent kernel corruption.

Differentiators vs similar concepts

FreeRTOS is often compared to other embedded RTOS options. Zephyr RTOS (backed by the Linux Foundation) is a larger, more opinionated kernel with a device driver model, Kconfig-based build system, and broader built-in peripheral support, making it closer to an embedded Linux alternative; FreeRTOS is leaner and easier to drop into an existing project with minimal build system changes. ThreadX (Azure RTOS) has a similar footprint to FreeRTOS and offers formal certification artifacts (IEC 61508, DO-178C) as a commercial product, whereas FreeRTOS's SafeRTOS variant provides certification support at additional cost. Bare-metal superloops and cooperative round-robin schedulers have no preemption and require no stack-per-task overhead; FreeRTOS's preemptive model adds RAM cost and concurrency hazards in exchange for priority-based responsiveness.