This document is used to track all changes made the to FreeRTOS V10.5.1 source code when adding dual core SMP support or IDF additional features.
Todo: Add these to ESP-IDF docs once v10.5.1 becomes default kernel (IDF-8203)
SPDX-FileCopyrightText and SPDX-FileContributor tags to all files to pass ESP-IDF pre-commit checks.FreeRTOS Kernel V10.5.1 (ESP-IDF SMP modified) in all files to indicate files are different from upstream V10.5.1.croutine.c and croutine.hList of changes to the Vanilla FreeRTOS V10.5.1 kernel in order to support dual-core SMP
xTaskIncrementTick()xTaskIncrementTickOtherCores()vTaskSwitchContext() to pick the highest priority task it can currently run
taskSELECT_HIGHEST_PRIORITY_TASK() unchangedprvSelectHighestPriorityTaskSMP() is called. This will select the highest priority ready state task that...vTaskSuspendAll())Following configurations have been added
configNUMBER_OF_CORES to specify the number of cores to build. Can be 1 for vanilla, or 2 for SMP, error otherwiseconfigUSE_PORT_OPTIMISED_TASK_SELECTION for SMPtasks.c)The following data fields have been expanded to have configNUMBER_OF_CORES copies:
pxCurrentTCBs: Each core now has its own currently running taskxPendingReadyList: Each core has its own list to pend ready tasks if the scheduler is suspended on the corexYieldPending: Each core has its own flag to track whether it has a pending yieldxIdleTaskHandle: Each core now has its own idle taskuxSchedulerSuspended: Each core can independently suspend scheduling on its coreulTaskSwitchedInTime: Each core tracks its own "task switched in" timeTheir access is now indexed by a xCoreID if in SMP, or set to 0 in single core.
The following data structures have been added:
TCB_t.xCoreID: All tasks now store their core affinity in a TCB member. Always set to 0 in single-coreThe following APIs have been added to support SMP
xTaskCreatePinnedToCore() and xTaskCreateStaticPinnedToCore() to create tasks with a core affinity
xTaskCreate()xTaskGetCoreID() to get a task's affinityForCore() versions of the following API
xTaskGetIdleTaskHandleForCore()xTaskGetCurrentTaskHandleForCore()ulTaskGetIdleRunTimeCounterForCore()Added the following macros that abstract away single-core and SMP differences:
taskYIELD_CORE() triggers a particular core to yieldtaskIS_YIELD_REQUIRED()/taskIS_YIELD_REQUIRED_USING_PRIORITY() check if current core requires a yield after a task is unblockedtaskIS_AFFINITY_COMPATIBLE() check if a task has compatible affinitytaskIS_CURRENTLY_RUNNING()/taskIS_CURRENTLY_RUNNING_ON_CORE() checks if a task is running on either coretaskCAN_BE_SCHEDULED() checks if an unblocked task can be scheduled on any coretaskIS_SCHEDULER_SUSPENDED() checks if the scheduler on the current core is suspendedtaskSELECT_HIGHEST_PRIORITY_TASK() selects the highest priority task to execute for the current coreprvGetTCBFromHandle() updated in SMP to call xTaskGetCurrentTaskHandle() when the handle is NULL. Done so for thread safety (in case the current task switches cores at the same time).The following functions were modified to accommodate SMP behavior:
prvInitialiseNewTask()
xCoreID argument to pin task on creationxCoreID is hard coded to 0prvAddNewTaskToReadyList()
vTaskDelete()
vTaskPrioritySet()
vTaskSuspend()
prvTaskIsTaskSuspended()
xPendingReadyList of both cores to see if a task is suspendedxTaskResumeAll()
xTaskIncrementTick())xTaskIncrementTick()
vTaskSwitchContext()
xTaskRemoveFromEventList()
pxEventList has already been emptied by the other core before removingvTaskRemoveFromUnorderedEventList()
eTaskConfirmSleepModeStatus()
prvCheckTasksWaitingTermination()
xTasksWaitingTermination which are still currently running on the other core.xTaskGetCurrentTaskHandle()
xTaskGetSchedulerState()
uxSchedulerSuspended.prvAddCurrentTaskToDelayedList()
tasks.c): xKernelLockxQueueLockxQueueRegistryLockxEventGroupLockxStreamBufferLockxTimerLock..._SMP_ONLY() critical section calls)queueUSE_LOCKS)
List of differences between Vanilla FreeRTOS V10.5.1 and building the dual-core SMP kernel with congigNUMBER_OF_CORES == 1.
prvAddNewTaskToReadyList()
vTaskStepTick()
xTickCount while still inside critical sectionList of changes made to Vanilla FreeRTOS V10.5.1 header files to allow for building in ESP-IDF documentation build system.
Removed leading header name line (e.g., xxx.h) in doxygen comment blocks. For example:
/**
* xxx.h
*
* Documentation from some func
*/
void some_func(void);
Removed leading @code{c} blocks in containing redundant function prototypes. For example:
/**
* @code{c}
* void some_func(int var_a, int var_b);
* @endcode
*
* Documentation from some func
*/
void some_func(int var_a, int var_b);
Added /** @cond !DOC_EXCLUDE_HEADER_SECTION */ and /** @endcond */ labels to exclude various doxygen sections from being included into documentation builds. These excluded sections include:
In doxygen blocks that describe multiple related set of functions/macros, only the function/macro that matches the doxygen blocks parameters is included. For example:
/**
* Description that covers both some_func() and some_func_extra()
*
* @param var_a var_a description
* @param var_b var_b description
*/
/** @cond !DOC_EXCLUDE_HEADER_SECTION */
#define some_func(var_a) #define some_func_generic(var_a, NULL)
/** @endcond */
#define some_func_extra(var_a, var_b) #define some_func_generic(var_a, var_b)
In functions/macros that are not meant to be directly called by users (i.e., internal), such as the various Generic variants of functions
Some types/functions/macros are manually documented, thus are documented with regular comment blocks (i.e., /* */) instead of doxygen comment blocks (i.e., /** */). Some of these blocks are changed into doxygen blocks.