Motivation for using FreeRTOS
FreeRTOS, originally developed by Richard Barry and now maintained by Amazon, is the most widely used open-source real-time operating system (RTOS) for microcontrollers. With ports available for over 40 microprocessor architectures, FreeRTOS offers broad hardware compatibility.
It is completely free to download, modify, and deploy—without any royalties—making it a powerful tool for accelerating the development of complex embedded systems. The availability of a fully functional RTOS at no cost significantly shortens time-to-market for production-grade applications.
At its core, FreeRTOS is a lightweight scheduler that provides essential capabilities such as task management, inter-task communication, and memory handling. Impressively, it can operate with as little as 12 KB of RAM, a key factor behind its status as the de facto standard for resource-constrained embedded platforms.
The Scheduler
The FreeRTOS scheduler is responsible for selecting which task transitions into the Running state based on system status and task readiness. It evaluates all registered tasks, identifying those eligible to execute and those that must remain in the Blocked state until required resources become available.
Task priority is a central feature of FreeRTOS. The scheduler uses priority levels to ensure that time-critical tasks can preempt lower-priority tasks, supporting deterministic, real-time behavior. When multiple tasks are ready to run, the scheduler chooses the one with the highest priority.
If multiple tasks all have the same priority and are all ready to run, the FreeRTOS scheduler uses Round-robin scheduling (when configured to do so). Each task receives a fixed quantum of time, called a tick, to execute, after which it is rotated to the end of a circular queue. The next task in line is then dispatched. This method promotes fairness and prevents starvation within a given priority level.
The diagram below illustrates how Round-robin scheduling would work with 4 tasks all at the same priority level. After each Tick, the currently running task is moved to the end of the queue, and the next task in the queue becomes the active task.
When deciding which task to run, the scheduler examines not only the priority of a task, but also the state of each task before deciding which task will run next. FreeRTOS supports tasks being in one of the following states:
Running: The task that is currently executing. Only one task can be in the running state.
Ready: Tasks waiting to run and are not blocked waiting for a resource to become free. A task must be moved into the Ready state before it can be allowed to run.
Blocked: A task that is waiting for a resource (semaphore, timer, event). A task cannot be moved into the Ready state until the resource is available.
Suspended: The task is inactive and cannot be moved to the ready state without explicitly calling vTaskResume().
The diagram below summarizes the relationship between these states.
[1] Mastering the FreeRTOS Real-Time Kernel Pg67.
FreeRTOS also supports preempting tasks. Preemption allows the scheduler to interrupt a currently running task and switch to a higher-priority task as soon as it’s ready to run. With preemption active, the scheduler allows for increased responsiveness by granting CPU time to tasks based on their priority rather than waiting for the running task to yield voluntarily.
FreeRTOS Tick
In FreeRTOS, a tick is the basic unit of time that drives the scheduler. It represents a regularly occurring interrupt—typically every 1 millisecond—that allows the system to make time-based decisions. The tick interval is commonly set to 1 millisecond, but you can adjust this value in the FreeRTOSConfig.h file to suit your application’s timing requirements.
On Cortex-M microcontrollers, the RTOS tick is driven by the SysTick timer—a standard, vendor-independent peripheral built into the ARM architecture. SysTick is a 24-bit down counter designed specifically for generating periodic interrupts, making it ideal for driving the time base in real-time operating systems like FreeRTOS.
Cortex-M Resources Utilized by FreeRTOS
The FreeRTOS scheduler uses two resources provided by the Cortex-M architecture in order to function correctly: the SysTick Timer and the PendSV interrupt.
SysTick Timer
- The SysTick Timer generates periodic interrupts used to geneate ticks.
- Because FreeRTOS is designed for hard real-time behavior, maintaining accurate timekeeping is critical, even during periods of high system activity. To ensure correct timing, the SysTick timer is assigned the highest interrupt priority in the system (hardware priority of 0). This allows it to preempt both task execution and other interrupt service routines, ensuring the scheduler receives consistent timing updates.
PendSV Interrupt
PendSV (Pending Supervisor Call) is a software-triggered interrupt built into ARM Cortex-M processors designed to support efficient context switching without interfering with time-critical operations. FreeRTOS uses the PendSV handler to initiate a switch between tasks, selecting which one should transition into the Running state.
Unlike hardware interrupts, PendSV doesn’t fire on its own—it must be triggered by FreeRTOS when a context switch is necessary. This occurs under conditions such as:
- A higher-priority task becomes ready
- A task voluntarily yields control
- A SysTick interrupt causes a preemption
To preserve timing accuracy across the system, FreeRTOS assigns PendSV the lowest possible interrupt priority. This allows PendSV to interrupt tasks but not other interrupt service routines (ISRs) that are considered more time-sensitive, such as those driven by external hardware events or the SysTick timer.
This careful prioritization ensures that context switching is deferred until all critical ISR activity has completed, maintaining system responsiveness and deterministic real-time behavior.
SysTick + PendSV Summary
Together, the SysTick timer and PendSV interrupt form the foundation of the FreeRTOS scheduler. The SysTick timer, configured with the highest interrupt priority, maintains precise system timing by generating periodic tick interrupts. The SysTick handler updates the system tick count and evaluates whether a context switch is necessary. If a switch is required, the SysTick handler triggers the PendSV interrupt, deferring the actual context switch to a low-priority routine. PendSV handler performs task switching without interfering with higher-priority, time-critical interrupt service routines.