当前位置: 首页> 游戏> 游戏 > FreeRTOS xTaskCreate函数讲解(窥探系统任务管理)

FreeRTOS xTaskCreate函数讲解(窥探系统任务管理)

时间:2025/7/9 8:06:51来源:https://blog.csdn.net/xin2332612018/article/details/142201486 浏览次数:0次
一.函数讲解

        函数原型:

        BaseType_t ICACHE_ATTR xTaskCreate(    

                            TaskFunction_t pxTaskCode,

                            const configSTACK_DEPTH_TYPE usStackDepth,

                            void * const pvParameters,

                            UBaseType_t uxPriority,

                            TaskHandle_t * const pxCreatedTask )

        作用:创建任务

二.代码解析(创建任务)

        任务控制块TCB:

typedef struct tskTaskControlBlock
{//任务栈栈顶,必须要TCB的第一个成员volatile StackType_t	*pxTopOfStack;//任务状态列表项ListItem_t			xStateListItem;//任务时间列表项ListItem_t			xEventListItem;//任务优先级UBaseType_t			uxPriority;//指向任务栈首地址的指针StackType_t			*pxStack;//任务名字char				pcTaskName[ configMAX_TASK_NAME_LEN ];//任务栈栈底#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )StackType_t		*pxEndOfStack;#endif#if ( portCRITICAL_NESTING_IN_TCB == 1 )UBaseType_t		uxCriticalNesting;#endif#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t		uxTCBNumber;UBaseType_t		uxTaskNumber;#endif//互斥信号量变量#if ( configUSE_MUTEXES == 1 )UBaseType_t		uxBasePriority;UBaseType_t		uxMutexesHeld;#endif#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )void			*pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];#endif#if( configGENERATE_RUN_TIME_STATS == 1 )uint32_t		ulRunTimeCounter;#endif//任务通知模块变量#if( configUSE_TASK_NOTIFICATIONS == 1 )volatile uint32_t ulNotifiedValue;volatile uint8_t ucNotifyState;#endif} tskTCB;

    

	BaseType_t ICACHE_ATTR xTaskCreate(	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 ){//创建任务控制块TCB_t *pxNewTCB;BaseType_t xReturn;/* If the stack grows down then allocate the stack then the TCB so the stackdoes not grow into the TCB.  Likewise if the stack grows up then allocatethe TCB then the stack. *///判断栈的地址是向上增长还是向下增长。也就是地址存储是从低地址往高地址增长还是高往低#if( portSTACK_GROWTH > 0 ){/* Allocate space for the TCB.  Where the memory comes from depends onthe implementation of the port malloc function and whether or not staticallocation 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 canbe 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.  Freeit 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 thistask 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 );//把新创建的任务添加到就绪列表中prvAddNewTaskToReadyList( pxNewTCB );xReturn = pdPASS;}else{xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;}return xReturn;}

        prvInitialiseNewTask()函数:

//把堆栈空间全部赋值成tskSTACK_FILL_BYTE,方便检测剩余堆栈大小,判断是否为tskSTACK_FILL_BYTE
( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) );//把栈顶地址赋值给pxTopOfStack,注意是栈顶地址(栈末尾地址),不是栈起始地址
pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] );//8字节对其
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );//赋值名字
pxNewTCB->pcTaskName[ x ] = pcName[ x ];//任务优先级赋值
pxNewTCB->uxPriority = uxPriority;//互斥量优先级初始化,用于互斥信号量场景使用,防止优先级翻转问题
#if ( configUSE_MUTEXES == 1 )
{pxNewTCB->uxBasePriority = uxPriority;pxNewTCB->uxMutexesHeld = 0;
}//初始化状态列表项以及事件列表项
vListInitialiseItem( &( pxNewTCB->xStateListItem ) );
vListInitialiseItem( &( pxNewTCB->xEventListItem ) );
listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );
//初始化事件列表项数值
listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t )configMAX_PRIORITIES - ( TickType_t ) uxPriority );
listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );//对任务栈进行赋值
pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );//任务句柄赋值
*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;

        prvAddNewTaskToReadyList()函数

static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{/* Ensure interrupts don't access the task lists while the lists are beingupdated. *///临界区taskENTER_CRITICAL();{//任务数量++uxCurrentNumberOfTasks++;//pxCurrentTCB 指向当前优先级最高的任务,这里判断的意思是是否为第一个任务if( pxCurrentTCB == NULL ){/* There are no other tasks, or all the other tasks are inthe suspended state - make this the current task. *///赋值任务控制块pxCurrentTCB = pxNewTCB;//如果是第一个任务if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ){//初始化列表/* This is the first task to be created so do the preliminaryinitialisation required.  We will not recover if this callfails, but we will report the failure. */prvInitialiseTaskLists();}else{mtCOVERAGE_TEST_MARKER();}}else{/* If the scheduler is not already running, make this task thecurrent task if it is the highest priority task to be createdso far. *///判断调度器是否启动if( xSchedulerRunning == pdFALSE ){//如果已经启动,并且新创建的任务优先级比当前任务优先级高if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ){pxCurrentTCB = pxNewTCB;}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}}//任务标号,第几个创建的任务uxTaskNumber++;#if ( configUSE_TRACE_FACILITY == 1 ){/* Add a counter into the TCB for tracing only. */pxNewTCB->uxTCBNumber = uxTaskNumber;}#endif /* configUSE_TRACE_FACILITY */traceTASK_CREATE( pxNewTCB );//添加到就绪列表prvAddTaskToReadyList( pxNewTCB );portSETUP_TCB( pxNewTCB );}taskEXIT_CRITICAL();if( xSchedulerRunning != pdFALSE ){/* If the created task is of a higher priority than the current taskthen it should run now. *///调度器已启动,如果新创建的任务优先级比当前执行任务高,则进行一次任务调度,切换任务if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ){taskYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}
}

        prvInitialiseTaskLists()

static void prvInitialiseTaskLists( void )
{
UBaseType_t uxPriority;//初始化就绪列表for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ){vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );}//初始化两个延时列表,为什么是两个?为了防止溢出vListInitialise( &xDelayedTaskList1 );vListInitialise( &xDelayedTaskList2 );//初始化等待就绪列表vListInitialise( &xPendingReadyList );//初始化等待删除列表#if ( INCLUDE_vTaskDelete == 1 ){vListInitialise( &xTasksWaitingTermination );}#endif /* INCLUDE_vTaskDelete *///初始化挂起列表#if ( INCLUDE_vTaskSuspend == 1 ){vListInitialise( &xSuspendedTaskList );}#endif /* INCLUDE_vTaskSuspend *//* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskListusing list2. */pxDelayedTaskList = &xDelayedTaskList1;pxOverflowDelayedTaskList = &xDelayedTaskList2;
}

        #define prvAddTaskToReadyList( pxTCB )

#define prvAddTaskToReadyList( pxTCB )																\//traceMOVED_TASK_TO_READY_STATE( pxTCB );														\//如果新pxTCB的优先级比当前就绪列表中任务最高优先级大,则赋值给uxTopReadyPrioritytaskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority );												\//尾部插入到就绪列表中vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB )

关键字:FreeRTOS xTaskCreate函数讲解(窥探系统任务管理)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: