1、这个函数的作用
创建一个新的任务,使得FreeRTOS的调度器可以在这个任务就绪的时候给他CPU的使用权,让它运行。
2、分析代码
分析的内容直接写在代码注释中了
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )// 打开了动态分配这个宏
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, // 任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小
void * const pvParameters, // 参数列表
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask ) // 句柄
{
TCB_t * pxNewTCB; // 新建任务控制块
BaseType_t xReturn; // 返回值
/* 栈向下增长:先分配栈,再分配TCB,这样栈就不会长到TCB里。
* 栈向上增长:先分配TCB,再分配栈。 */
#if ( portSTACK_GROWTH > 0 ) // 栈向上增长的情况
{
// 与栈向下增长的情况差不多,因此此处省略
}
#else /* portSTACK_GROWTH */
{
StackType_t * pxStack; // 定义栈变量
/* 给栈变量分配内存空间 */
pxStack = pvPortMallocStack( ( ( ( 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 ) // 分配成功
{
/* 给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 ) // 分配成功
{
memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) );// 清洗TCB内存空间
/* 分配好的栈地址保存到TCB */
pxNewTCB->pxStack = pxStack;
}
else // 分配失败
{
/* 释放栈的内存空间 */
vPortFreeStack( pxStack );
}
}
else // 分配失败
{
pxNewTCB = NULL; // TCB无效
}
}
#endif /* portSTACK_GROWTH */
if( pxNewTCB != NULL ) // TCB 有效的情况
{
#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 );
// 把新任务添加到就绪列表
prvAddNewTaskToReadyList( pxNewTCB );
xReturn = pdPASS;
}
else // TCB 无效的情况
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;// 配置返回值(分配内存失败错误)
}
return xReturn;
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
3、总结
这个函数的主要工作:
1、根据栈增方开辟内存空间
2、为TCB分配内存空间
3、初始化新任务(prvInitialiseNewTask函数,该函数的浅析见https://blog.csdn.net/wong_xian/article/details/140775770)
4、将新任务添加到就绪列表(prvAddNewTaskToReadyList函数)