forked from espressif/esp-idf
refactor(freertos/idf): Move task creation "PinnedToCore" API to addition headers
This commit moves/merges the IDF FreeRTOS "PinnedToCore" task creation functions from tasks.c/task.h to idf_additions.h/freertos_task_c_additions.h. Also updated FreeRTOS Mock component to provide mocks for "idf_additions.h" headers for our mock tests.
This commit is contained in:
@@ -285,204 +285,6 @@ typedef enum
|
||||
* TASK CREATION API
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Create a new task with a specified affinity and add it to the list of tasks
|
||||
* that are ready to run.
|
||||
*
|
||||
* This function is similar to xTaskCreate, but allows setting task affinity
|
||||
* in SMP system.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop), or should be
|
||||
* terminated using vTaskDelete function.
|
||||
*
|
||||
* @param pcName A descriptive name for the task. This is mainly used to
|
||||
* facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default
|
||||
* is 16.
|
||||
*
|
||||
* @param usStackDepth The size of the task stack specified as the number of
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
*
|
||||
* @param uxPriority The priority at which the task should run. Systems that
|
||||
* include MPU support can optionally create tasks in a privileged (system)
|
||||
* mode by setting bit portPRIVILEGE_BIT of the priority parameter. For
|
||||
* example, to create a privileged task at priority 2 the uxPriority parameter
|
||||
* should be set to ( 2 | portPRIVILEGE_BIT ).
|
||||
*
|
||||
* @param[out] pvCreatedTask Used to pass back a handle by which the created task
|
||||
* can be referenced.
|
||||
*
|
||||
* @param xCoreID If the value is tskNO_AFFINITY, the created task is not
|
||||
* pinned to any CPU, and the scheduler can run it on any core available.
|
||||
* Values 0 or 1 indicate the index number of the CPU which the task should
|
||||
* be pinned to. Specifying values larger than (configNUM_CORES - 1) will
|
||||
* cause the function to fail.
|
||||
*
|
||||
* @return pdPASS if the task was successfully created and added to a ready
|
||||
* list, otherwise an error code defined in the file projdefs.h
|
||||
*
|
||||
* @note If program uses thread local variables (ones specified with "__thread" keyword)
|
||||
* then storage for them will be allocated on the task's stack.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
* // Task to be created.
|
||||
* void vTaskCode( void * pvParameters )
|
||||
* {
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Task code goes here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Function that creates a task.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* static uint8_t ucParameterToPass;
|
||||
* TaskHandle_t xHandle = NULL;
|
||||
*
|
||||
* // Create the task pinned to core 0, storing the handle. Note that the passed parameter ucParameterToPass
|
||||
* // must exist for the lifetime of the task, so in this case is declared static. If it was just an
|
||||
* // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
|
||||
* // the new task attempts to access it.
|
||||
* xTaskCreatePinnedToCore( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle, 0 );
|
||||
* configASSERT( xHandle );
|
||||
*
|
||||
* // Use the handle to delete the task.
|
||||
* if( xHandle != NULL )
|
||||
* {
|
||||
* vTaskDelete( xHandle );
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @cond !DOC_SINGLE_GROUP
|
||||
* \defgroup xTaskCreatePinnedToCore xTaskCreatePinnedToCore
|
||||
* @endcond
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a new task with a specified affinity and add it to the list of tasks
|
||||
* that are ready to run.
|
||||
*
|
||||
* This function is similar to xTaskCreateStatic, but allows specifying
|
||||
* task affinity in an SMP system.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function. Tasks
|
||||
* must be implemented to never return (i.e. continuous loop), or should be
|
||||
* terminated using vTaskDelete function.
|
||||
*
|
||||
* @param pcName A descriptive name for the task. This is mainly used to
|
||||
* facilitate debugging. The maximum length of the string is defined by
|
||||
* configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param ulStackDepth The size of the task stack specified as the number of
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
*
|
||||
* @param uxPriority The priority at which the task will run.
|
||||
*
|
||||
* @param pxStackBuffer Must point to a StackType_t array that has at least
|
||||
* ulStackDepth indexes - the array will then be used as the task's stack,
|
||||
* removing the need for the stack to be allocated dynamically.
|
||||
*
|
||||
* @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will
|
||||
* then be used to hold the task's data structures, removing the need for the
|
||||
* memory to be allocated dynamically.
|
||||
*
|
||||
* @param xCoreID If the value is tskNO_AFFINITY, the created task is not
|
||||
* pinned to any CPU, and the scheduler can run it on any core available.
|
||||
* Values 0 or 1 indicate the index number of the CPU which the task should
|
||||
* be pinned to. Specifying values larger than (configNUM_CORES - 1) will
|
||||
* cause the function to fail.
|
||||
*
|
||||
* @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will
|
||||
* be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer
|
||||
* are NULL then the task will not be created and
|
||||
* errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.
|
||||
*
|
||||
* Example usage:
|
||||
* @code{c}
|
||||
*
|
||||
* // Dimensions the buffer that the task being created will use as its stack.
|
||||
* // NOTE: This is the number of words the stack will hold, not the number of
|
||||
* // bytes. For example, if each stack item is 32-bits, and this is set to 100,
|
||||
* // then 400 bytes (100 * 32-bits) will be allocated.
|
||||
* #define STACK_SIZE 200
|
||||
*
|
||||
* // Structure that will hold the TCB of the task being created.
|
||||
* StaticTask_t xTaskBuffer;
|
||||
*
|
||||
* // Buffer that the task being created will use as its stack. Note this is
|
||||
* // an array of StackType_t variables. The size of StackType_t is dependent on
|
||||
* // the RTOS port.
|
||||
* StackType_t xStack[ STACK_SIZE ];
|
||||
*
|
||||
* // Function that implements the task being created.
|
||||
* void vTaskCode( void * pvParameters )
|
||||
* {
|
||||
* // The parameter value is expected to be 1 as 1 is passed in the
|
||||
* // pvParameters value in the call to xTaskCreateStaticPinnedToCore().
|
||||
* configASSERT( ( uint32_t ) pvParameters == 1UL );
|
||||
*
|
||||
* for( ;; )
|
||||
* {
|
||||
* // Task code goes here.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Function that creates a task.
|
||||
* void vOtherFunction( void )
|
||||
* {
|
||||
* TaskHandle_t xHandle = NULL;
|
||||
*
|
||||
* // Create the task pinned to core 0 without using any dynamic memory allocation.
|
||||
* xHandle = xTaskCreateStaticPinnedToCore(
|
||||
* vTaskCode, // Function that implements the task.
|
||||
* "NAME", // Text name for the task.
|
||||
* STACK_SIZE, // Stack size in bytes, not words.
|
||||
* ( void * ) 1, // Parameter passed into the task.
|
||||
* tskIDLE_PRIORITY,// Priority at which the task is created.
|
||||
* xStack, // Array to use as the task's stack.
|
||||
* &xTaskBuffer, // Variable to hold the task's data structure.
|
||||
* 0 ); // Specify the task's core affinity
|
||||
*
|
||||
* // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
|
||||
* // been created, and xHandle will be the task's handle. Use the handle
|
||||
* // to suspend the task.
|
||||
* vTaskSuspend( xHandle );
|
||||
* }
|
||||
* @endcode
|
||||
* @cond !DOC_SINGLE_GROUP
|
||||
* \defgroup xTaskCreateStaticPinnedToCore xTaskCreateStaticPinnedToCore
|
||||
* @endcond
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const pxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
* @cond !DOC_EXCLUDE_HEADER_SECTION
|
||||
* task. h
|
||||
@@ -526,8 +328,8 @@ typedef enum
|
||||
* facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default
|
||||
* is 16.
|
||||
*
|
||||
* @param usStackDepth The size of the task stack specified as the number of
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
* @param usStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
@@ -584,6 +386,7 @@ typedef enum
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
@@ -592,8 +395,31 @@ typedef enum
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
return xTaskCreatePinnedToCore( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, tskNO_AFFINITY );
|
||||
/*
|
||||
* The idf_additions.h has not been included here yet due to inclusion
|
||||
* order. Thus we manually declare the function here.
|
||||
*/
|
||||
extern BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pvCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
/*
|
||||
* Call the "PinnedToCore" version with tskNO_AFFINITY to create
|
||||
* an unpinned task.
|
||||
*/
|
||||
return xTaskCreatePinnedToCore( pxTaskCode,
|
||||
pcName,
|
||||
usStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
pxCreatedTask,
|
||||
tskNO_AFFINITY );
|
||||
}
|
||||
|
||||
#endif /* if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
|
||||
/**
|
||||
@@ -630,8 +456,8 @@ typedef enum
|
||||
* facilitate debugging. The maximum length of the string is defined by
|
||||
* configMAX_TASK_NAME_LEN in FreeRTOSConfig.h.
|
||||
*
|
||||
* @param ulStackDepth The size of the task stack specified as the number of
|
||||
* bytes. Note that this differs from vanilla FreeRTOS.
|
||||
* @param ulStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
*
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
@@ -706,8 +532,8 @@ typedef enum
|
||||
* @endcode
|
||||
* \ingroup Tasks
|
||||
*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
static inline __attribute__( ( always_inline ) )
|
||||
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
@@ -717,8 +543,32 @@ typedef enum
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION
|
||||
{
|
||||
return xTaskCreateStaticPinnedToCore( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, tskNO_AFFINITY );
|
||||
/*
|
||||
* The idf_additions.h has not been included here yet due to inclusion
|
||||
* order. Thus we manually declare the function here.
|
||||
*/
|
||||
extern TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const pxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
/*
|
||||
* Call the "PinnedToCore" version with tskNO_AFFINITY to create
|
||||
* an unpinned task.
|
||||
*/
|
||||
return xTaskCreateStaticPinnedToCore( pxTaskCode,
|
||||
pcName,
|
||||
ulStackDepth,
|
||||
pvParameters,
|
||||
uxPriority,
|
||||
puxStackBuffer,
|
||||
pxTaskBuffer,
|
||||
tskNO_AFFINITY );
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/**
|
||||
|
@@ -708,64 +708,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
StackType_t * const puxStackBuffer,
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
configASSERT( portVALID_STACK_MEM( puxStackBuffer ) );
|
||||
configASSERT( portVALID_TCB_MEM( pxTaskBuffer ) );
|
||||
configASSERT( ( ( xCoreID >= 0 ) && ( xCoreID < configNUM_CORES ) ) || ( xCoreID == tskNO_AFFINITY ) );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
* variable of type StaticTask_t equals the size of the real task
|
||||
* structure. */
|
||||
volatile size_t xSize = sizeof( StaticTask_t );
|
||||
configASSERT( xSize == sizeof( TCB_t ) );
|
||||
( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
|
||||
{
|
||||
/* The memory used for the task's TCB and stack are passed into this
|
||||
* function - use them. */
|
||||
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
|
||||
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created statically in case the task is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* SUPPORT_STATIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
|
||||
BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
|
||||
@@ -865,100 +807,6 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const configSTACK_DEPTH_TYPE usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* If the stack grows down then allocate the stack then the TCB so the stack
|
||||
* does not grow into the TCB. Likewise if the stack grows up then allocate
|
||||
* the TCB then the stack. */
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
{
|
||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||
* the implementation of the port malloc function and whether or not static
|
||||
* allocation is being used. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Allocate space for the stack used by the task being created.
|
||||
* The base of the stack memory stored in the TCB so the task can
|
||||
* be deleted later if required. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
|
||||
if( pxNewTCB->pxStack == NULL )
|
||||
{
|
||||
/* Could not allocate the stack. Delete the allocated TCB. */
|
||||
vPortFree( pxNewTCB );
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
StackType_t * pxStack;
|
||||
|
||||
/* Allocate space for the stack used by the task being created. */
|
||||
pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */
|
||||
|
||||
if( pxStack != NULL )
|
||||
{
|
||||
/* Allocate space for the TCB. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Store the stack location in the TCB. */
|
||||
pxNewTCB->pxStack = pxStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The stack cannot be used as the TCB was not created. Free
|
||||
* it again. */
|
||||
vPortFree( pxStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* portSTACK_GROWTH */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created dynamically in case it is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
const uint32_t ulStackDepth,
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_assert.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
#if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT
|
||||
#include "freertos/task_snapshot.h"
|
||||
@@ -163,7 +164,7 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
|
||||
/* -------------------------------------------------- Task Creation ------------------------------------------------- */
|
||||
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
@@ -173,13 +174,21 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
BaseType_t ret;
|
||||
BaseType_t xReturn;
|
||||
|
||||
#if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) )
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
/* If using Amazon SMP FreeRTOS. This function is just a wrapper around
|
||||
* xTaskCreate() or xTaskCreateAffinitySet(). */
|
||||
#if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
|
||||
/* Bit shifting << xCoreID is only valid if we have less than
|
||||
* 32 cores. */
|
||||
ESP_STATIC_ASSERT( configNUM_CORES < 32 );
|
||||
|
||||
if( xCoreID == tskNO_AFFINITY )
|
||||
{
|
||||
uxCoreAffinityMask = tskNO_AFFINITY;
|
||||
@@ -189,20 +198,102 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
}
|
||||
|
||||
ret = xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask );
|
||||
xReturn = xTaskCreateAffinitySet( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, uxCoreAffinityMask, pxCreatedTask );
|
||||
}
|
||||
#else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */
|
||||
#else /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
{
|
||||
ret = xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask );
|
||||
xReturn = xTaskCreate( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask );
|
||||
}
|
||||
#endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */
|
||||
return ret;
|
||||
#endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
|
||||
/* If the stack grows down then allocate the stack then the TCB so the
|
||||
* stack does not grow into the TCB. Likewise if the stack grows up
|
||||
* then allocate the TCB then the stack. */
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
{
|
||||
/* Allocate space for the TCB. Where the memory comes from depends on
|
||||
* the implementation of the port malloc function and whether or not static
|
||||
* allocation is being used. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Allocate space for the stack used by the task being created.
|
||||
* The base of the stack memory stored in the TCB so the task can
|
||||
* be deleted later if required. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||
|
||||
if( pxNewTCB->pxStack == NULL )
|
||||
{
|
||||
/* Could not allocate the stack. Delete the allocated TCB. */
|
||||
vPortFree( pxNewTCB );
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
StackType_t * pxStack;
|
||||
|
||||
/* Allocate space for the stack used by the task being created. */
|
||||
pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */
|
||||
|
||||
if( pxStack != NULL )
|
||||
{
|
||||
/* Allocate space for the TCB. */
|
||||
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
/* Store the stack location in the TCB. */
|
||||
pxNewTCB->pxStack = pxStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The stack cannot be used as the TCB was not created. Free
|
||||
* it again. */
|
||||
vPortFree( pxStack );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pxNewTCB = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* portSTACK_GROWTH */
|
||||
|
||||
if( pxNewTCB != NULL )
|
||||
{
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created dynamically in case it is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
#endif /* ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
TaskHandle_t xTaskCreateStaticPinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
@@ -213,9 +304,13 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID )
|
||||
{
|
||||
TaskHandle_t ret;
|
||||
TaskHandle_t xReturn;
|
||||
|
||||
#if ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) )
|
||||
#if CONFIG_FREERTOS_SMP
|
||||
{
|
||||
/* If using Amazon SMP FreeRTOS. This function is just a wrapper around
|
||||
* xTaskCreateStatic() or xTaskCreateStaticAffinitySet(). */
|
||||
#if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
|
||||
{
|
||||
/* Convert xCoreID into an affinity mask */
|
||||
UBaseType_t uxCoreAffinityMask;
|
||||
@@ -229,17 +324,62 @@ _Static_assert( offsetof( StaticTask_t, pxDummy8 ) == offsetof( TCB_t, pxEndOfSt
|
||||
uxCoreAffinityMask = ( 1 << xCoreID );
|
||||
}
|
||||
|
||||
ret = xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask );
|
||||
xReturn = xTaskCreateStaticAffinitySet( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer, uxCoreAffinityMask );
|
||||
}
|
||||
#else /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */
|
||||
#else /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
{
|
||||
ret = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer );
|
||||
xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer );
|
||||
}
|
||||
#endif /* ( ( configUSE_CORE_AFFINITY == 1 ) && ( configNUM_CORES > 1 ) ) */
|
||||
return ret;
|
||||
#endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */
|
||||
}
|
||||
#else /* CONFIG_FREERTOS_SMP */
|
||||
{
|
||||
TCB_t * pxNewTCB;
|
||||
|
||||
configASSERT( portVALID_STACK_MEM( puxStackBuffer ) );
|
||||
configASSERT( portVALID_TCB_MEM( pxTaskBuffer ) );
|
||||
configASSERT( ( ( xCoreID >= 0 ) && ( xCoreID < configNUM_CORES ) ) || ( xCoreID == tskNO_AFFINITY ) );
|
||||
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
/* Sanity check that the size of the structure used to declare a
|
||||
* variable of type StaticTask_t equals the size of the real task
|
||||
* structure. */
|
||||
volatile size_t xSize = sizeof( StaticTask_t );
|
||||
configASSERT( xSize == sizeof( TCB_t ) );
|
||||
( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )
|
||||
{
|
||||
/* The memory used for the task's TCB and stack are passed into this
|
||||
* function - use them. */
|
||||
pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */
|
||||
pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;
|
||||
|
||||
#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */
|
||||
{
|
||||
/* Tasks can be created statically or dynamically, so note this
|
||||
* task was created statically in case the task is later deleted. */
|
||||
pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;
|
||||
}
|
||||
#endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */
|
||||
|
||||
prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL, xCoreID );
|
||||
prvAddNewTaskToReadyList( pxNewTCB );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_FREERTOS_SMP */
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
|
||||
/*----------------------------------------------------------*/
|
||||
|
||||
#if ( configUSE_TIMERS == 1 )
|
||||
|
@@ -31,26 +31,23 @@
|
||||
#endif
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* -------------------------------------------------- Task Creation ---------------------------------------------------
|
||||
* Task Creation APIs added by ESP-IDF
|
||||
*
|
||||
* Todo: Move IDF FreeRTOS SMP related additions to this header as well (see IDF-7201)
|
||||
* Todo: Add these SMP related additions to docs once they are combined with IDF FreeRTOS.
|
||||
* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* -------------------------------------------------- Task Creation ------------------------------------------------- */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Create a new task that is pinned to a particular core
|
||||
*
|
||||
* Helper function to create a task that is pinned to a particular core, or has
|
||||
* no affinity. In other words, the created task will have an affinity mask of:
|
||||
* - (1 << xCoreID) if it is pinned to a particular core
|
||||
* - Set to tskNO_AFFINITY if it has no affinity
|
||||
* This function is similar to xTaskCreate(), but allows the creation of a pinned
|
||||
* task. The task's pinned core is specified by the xCoreID argument. If xCoreID
|
||||
* is set to tskNO_AFFINITY, then the task is unpinned and can run on any core.
|
||||
*
|
||||
* @note If ( configNUM_CORES == 1 ), xCoreID is ignored.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function.
|
||||
* @param pcName A descriptive name for the task.
|
||||
* @param usStackDepth The size of the task stack.
|
||||
* @param ulStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
* @param uxPriority The priority at which the task should run.
|
||||
@@ -63,24 +60,30 @@
|
||||
*/
|
||||
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
const uint32_t ulStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */
|
||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||
|
||||
#if ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||
|
||||
/**
|
||||
* @brief Create a new static task that is pinned to a particular core
|
||||
*
|
||||
* This funciton is the static equivalent of xTaskCreatePinnedToCore().
|
||||
* This function is similar to xTaskCreateStatic(), but allows the creation of a
|
||||
* pinned task. The task's pinned core is specified by the xCoreID argument. If
|
||||
* xCoreID is set to tskNO_AFFINITY, then the task is unpinned and can run on any
|
||||
* core.
|
||||
*
|
||||
* @note If ( configNUM_CORES == 1 ), xCoreID is ignored.
|
||||
*
|
||||
* @param pxTaskCode Pointer to the task entry function.
|
||||
* @param pcName A descriptive name for the task.
|
||||
* @param ulStackDepth The size of the task stack.
|
||||
* @param ulStackDepth The size of the task stack specified as the NUMBER OF
|
||||
* BYTES. Note that this differs from vanilla FreeRTOS.
|
||||
* @param pvParameters Pointer that will be used as the parameter for the task
|
||||
* being created.
|
||||
* @param uxPriority The priority at which the task should run.
|
||||
@@ -101,7 +104,7 @@
|
||||
StaticTask_t * const pxTaskBuffer,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
#endif /* ( CONFIG_FREERTOS_SMP && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */
|
||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||
|
||||
/* ------------------------------------------------- Task Utilities ------------------------------------------------- */
|
||||
|
||||
|
@@ -109,8 +109,6 @@ entries:
|
||||
# - "xTaskGetSchedulerState"
|
||||
# - "xTaskGetTickCount"
|
||||
# --------------------------------------------------------------------------------------------------------------
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:prvInitialiseNewTask (default)
|
||||
tasks:prvAddNewTaskToReadyList (default)
|
||||
tasks:vTaskDelete (default)
|
||||
|
@@ -22,7 +22,6 @@ entries:
|
||||
tasks:prvTakeKernelLock (default)
|
||||
tasks:prvReleaseKernelLock (default)
|
||||
# Task Creation
|
||||
if FREERTOS_SMP = y:
|
||||
tasks:xTaskCreatePinnedToCore (default)
|
||||
tasks:xTaskCreateStaticPinnedToCore (default)
|
||||
# Task Utilities
|
||||
|
@@ -12,6 +12,8 @@ set(include_dirs
|
||||
"${original_freertos_dir}/config/include/freertos" # For "FreeRTOSConfig.h"
|
||||
"${original_freertos_dir}/config/linux/include" # For "freertos/FreeRTOSConfig_arch.h"
|
||||
"${original_freertos_dir}/esp_additions/include"
|
||||
# Required because CMock tries to include "idf_additions.h" instead of "freertos/idf_additions.h"
|
||||
"${original_freertos_dir}/esp_additions/include/freertos"
|
||||
"${kernel_dir}/portable/linux/include" # For "freertos/portmacro.h"
|
||||
"${kernel_dir}/include/freertos" # this is due to the way includes are generated in CMock (without freertos prefix)
|
||||
)
|
||||
@@ -19,6 +21,7 @@ set(include_dirs
|
||||
idf_component_mock(INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES esp_common
|
||||
MOCK_HEADER_FILES
|
||||
${original_freertos_dir}/esp_additions/include/freertos/idf_additions.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/task.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/event_groups.h
|
||||
${original_freertos_dir}/FreeRTOS-Kernel/include/freertos/queue.h)
|
||||
|
Reference in New Issue
Block a user