feat(freertos/idf): Add config option for FreeRTOS Timer Task core affinity

This commit adds the ability to set the core affinity for the FreeRTOS
Timer Service task when multi-core configuration is enabled. This commit
also adds a Kconfig option to set the core affinity of the timer task
via the menuconfig.

Closes https://github.com/espressif/esp-idf/issues/10315
This commit is contained in:
Sudeep Mohanty 2023-10-24 11:59:40 +02:00
parent dd5b091a8b
commit f01dbe0314
5 changed files with 114 additions and 35 deletions

View File

@ -199,3 +199,8 @@ List of changes made to Vanilla FreeRTOS V10.5.1 header files to allow for build
### tasks.c
- Backported a change where the IDLE tasks are created with the core ID as a suffix in the task name.
### timers.c
- Backported configTIMER_SERVICE_TASK_CORE_AFFINITY config option to enable configurability of the Timer Service task's core affinity.
- The change also entails updating the task creation APIs to use IDF-FreeRTOS task creation APIs, adding a assert check for valid affinity values and dropping the use of configUSE_CORE_AFFINITY.

View File

@ -66,12 +66,25 @@
#define tmrNO_DELAY ( ( TickType_t ) 0U )
#define tmrMAX_TIME_BEFORE_OVERFLOW ( ( TickType_t ) -1 )
/* The name assigned to the timer service task. This can be overridden by
* defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
/* The name assigned to the timer service task. This can be overridden by
* defining configTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */
#ifndef configTIMER_SERVICE_TASK_NAME
#define configTIMER_SERVICE_TASK_NAME "Tmr Svc"
#endif
#if ( configNUMBER_OF_CORES > 1 )
/* The core affinity assigned to the timer service task on SMP systems.
* This can be overridden by defining configTIMER_SERVICE_TASK_CORE_AFFINITY in FreeRTOSConfig.h. */
#ifndef configTIMER_SERVICE_TASK_CORE_AFFINITY
#define configTIMER_SERVICE_TASK_CORE_AFFINITY tskNO_AFFINITY
#endif
#if ( !( ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x0 ) || ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x1 ) || ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x7FFFFFFF /* tskNO_AFFINITY */ ) ) )
#error Invalid Timer task affinity. Timer task core ID can only be 0x0, 0x1 or 0x7FFFFFFF (tskNO_AFFINITY).
#endif /* #if ( !( ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x0 ) || ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x01 ) || ( configTIMER_SERVICE_TASK_CORE_AFFINITY == 0x7FFFFFFF ) ) ) */
#endif /* #if ( configNUMBER_OF_CORES > 1 ) */
/* Bit definitions used in the ucStatus member of a timer structure. */
#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 )
#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 )
@ -252,40 +265,78 @@
if( xTimerQueue != NULL )
{
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
/* The following code block to set the timer task core affinity has been picked up from the FreeRTOS-Kernel
* upstream repository. Commit# 631ae9e6e4828cf5c7d58bb7ac78a64fc309bcb7.
* Necessary changes have been made for IDF-FreeRTOS compatibility. */
#if ( configNUMBER_OF_CORES > 1 )
{
StaticTask_t * pxTimerTaskTCBBuffer = NULL;
StackType_t * pxTimerTaskStackBuffer = NULL;
uint32_t ulTimerTaskStackSize;
/* Timer tasks is always pinned to core 0. Todo: IDF-7906 */
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStaticPinnedToCore( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
ulTimerTaskStackSize,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
pxTimerTaskStackBuffer,
pxTimerTaskTCBBuffer,
0 );
if( xTimerTaskHandle != NULL )
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{
xReturn = pdPASS;
StaticTask_t * pxTimerTaskTCBBuffer = NULL;
StackType_t * pxTimerTaskStackBuffer = NULL;
uint32_t ulTimerTaskStackSize;
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStaticPinnedToCore( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
ulTimerTaskStackSize,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
pxTimerTaskStackBuffer,
pxTimerTaskTCBBuffer,
configTIMER_SERVICE_TASK_CORE_AFFINITY );
if( xTimerTaskHandle != NULL )
{
xReturn = pdPASS;
}
}
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{
xReturn = xTaskCreatePinnedToCore( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
configTIMER_TASK_STACK_DEPTH,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
&xTimerTaskHandle,
configTIMER_SERVICE_TASK_CORE_AFFINITY );
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
}
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
#else /* #if ( configNUMBER_OF_CORES > 1 ) */
{
/* Timer tasks is always pinned to core 0. Todo: IDF-7906 */
xReturn = xTaskCreatePinnedToCore( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
configTIMER_TASK_STACK_DEPTH,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
&xTimerTaskHandle,
0 );
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{
StaticTask_t * pxTimerTaskTCBBuffer = NULL;
StackType_t * pxTimerTaskStackBuffer = NULL;
uint32_t ulTimerTaskStackSize;
vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );
xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
ulTimerTaskStackSize,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
pxTimerTaskStackBuffer,
pxTimerTaskTCBBuffer );
if( xTimerTaskHandle != NULL )
{
xReturn = pdPASS;
}
}
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{
xReturn = xTaskCreate( prvTimerTask,
configTIMER_SERVICE_TASK_NAME,
configTIMER_TASK_STACK_DEPTH,
NULL,
( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,
&xTimerTaskHandle );
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
#endif /* #if ( configNUMBER_OF_CORES > 1 ) */
}
else
{

View File

@ -166,6 +166,27 @@ menu "FreeRTOS"
help
Sets the timer task's name (see configTIMER_SERVICE_TASK_NAME documentation for more details).
choice FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY
prompt "configTIMER_SERVICE_TASK_CORE_AFFINITY"
default FREERTOS_TIMER_TASK_NO_AFFINITY
help
Sets the timer task's core affinity (see configTIMER_SERVICE_TASK_CORE_AFFINITY documentation for more details).
config FREERTOS_TIMER_TASK_AFFINITY_CPU0
bool "CPU0"
config FREERTOS_TIMER_TASK_AFFINITY_CPU1
bool "CPU1"
depends on !FREERTOS_UNICORE
config FREERTOS_TIMER_TASK_NO_AFFINITY
bool "No affinity"
endchoice
config FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY
hex
default 0x0 if FREERTOS_TIMER_TASK_AFFINITY_CPU0
default 0x1 if FREERTOS_TIMER_TASK_AFFINITY_CPU1
default FREERTOS_NO_AFFINITY if FREERTOS_TIMER_TASK_NO_AFFINITY
config FREERTOS_TIMER_TASK_PRIORITY
int "configTIMER_TASK_PRIORITY"
range 1 25

View File

@ -180,11 +180,12 @@
/* ------------------- Software Timer ---------------------- */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY
#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH
#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH
#define configTIMER_SERVICE_TASK_NAME CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY
#define configTIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH
#define configTIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH
#define configTIMER_SERVICE_TASK_NAME CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME
#define configTIMER_SERVICE_TASK_CORE_AFFINITY CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY
/* ------------------------ List --------------------------- */

View File

@ -18,3 +18,4 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_FREERTOS_FPU_IN_ISR=y
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES=y
CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU1=y