Update SMP get idle task memory for static allocation (#784)

* Add static idle task memory support for SMP
* Rename vApplicationMinimalIdleTask to vApplicationPassiveIdleTask
* Rename the macro configUSE_MINIMAL_IDLE_HOOK to configUSE_PASSIVE_IDLE_HOOK
* Update xTaskGetIdleTaskHandle for SMP
* Add more check in xTaskGetIdleTaskHandle
* Support configKERNEL_PROVIDED_STATIC_MEMORY for SMP

---------

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com>
This commit is contained in:
chinglee-iot 2023-10-12 10:41:16 +08:00 committed by GitHub
parent 92a4d175e6
commit 4bfb9b2d70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 241 additions and 198 deletions

View file

@ -175,8 +175,8 @@
#endif #endif
#if ( configNUMBER_OF_CORES > 1 ) #if ( configNUMBER_OF_CORES > 1 )
#ifndef configUSE_MINIMAL_IDLE_HOOK #ifndef configUSE_PASSIVE_IDLE_HOOK
#error Missing definition: configUSE_MINIMAL_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #error Missing definition: configUSE_PASSIVE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
#endif #endif
#endif #endif
@ -473,9 +473,9 @@
#define configUSE_CORE_AFFINITY 0 #define configUSE_CORE_AFFINITY 0
#endif /* configUSE_CORE_AFFINITY */ #endif /* configUSE_CORE_AFFINITY */
#ifndef configUSE_MINIMAL_IDLE_HOOK #ifndef configUSE_PASSIVE_IDLE_HOOK
#define configUSE_MINIMAL_IDLE_HOOK 0 #define configUSE_PASSIVE_IDLE_HOOK 0
#endif /* configUSE_MINIMAL_IDLE_HOOK */ #endif /* configUSE_PASSIVE_IDLE_HOOK */
/* The timers module relies on xTaskGetSchedulerState(). */ /* The timers module relies on xTaskGetSchedulerState(). */
#if configUSE_TIMERS == 1 #if configUSE_TIMERS == 1
@ -1834,8 +1834,14 @@
#define traceRETURN_uxTaskGetSystemState( uxTask ) #define traceRETURN_uxTaskGetSystemState( uxTask )
#endif #endif
#ifndef traceENTER_xTaskGetIdleTaskHandle #if ( configNUMBER_OF_CORES == 1 )
#define traceENTER_xTaskGetIdleTaskHandle() #ifndef traceENTER_xTaskGetIdleTaskHandle
#define traceENTER_xTaskGetIdleTaskHandle()
#endif
#else
#ifndef traceENTER_xTaskGetIdleTaskHandle
#define traceENTER_xTaskGetIdleTaskHandle( xCoreID )
#endif
#endif #endif
#ifndef traceRETURN_xTaskGetIdleTaskHandle #ifndef traceRETURN_xTaskGetIdleTaskHandle

View file

@ -1930,6 +1930,8 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
#if ( configNUMBER_OF_CORES == 1 )
/** /**
* task.h * task.h
* @code{c} * @code{c}
@ -1943,10 +1945,41 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
* @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task * @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task
* @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer * @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer
*/ */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer, StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ uint32_t * pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */
#endif #else /* #if ( configNUMBER_OF_CORES == 1 ) */
/**
* task.h
* @code{c}
* void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, StackType_t ** ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize, BaseType_t xCoreID )
* @endcode
*
* This function is used to provide a statically allocated block of memory to FreeRTOS to hold the Idle Tasks TCB. This function is required when
* configSUPPORT_STATIC_ALLOCATION is set. For more information see this URI: https://www.FreeRTOS.org/a00110.html#configSUPPORT_STATIC_ALLOCATION
*
* In the FreeRTOS SMP, there are a total of configNUMBER_OF_CORES idle tasks:
* 1. 1 Active idle task which does all the housekeeping.
* 2. ( configNUMBER_OF_CORES - 1 ) Passive idle tasks which do nothing.
* These idle tasks are created to ensure that each core has an idle task to run when
* no other task is available to run.
*
* The function vApplicationGetIdleTaskMemory is called with xCoreID 0 to get the
* memory for Active idle task. It is called with xCoreID 1, 2 ... ( configNUMBER_OF_CORES - 1 )
* to get memory for passive idle tasks.
*
* @param ppxIdleTaskTCBBuffer A handle to a statically allocated TCB buffer
* @param ppxIdleTaskStackBuffer A handle to a statically allocated Stack buffer for the idle task
* @param pulIdleTaskStackSize A pointer to the number of elements that will fit in the allocated stack buffer
* @param xCoreId The core index of the idle task buffer
*/
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize, /*lint !e526 Symbol not defined as it is an application callback. */
BaseType_t xCoreID );
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/** /**
* task.h * task.h
@ -1970,8 +2003,22 @@ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
* *
* Simply returns the handle of the idle task. It is not valid to call * Simply returns the handle of the idle task. It is not valid to call
* xTaskGetIdleTaskHandle() before the scheduler has been started. * xTaskGetIdleTaskHandle() before the scheduler has been started.
*
* In the FreeRTOS SMP, there are a total of configNUMBER_OF_CORES idle tasks:
* 1. 1 Active idle task which does all the housekeeping.
* 2. ( configNUMBER_OF_CORES - 1 ) Passive idle tasks which do nothing.
* These idle tasks are created to ensure that each core has an idle task to run when
* no other task is available to run.
*
* Set xCoreID to 0 to get the Active idle task handle. Set xCoreID to
* 1,2 ... ( configNUMBER_OF_CORES - 1 ) to get the Passive idle task
* handles.
*/ */
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; #if ( configNUMBER_OF_CORES == 1 )
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
TaskHandle_t xTaskGetIdleTaskHandle( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
/** /**
* configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for

362
tasks.c
View file

@ -515,15 +515,6 @@ PRIVILEGED_DATA static volatile configRUN_TIME_COUNTER_TYPE ulTotalRunTime[ conf
#endif #endif
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 )
/* Do not move these variables to function scope as doing so prevents the
* code working with debuggers that need to remove the static qualifier. */
static StaticTask_t xIdleTCBBuffers[ configNUMBER_OF_CORES - 1 ];
static StackType_t xIdleTaskStackBuffers[ configNUMBER_OF_CORES - 1 ][ configMINIMAL_STACK_SIZE ];
#endif /* #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configNUMBER_OF_CORES > 1 ) */
/*lint -restore */ /*lint -restore */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -583,7 +574,7 @@ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
* The idle task is automatically created and added to the ready lists upon * The idle task is automatically created and added to the ready lists upon
* creation of the first user task. * creation of the first user task.
* *
* In the FreeRTOS SMP, configNUMBER_OF_CORES - 1 minimal idle tasks are also * In the FreeRTOS SMP, configNUMBER_OF_CORES - 1 passive idle tasks are also
* created to ensure that each core has an idle task to run when no other * created to ensure that each core has an idle task to run when no other
* task is available to run. * task is available to run.
* *
@ -591,12 +582,12 @@ static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION;
* language extensions. The equivalent prototype for these functions are: * language extensions. The equivalent prototype for these functions are:
* *
* void prvIdleTask( void *pvParameters ); * void prvIdleTask( void *pvParameters );
* void prvMinimalIdleTask( void *pvParameters ); * void prvPassiveIdleTask( void *pvParameters );
* *
*/ */
static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION; static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION;
#if ( configNUMBER_OF_CORES > 1 ) #if ( configNUMBER_OF_CORES > 1 )
static portTASK_FUNCTION_PROTO( prvMinimalIdleTask, pvParameters ) PRIVILEGED_FUNCTION; static portTASK_FUNCTION_PROTO( prvPassiveIdleTask, pvParameters ) PRIVILEGED_FUNCTION;
#endif #endif
/* /*
@ -726,9 +717,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
#endif #endif
#if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) #if ( configUSE_PASSIVE_IDLE_HOOK == 1 )
extern void vApplicationMinimalIdleHook( void ); extern void vApplicationPassiveIdleHook( void );
#endif /* #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) */ #endif /* #if ( configUSE_PASSIVE_IDLE_HOOK == 1 ) */
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )
@ -1760,7 +1751,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
pxNewTCB->xTaskRunState = taskTASK_NOT_RUNNING; pxNewTCB->xTaskRunState = taskTASK_NOT_RUNNING;
/* Is this an idle task? */ /* Is this an idle task? */
if( ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvIdleTask ) || ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvMinimalIdleTask ) ) if( ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvIdleTask ) || ( ( TaskFunction_t ) pxTaskCode == ( TaskFunction_t ) prvPassiveIdleTask ) )
{ {
pxNewTCB->uxTaskAttributes |= taskATTRIBUTE_IS_IDLE; pxNewTCB->uxTaskAttributes |= taskATTRIBUTE_IS_IDLE;
} }
@ -3192,10 +3183,78 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
static BaseType_t prvCreateIdleTasks( void ) static BaseType_t prvCreateIdleTasks( void )
{ {
BaseType_t xReturn = pdPASS; BaseType_t xReturn = pdPASS;
BaseType_t xCoreID;
char cIdleName[ configMAX_TASK_NAME_LEN ];
TaskFunction_t pxIdleTaskFunction = NULL;
BaseType_t xIdleTaskNameIndex;
#if ( configNUMBER_OF_CORES == 1 ) for( xIdleTaskNameIndex = ( BaseType_t ) 0; xIdleTaskNameIndex < ( BaseType_t ) configMAX_TASK_NAME_LEN; xIdleTaskNameIndex++ )
{ {
/* Add the idle task at the lowest priority. */ cIdleName[ xIdleTaskNameIndex ] = configIDLE_TASK_NAME[ xIdleTaskNameIndex ];
/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
* configMAX_TASK_NAME_LEN characters just in case the memory after the
* string is not accessible (extremely unlikely). */
if( cIdleName[ xIdleTaskNameIndex ] == ( char ) 0x00 )
{
break;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/* Add each idle task at the lowest priority. */
for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ )
{
#if ( configNUMBER_OF_CORES == 1 )
{
pxIdleTaskFunction = prvIdleTask;
}
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
{
/* In the FreeRTOS SMP, configNUMBER_OF_CORES - 1 passive idle tasks
* are also created to ensure that each core has an idle task to
* run when no other task is available to run. */
if( xCoreID == 0 )
{
pxIdleTaskFunction = prvIdleTask;
}
else
{
pxIdleTaskFunction = prvPassiveIdleTask;
}
}
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
/* Update the idle task name with suffix to differentiate the idle tasks.
* This function is not required in single core FreeRTOS since there is
* only one idle task. */
#if ( configNUMBER_OF_CORES > 1 )
{
/* Append the idle task number to the end of the name if there is space. */
if( xIdleTaskNameIndex < ( BaseType_t ) configMAX_TASK_NAME_LEN )
{
cIdleName[ xIdleTaskNameIndex ] = ( char ) ( xCoreID + '0' );
/* And append a null character if there is space. */
if( ( xIdleTaskNameIndex + 1 ) < ( BaseType_t ) configMAX_TASK_NAME_LEN )
{
cIdleName[ xIdleTaskNameIndex + 1 ] = '\0';
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* if ( configNUMBER_OF_CORES > 1 ) */
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{ {
StaticTask_t * pxIdleTaskTCBBuffer = NULL; StaticTask_t * pxIdleTaskTCBBuffer = NULL;
@ -3204,16 +3263,20 @@ static BaseType_t prvCreateIdleTasks( void )
/* The Idle task is created using user provided RAM - obtain the /* The Idle task is created using user provided RAM - obtain the
* address of the RAM then create the idle task. */ * address of the RAM then create the idle task. */
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); #if ( configNUMBER_OF_CORES == 1 )
xIdleTaskHandles[ 0 ] = xTaskCreateStatic( prvIdleTask, vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
configIDLE_TASK_NAME, #else
ulIdleTaskStackSize, vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize, xCoreID );
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ #endif
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ xIdleTaskHandles[ xCoreID ] = xTaskCreateStatic( pxIdleTaskFunction,
pxIdleTaskStackBuffer, cIdleName,
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ ulIdleTaskStackSize,
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
pxIdleTaskStackBuffer,
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
if( xIdleTaskHandles[ 0 ] != NULL ) if( xIdleTaskHandles[ xCoreID ] != NULL )
{ {
xReturn = pdPASS; xReturn = pdPASS;
} }
@ -3225,137 +3288,25 @@ static BaseType_t prvCreateIdleTasks( void )
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{ {
/* The Idle task is being created using dynamically allocated RAM. */ /* The Idle task is being created using dynamically allocated RAM. */
xReturn = xTaskCreate( prvIdleTask, xReturn = xTaskCreate( pxIdleTaskFunction,
configIDLE_TASK_NAME, cIdleName,
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
( void * ) NULL, ( void * ) NULL,
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
&xIdleTaskHandles[ 0 ] ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ &xIdleTaskHandles[ xCoreID ] ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
} }
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
}
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
{
BaseType_t xCoreID;
char cIdleName[ configMAX_TASK_NAME_LEN ];
/* Add each idle task at the lowest priority. */ /* Break the loop if any of the idle task is failed to be created. */
for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) if( xReturn == pdFAIL )
{ {
BaseType_t x; break;
}
if( xReturn == pdFAIL ) else
{ {
break; mtCOVERAGE_TEST_MARKER();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ )
{
cIdleName[ x ] = configIDLE_TASK_NAME[ x ];
/* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than
* configMAX_TASK_NAME_LEN characters just in case the memory after the
* string is not accessible (extremely unlikely). */
if( cIdleName[ x ] == ( char ) 0x00 )
{
break;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/* Append the idle task number to the end of the name if there is space. */
if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN )
{
cIdleName[ x ] = ( char ) ( xCoreID + '0' );
x++;
/* And append a null character if there is space. */
if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN )
{
cIdleName[ x ] = '\0';
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
{
if( xCoreID == 0 )
{
StaticTask_t * pxIdleTaskTCBBuffer = NULL;
StackType_t * pxIdleTaskStackBuffer = NULL;
uint32_t ulIdleTaskStackSize;
/* The Idle task is created using user provided RAM - obtain the
* address of the RAM then create the idle task. */
vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize );
xIdleTaskHandles[ xCoreID ] = xTaskCreateStatic( prvIdleTask,
cIdleName,
ulIdleTaskStackSize,
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
pxIdleTaskStackBuffer,
pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
}
else
{
xIdleTaskHandles[ xCoreID ] = xTaskCreateStatic( prvMinimalIdleTask,
cIdleName,
configMINIMAL_STACK_SIZE,
( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
xIdleTaskStackBuffers[ xCoreID - 1 ],
&xIdleTCBBuffers[ xCoreID - 1 ] ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
}
if( xIdleTaskHandles[ xCoreID ] != NULL )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
}
#else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
{
if( xCoreID == 0 )
{
/* The Idle task is being created using dynamically allocated RAM. */
xReturn = xTaskCreate( prvIdleTask,
cIdleName,
configMINIMAL_STACK_SIZE,
( void * ) NULL,
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
&xIdleTaskHandles[ xCoreID ] ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
}
else
{
xReturn = xTaskCreate( prvMinimalIdleTask,
cIdleName,
configMINIMAL_STACK_SIZE,
( void * ) NULL,
portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */
&xIdleTaskHandles[ xCoreID ] ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
}
}
#endif /* configSUPPORT_STATIC_ALLOCATION */
} }
} }
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
return xReturn; return xReturn;
} }
@ -4192,20 +4143,40 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
/* SMP_TODO : This function returns only idle task handle for core 0. #if ( configNUMBER_OF_CORES == 1 )
* Consider to add another function to return the idle task handles. */
TaskHandle_t xTaskGetIdleTaskHandle( void )
{
traceENTER_xTaskGetIdleTaskHandle();
/* If xTaskGetIdleTaskHandle() is called before the scheduler has been TaskHandle_t xTaskGetIdleTaskHandle( void )
* started, then xIdleTaskHandles will be NULL. */ {
configASSERT( ( xIdleTaskHandles[ 0 ] != NULL ) ); traceENTER_xTaskGetIdleTaskHandle();
traceRETURN_xTaskGetIdleTaskHandle( xIdleTaskHandles[ 0 ] ); /* If xTaskGetIdleTaskHandle() is called before the scheduler has been
* started, then xIdleTaskHandles will be NULL. */
configASSERT( ( xIdleTaskHandles[ 0 ] != NULL ) );
return xIdleTaskHandles[ 0 ]; traceRETURN_xTaskGetIdleTaskHandle( xIdleTaskHandles[ 0 ] );
}
return xIdleTaskHandles[ 0 ];
}
#else /* if ( configNUMBER_OF_CORES == 1 ) */
TaskHandle_t xTaskGetIdleTaskHandle( BaseType_t xCoreID )
{
traceENTER_xTaskGetIdleTaskHandle( xCoreID );
/* Ensure the core ID is valid. */
configASSERT( taskVALID_CORE_ID( xCoreID ) == pdTRUE );
/* If xTaskGetIdleTaskHandle() is called before the scheduler has been
* started, then xIdleTaskHandles will be NULL. */
configASSERT( ( xIdleTaskHandles[ xCoreID ] != NULL ) );
traceRETURN_xTaskGetIdleTaskHandle( xIdleTaskHandles[ xCoreID ] );
return xIdleTaskHandles[ xCoreID ];
}
#endif /* if ( configNUMBER_OF_CORES == 1 ) */
#endif /* INCLUDE_xTaskGetIdleTaskHandle */ #endif /* INCLUDE_xTaskGetIdleTaskHandle */
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
@ -5348,21 +5319,21 @@ void vTaskMissedYield( void )
/* /*
* ----------------------------------------------------------- * -----------------------------------------------------------
* The MinimalIdle task. * The passive idle task.
* ---------------------------------------------------------- * ----------------------------------------------------------
* *
* The minimal idle task is used for all the additional cores in a SMP * The passive idle task is used for all the additional cores in a SMP
* system. There must be only 1 idle task and the rest are minimal idle * system. There must be only 1 active idle task and the rest are passive
* tasks. * idle tasks.
* *
* The portTASK_FUNCTION() macro is used to allow port/compiler specific * The portTASK_FUNCTION() macro is used to allow port/compiler specific
* language extensions. The equivalent prototype for this function is: * language extensions. The equivalent prototype for this function is:
* *
* void prvMinimalIdleTask( void *pvParameters ); * void prvPassiveIdleTask( void *pvParameters );
*/ */
#if ( configNUMBER_OF_CORES > 1 ) #if ( configNUMBER_OF_CORES > 1 )
static portTASK_FUNCTION( prvMinimalIdleTask, pvParameters ) static portTASK_FUNCTION( prvPassiveIdleTask, pvParameters )
{ {
( void ) pvParameters; ( void ) pvParameters;
@ -5403,7 +5374,7 @@ void vTaskMissedYield( void )
} }
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */
#if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) #if ( configUSE_PASSIVE_IDLE_HOOK == 1 )
{ {
/* Call the user defined function from within the idle task. This /* Call the user defined function from within the idle task. This
* allows the application designer to add background functionality * allows the application designer to add background functionality
@ -5411,18 +5382,18 @@ void vTaskMissedYield( void )
* *
* This hook is intended to manage core activity such as disabling cores that go idle. * This hook is intended to manage core activity such as disabling cores that go idle.
* *
* NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, * NOTE: vApplicationPassiveIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
* CALL A FUNCTION THAT MIGHT BLOCK. */ * CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationMinimalIdleHook(); vApplicationPassiveIdleHook();
} }
#endif /* configUSE_MINIMAL_IDLE_HOOK */ #endif /* configUSE_PASSIVE_IDLE_HOOK */
} }
} }
#endif /* #if ( configNUMBER_OF_CORES > 1 ) */ #endif /* #if ( configNUMBER_OF_CORES > 1 ) */
/* /*
* ----------------------------------------------------------- * -----------------------------------------------------------
* The Idle task. * The idle task.
* ---------------------------------------------------------- * ----------------------------------------------------------
* *
* The portTASK_FUNCTION() macro is used to allow port/compiler specific * The portTASK_FUNCTION() macro is used to allow port/compiler specific
@ -5549,7 +5520,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
} }
#endif /* configUSE_TICKLESS_IDLE */ #endif /* configUSE_TICKLESS_IDLE */
#if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_MINIMAL_IDLE_HOOK == 1 ) ) #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PASSIVE_IDLE_HOOK == 1 ) )
{ {
/* Call the user defined function from within the idle task. This /* Call the user defined function from within the idle task. This
* allows the application designer to add background functionality * allows the application designer to add background functionality
@ -5557,11 +5528,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
* *
* This hook is intended to manage core activity such as disabling cores that go idle. * This hook is intended to manage core activity such as disabling cores that go idle.
* *
* NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, * NOTE: vApplicationPassiveIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
* CALL A FUNCTION THAT MIGHT BLOCK. */ * CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationMinimalIdleHook(); vApplicationPassiveIdleHook();
} }
#endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_MINIMAL_IDLE_HOOK == 1 ) ) */ #endif /* #if ( ( configNUMBER_OF_CORES > 1 ) && ( configUSE_PASSIVE_IDLE_HOOK == 1 ) ) */
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -8127,17 +8098,36 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
* it's own implementation of vApplicationGetIdleTaskMemory by setting * it's own implementation of vApplicationGetIdleTaskMemory by setting
* configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined. * configKERNEL_PROVIDED_STATIC_MEMORY to 0 or leaving it undefined.
*/ */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, #if ( configNUMBER_OF_CORES == 1 )
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize )
{
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
*ppxIdleTaskTCBBuffer = &( xIdleTaskTCB ); void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
*ppxIdleTaskStackBuffer = &( uxIdleTaskStack[ 0 ] ); StackType_t ** ppxIdleTaskStackBuffer,
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; uint32_t * pulIdleTaskStackSize )
} {
static StaticTask_t xIdleTaskTCB;
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
*ppxIdleTaskTCBBuffer = &( xIdleTaskTCB );
*ppxIdleTaskStackBuffer = &( uxIdleTaskStack[ 0 ] );
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
uint32_t * pulIdleTaskStackSize,
BaseType_t xCoreId )
{
static StaticTask_t xIdleTaskTCBs[ configNUMBER_OF_CORES ];
static StackType_t uxIdleTaskStacks[ configNUMBER_OF_CORES ][ configMINIMAL_STACK_SIZE ];
*ppxIdleTaskTCBBuffer = &( xIdleTaskTCBs[ xCoreId ] );
*ppxIdleTaskStackBuffer = &( uxIdleTaskStacks[ xCoreId ][ 0 ] );
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
#endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */ #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configKERNEL_PROVIDED_STATIC_MEMORY == 1 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/