Scheduling Strategies for Single-Core and Multi-Core FreeRTOS

FreeRTOS has dominated the RTOS market due to its early open-source and free commercial use (under the MIT open-source license).

With the popularity of multi-core MCUs, FreeRTOS has also kept up with the trend and supports multi-core scheduling. Today, I will share the scheduling strategies for single-core and multi-core FreeRTOS.

Single-Core Scheduling Strategy

Single-core scheduling is a feature that all RTOS must have, and it is the most basic requirement.
FreeRTOS’s single-core scheduling strategy is similar to many RTOS on the market, which means: it defaults to a fixed-priority preemptive scheduling strategy, performing time-sliced round-robin scheduling for tasks of equal priority.
  • Fixed Priority: This means the scheduler does not permanently change the priority of tasks, but may temporarily increase the priority of a task due to priority inheritance.

  • Preemptive: This means the scheduler always runs the highest-priority runnable RTOS task, regardless of when the task can run. For example, if an interrupt service routine (ISR) changes the highest-priority runnable task, the scheduler will stop the currently running low-priority task and start the high-priority task—even if this happens within the same time slice. In this case, it can be said that the high-priority task “preempts” the low-priority task.

  • Round-Robin Scheduling: This means tasks with the same priority take turns entering the running state.

  • Time Slicing: This means the scheduler switches between tasks of equal priority at each tick interrupt, with the time between tick interrupts forming a time slice. (Tick interrupts are periodic interrupts used by RTOS to measure time.)

  • Here, you can refer to my previous article:About the RTOS Tick Configuration Issues

Configuring Scheduling Strategy

FreeRTOSConfig.h is the configuration file for the entire system, and there are two configurations related to scheduling here.

1. configUSE_PREEMPTION

The default configuration is 1
#define configUSE_PREEMPTION      1

If configUSE_PREEMPTION is set to 0, it means preemption is disabled, and context switching will only occur when a running task enters a “blocked” or “suspended” state, or when a running task calls taskYIELD(), or when an ISR manually requests a context switch.

2. configUSE_TIME_SLICING

This configuration was not available in earlier versions and is a new feature. Similarly, the default configuration is 1

#define configUSE_TIME_SLICING                     1

If configUSE_TIME_SLICING is set to 0, it means time slicing is disabled, and the scheduler will not switch between tasks of equal priority at each tick interrupt.

Multi-Core Scheduling Strategy

Multi-core scheduling for MCUs can be divided into: Symmetric Multi-Processing (SMP) and Asymmetric Multi-Processing (AMP).
1. Symmetric Multi-Processing (SMP)
Using FreeRTOS for Symmetric Multi-Processing (SMP) means that a single FreeRTOS instance can schedule RTOS tasks across multiple processor cores.
Since only one FreeRTOS instance is running, only one “port” of FreeRTOS can be used at a time, so each core must have the same processor architecture and share the same memory space.
For (SMP) symmetric multi-processing, there are also relevant configurations in FreeRTOSConfig.h configuration file.
a. configRUN_MULTIPLE_PRIORITIES
If configRUN_MULTIPLE_PRIORITIES is set to 0, the scheduler will only run multiple tasks simultaneously when multiple tasks have the same priority. This can fix code written under the assumption that only one task will run at a time, but it sacrifices some of the benefits brought by SMP configuration.
b. configUSE_CORE_AFFINITY
If configUSE_CORE_AFFINITY is set to 1, the vTaskCoreAffinitySet() API function can be used to define which cores a task can run on and which cores it cannot run on. Using this method, application writers can prevent two tasks that assume their execution order from running simultaneously.
2. Asymmetric Multi-Processing (AMP)
Using FreeRTOS for Asymmetric Multi-Processing (AMP) means that each core of a multi-core device runs its own FreeRTOS instance independently. These cores do not need to have the same architecture, but if communication is required between FreeRTOS instances, some memory must be shared.
Each core runs its own FreeRTOS instance, so the scheduling algorithm on any given core is exactly the same as the single-core system scheduling algorithm mentioned above. You can use stream buffers or message buffers as inter-core communication primitives, allowing a task on one core to enter a “blocked” state while waiting for data or events from another core.
The previously shared article “Principles of Communication Between Dual-Core Microcontrollers M4 and M7” discusses some principles of the specific implementation of Asymmetric Multi-Processing (AMP).
The basic principle of implementing communication between dual cores: Sending and receiving tasks are located on different cores of a multi-core microcontroller (MCU) in an Asymmetric Multi-Processing (AMP) configuration, which means each core runs its own FreeRTOS program.
At the same time, one core has the ability to generate interrupts in another core, and both cores have access to a memory area (shared memory). Message buffers are placed in shared memory at known addresses in the application running on each core, as shown in the figure below:
Scheduling Strategies for Single-Core and Multi-Core FreeRTOS
Ideally, there will also be a Memory Protection Unit (MPU) to ensure that the message buffer can only be accessed through the kernel’s message buffer API, and it is best to mark the shared memory as unavailable for other programs.
Scheduling Strategies for Single-Core and Multi-Core FreeRTOS

END

Author: strongerHuang
Source: Embedded Column
Copyright belongs to the original author, if there is any infringement, please contact to delete.
Recommended Reading
How difficult is it to cultivate an excellent embedded engineer?
He Tongxue’s plagiarism incident original author has accepted an apology: does not want to ruin him
C/C++ deadline is approaching, the United States insists on removing it completely before 2026!
→ Follow to avoid getting lost ←

Leave a Comment