+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) )\r
+\r
+ static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * Return the amount of time, in ticks, that will pass before the kernel will\r
+ * next move a task from the Blocked state to the Running state.\r
+ *\r
+ * This conditional compilation should use inequality to 0, not equality to 1.\r
+ * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user\r
+ * defined low power mode implementations require configUSE_TICKLESS_IDLE to be\r
+ * set to a value other than 1.\r
+ */\r
+#if ( configUSE_TICKLESS_IDLE != 0 )\r
+\r
+ static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * Set xNextTaskUnblockTime to the time at which the next Blocked state task\r
+ * will exit the Blocked state.\r
+ */\r
+static void prvResetNextTaskUnblockTime( void );\r
+\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) )\r
+\r
+ /*\r
+ * Helper function used to pad task names with spaces when printing out\r
+ * human readable tables of task information.\r
+ */\r
+ static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * Called after a Task_t structure has been allocated either statically or\r
+ * dynamically to fill in the structure's members.\r
+ */\r
+static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,\r
+ const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const uint32_t ulStackDepth,\r
+ void * const pvParameters,\r
+ UBaseType_t uxPriority,\r
+ TaskHandle_t * const pxCreatedTask,\r
+ TCB_t *pxNewTCB,\r
+ const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * Called after a new task has been created and initialised to place the task\r
+ * under the control of the scheduler.\r
+ */\r
+static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * freertos_tasks_c_additions_init() should only be called if the user definable\r
+ * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro\r
+ * called by the function.\r
+ */\r
+#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT\r
+\r
+ static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+\r
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,\r
+ const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const uint32_t ulStackDepth,\r
+ void * const pvParameters,\r
+ UBaseType_t uxPriority,\r
+ StackType_t * const puxStackBuffer,\r
+ StaticTask_t * const pxTaskBuffer )\r
+ {\r
+ TCB_t *pxNewTCB;\r
+ TaskHandle_t xReturn;\r
+\r
+ configASSERT( puxStackBuffer != NULL );\r
+ configASSERT( pxTaskBuffer != NULL );\r
+\r
+ #if( configASSERT_DEFINED == 1 )\r
+ {\r
+ /* Sanity check that the size of the structure used to declare a\r
+ variable of type StaticTask_t equals the size of the real task\r
+ structure. */\r
+ volatile size_t xSize = sizeof( StaticTask_t );\r
+ configASSERT( xSize == sizeof( TCB_t ) );\r
+ ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */\r
+ }\r
+ #endif /* configASSERT_DEFINED */\r
+\r
+\r
+ if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )\r
+ {\r
+ /* The memory used for the task's TCB and stack are passed into this\r
+ function - use them. */\r
+ 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. */\r
+ pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer;\r
+\r
+ #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */\r
+ {\r
+ /* Tasks can be created statically or dynamically, so note this\r
+ task was created statically in case the task is later deleted. */\r
+ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;\r
+ }\r
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
+\r
+ prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL );\r
+ prvAddNewTaskToReadyList( pxNewTCB );\r
+ }\r
+ else\r
+ {\r
+ xReturn = NULL;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* SUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )\r
+\r
+ BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )\r
+ {\r
+ TCB_t *pxNewTCB;\r
+ BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+\r
+ configASSERT( pxTaskDefinition->puxStackBuffer != NULL );\r
+ configASSERT( pxTaskDefinition->pxTaskBuffer != NULL );\r
+\r
+ if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) )\r
+ {\r
+ /* Allocate space for the TCB. Where the memory comes from depends\r
+ on the implementation of the port malloc function and whether or\r
+ not static allocation is being used. */\r
+ pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer;\r
+\r
+ /* Store the stack location in the TCB. */\r
+ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;\r
+\r
+ #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )\r
+ {\r
+ /* Tasks can be created statically or dynamically, so note this\r
+ task was created statically in case the task is later deleted. */\r
+ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB;\r
+ }\r
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
+\r
+ prvInitialiseNewTask( pxTaskDefinition->pvTaskCode,\r
+ pxTaskDefinition->pcName,\r
+ ( uint32_t ) pxTaskDefinition->usStackDepth,\r
+ pxTaskDefinition->pvParameters,\r
+ pxTaskDefinition->uxPriority,\r
+ pxCreatedTask, pxNewTCB,\r
+ pxTaskDefinition->xRegions );\r
+\r
+ prvAddNewTaskToReadyList( pxNewTCB );\r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )\r
+\r
+ BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask )\r
+ {\r
+ TCB_t *pxNewTCB;\r
+ BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+\r
+ configASSERT( pxTaskDefinition->puxStackBuffer );\r
+\r
+ if( pxTaskDefinition->puxStackBuffer != NULL )\r
+ {\r
+ /* Allocate space for the TCB. Where the memory comes from depends\r
+ on the implementation of the port malloc function and whether or\r
+ not static allocation is being used. */\r
+ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ /* Store the stack location in the TCB. */\r
+ pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer;\r
+\r
+ #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )\r
+ {\r
+ /* Tasks can be created statically or dynamically, so note\r
+ this task had a statically allocated stack in case it is\r
+ later deleted. The TCB was allocated dynamically. */\r
+ pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY;\r
+ }\r
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
+\r
+ prvInitialiseNewTask( pxTaskDefinition->pvTaskCode,\r
+ pxTaskDefinition->pcName,\r
+ ( uint32_t ) pxTaskDefinition->usStackDepth,\r
+ pxTaskDefinition->pvParameters,\r
+ pxTaskDefinition->uxPriority,\r
+ pxCreatedTask, pxNewTCB,\r
+ pxTaskDefinition->xRegions );\r
+\r
+ prvAddNewTaskToReadyList( pxNewTCB );\r
+ xReturn = pdPASS;\r
+ }\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* portUSING_MPU_WRAPPERS */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+\r
+ BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,\r
+ const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const configSTACK_DEPTH_TYPE usStackDepth,\r
+ void * const pvParameters,\r
+ UBaseType_t uxPriority,\r
+ TaskHandle_t * const pxCreatedTask )\r
+ {\r
+ TCB_t *pxNewTCB;\r
+ BaseType_t xReturn;\r
+\r
+ /* If the stack grows down then allocate the stack then the TCB so the stack\r
+ does not grow into the TCB. Likewise if the stack grows up then allocate\r
+ the TCB then the stack. */\r
+ #if( portSTACK_GROWTH > 0 )\r
+ {\r
+ /* Allocate space for the TCB. Where the memory comes from depends on\r
+ the implementation of the port malloc function and whether or not static\r
+ allocation is being used. */\r
+ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ /* Allocate space for the stack used by the task being created.\r
+ The base of the stack memory stored in the TCB so the task can\r
+ be deleted later if required. */\r
+ pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
+\r
+ if( pxNewTCB->pxStack == NULL )\r
+ {\r
+ /* Could not allocate the stack. Delete the allocated TCB. */\r
+ vPortFree( pxNewTCB );\r
+ pxNewTCB = NULL;\r
+ }\r
+ }\r
+ }\r
+ #else /* portSTACK_GROWTH */\r
+ {\r
+ StackType_t *pxStack;\r
+\r
+ /* Allocate space for the stack used by the task being created. */\r
+ 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. */\r
+\r
+ if( pxStack != NULL )\r
+ {\r
+ /* Allocate space for the TCB. */\r
+ 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. */\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ /* Store the stack location in the TCB. */\r
+ pxNewTCB->pxStack = pxStack;\r
+ }\r
+ else\r
+ {\r
+ /* The stack cannot be used as the TCB was not created. Free\r
+ it again. */\r
+ vPortFree( pxStack );\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pxNewTCB = NULL;\r
+ }\r
+ }\r
+ #endif /* portSTACK_GROWTH */\r
+\r
+ if( pxNewTCB != NULL )\r
+ {\r
+ #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */\r
+ {\r
+ /* Tasks can be created statically or dynamically, so note this\r
+ task was created dynamically in case it is later deleted. */\r
+ pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;\r
+ }\r
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */\r
+\r
+ prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );\r
+ prvAddNewTaskToReadyList( pxNewTCB );\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,\r
+ const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const uint32_t ulStackDepth,\r
+ void * const pvParameters,\r
+ UBaseType_t uxPriority,\r
+ TaskHandle_t * const pxCreatedTask,\r
+ TCB_t *pxNewTCB,\r
+ const MemoryRegion_t * const xRegions )\r
+{\r
+StackType_t *pxTopOfStack;\r
+UBaseType_t x;\r
+\r
+ #if( portUSING_MPU_WRAPPERS == 1 )\r
+ /* Should the task be created in privileged mode? */\r
+ BaseType_t xRunPrivileged;\r
+ if( ( uxPriority & portPRIVILEGE_BIT ) != 0U )\r
+ {\r
+ xRunPrivileged = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ xRunPrivileged = pdFALSE;\r
+ }\r
+ uxPriority &= ~portPRIVILEGE_BIT;\r
+ #endif /* portUSING_MPU_WRAPPERS == 1 */\r
+\r
+ /* Avoid dependency on memset() if it is not required. */\r
+ #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )\r
+ {\r
+ /* Fill the stack with a known value to assist debugging. */\r
+ ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) );\r
+ }\r
+ #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */\r
+\r
+ /* Calculate the top of stack address. This depends on whether the stack\r
+ grows from high memory to low (as per the 80x86) or vice versa.\r
+ portSTACK_GROWTH is used to make the result positive or negative as required\r
+ by the port. */\r
+ #if( portSTACK_GROWTH < 0 )\r
+ {\r
+ pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] );\r
+ pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */\r
+\r
+ /* Check the alignment of the calculated top of stack is correct. */\r
+ configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+\r
+ #if( configRECORD_STACK_HIGH_ADDRESS == 1 )\r
+ {\r
+ /* Also record the stack's high address, which may assist\r
+ debugging. */\r
+ pxNewTCB->pxEndOfStack = pxTopOfStack;\r
+ }\r
+ #endif /* configRECORD_STACK_HIGH_ADDRESS */\r
+ }\r
+ #else /* portSTACK_GROWTH */\r
+ {\r
+ pxTopOfStack = pxNewTCB->pxStack;\r
+\r
+ /* Check the alignment of the stack buffer is correct. */\r
+ configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
+\r
+ /* The other extreme of the stack space is required if stack checking is\r
+ performed. */\r
+ pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 );\r
+ }\r
+ #endif /* portSTACK_GROWTH */\r
+\r
+ /* Store the task name in the TCB. */\r
+ if( pcName != NULL )\r
+ {\r
+ for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )\r
+ {\r
+ pxNewTCB->pcTaskName[ x ] = pcName[ x ];\r
+\r
+ /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than\r
+ configMAX_TASK_NAME_LEN characters just in case the memory after the\r
+ string is not accessible (extremely unlikely). */\r
+ if( pcName[ x ] == ( char ) 0x00 )\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+\r
+ /* Ensure the name string is terminated in the case that the string length\r
+ was greater or equal to configMAX_TASK_NAME_LEN. */\r
+ pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0';\r
+ }\r
+ else\r
+ {\r
+ /* The task has not been given a name, so just ensure there is a NULL\r
+ terminator when it is read out. */\r
+ pxNewTCB->pcTaskName[ 0 ] = 0x00;\r
+ }\r
+\r
+ /* This is used as an array index so must ensure it's not too large. First\r
+ remove the privilege bit if one is present. */\r
+ if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES )\r
+ {\r
+ uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U;\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r