+/*\r
+ * Searches pxList for a task with name pcNameToQuery - returning a handle to\r
+ * the task if it is found, or NULL if the task is not found.\r
+ */\r
+#if ( INCLUDE_xTaskGetTaskHandle == 1 )\r
+\r
+ static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION;\r
+\r
+#endif\r
+\r
+/*\r
+ * When a task is created, the stack of the task is filled with a known value.\r
+ * This function determines the 'high water mark' of the task stack by\r
+ * determining how much of the stack remains at the original preset value.\r
+ */\r
+#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+\r
+ static uint16_t 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, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\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
+\r
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+\r
+ BaseType_t xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ {\r
+ TCB_t *pxNewTCB;\r
+ BaseType_t xReturn;\r
+\r
+ configASSERT( puxStackBuffer != NULL );\r
+ configASSERT( pxTaskBuffer != NULL );\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 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( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\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 = pdTRUE;\r
+ }\r
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
+\r
+ prvInitialiseNewTask( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB );\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 /* SUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+\r
+ BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\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 = ( 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( pxStack != NULL )\r
+ {\r
+ /* Allocate space for the TCB. */\r
+ pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */\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( configSUPPORT_STATIC_ALLOCATION == 1 )\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 = pdFALSE;\r
+ }\r
+ #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+\r
+ prvInitialiseNewTask( pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB );\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, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, TCB_t *pxNewTCB ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\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( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )\r
+ {\r
+ /* Fill the stack with a known value to assist debugging. */\r
+ ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) );\r
+ }\r
+ #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */\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 + ( usStackDepth - ( uint16_t ) 1 );\r
+ pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */\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
+ #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 + ( usStackDepth - ( uint16_t ) 1 );\r
+ }\r
+ #endif /* portSTACK_GROWTH */\r
+\r
+ /* Store the task name in the TCB. */\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 ] == 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
+ /* 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
+\r
+ pxNewTCB->uxPriority = uxPriority;\r
+ #if ( configUSE_MUTEXES == 1 )\r
+ {\r
+ pxNewTCB->uxBasePriority = uxPriority;\r
+ pxNewTCB->uxMutexesHeld = 0;\r
+ }\r
+ #endif /* configUSE_MUTEXES */\r
+\r
+ vListInitialiseItem( &( pxNewTCB->xStateListItem ) );\r
+ vListInitialiseItem( &( pxNewTCB->xEventListItem ) );\r