静态创建:
函数返回值类型:t typedef long BaseType_t;一般为pdTRUE表示任务创建成功,pdFALSE表示任务创建失败
参数:函数指针类型变量pxTaskCode;任务的描述pcName;任务的堆栈深度,实际所占用的任务堆栈大小是usStackDepth*4;入口参数pvParameters,一般设置为NULL,任务的优先级uxPriority;任务的句柄pxCreatedTask;最后两个参数一般设置为NULL
函数描述:为任务申请一段空间作为任务的堆栈,以及任务控制块。
BaseType_t xTaskGenericCreate( 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, const MemoryRegion_t * const xRegions )
函数体主要分为:
①为任务分配任务堆栈内存以及任务控制块,由于M3内核任务堆栈是向下生长的,为了防止堆栈在生长的过程中发生堆栈溢出破坏任务控制块的结构,所以先申请任务堆栈再申请任务控制块
函数名:prvAllocateTCBAndStack
函数返回值数据类型:任务控制块类型的指针
函数参数:usStackDepth,puxStackBuffer
函数描述:为任务分配任务堆栈和任务控制块
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
②重定向任务的栈顶
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );
//pxNewTCB->pxStack指向最初的栈顶(固定不变的位置)、而新的栈顶pxTopOfStack是随着进栈出栈而变化的。
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
③:初始化任务控制块
函数名:prvInitialiseTCBVariables
函数返回值数据类型:static void
函数描述:初始化任务控制块中的一些变量
函数参数:新创建的任务控制块指针pxNewTCB、任务的描述pcName、任务优先级uxPriority、
xRegions一般为NULL指针,堆栈深度usStackDepth
prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth );
④:初始化任务堆栈
pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
⑤:初始化列表
prvInitialiseTaskLists();
⑥:将新创建的任务加入到任务就绪列表中
prvAddTaskToReadyList( pxNewTCB );
⑦:如果调度器已经启动且新创建的任务优先级较高则执行一次任务调度
if( xSchedulerRunning != pdFALSE )//但是此时任务调度器已经启动
{
/* If the created task is of a higher priority than the current task
then it should run now. */
if( pxCurrentTCB->uxPriority < uxPriority )//如果优先级比当前运行的任务优先级
//高的话就执行一次任务切换
{
taskYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}