FreeRTOS学习笔记(13)---- FreeRTOS 任务创建分析

一、xTaskCreate()精简代码

BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,
							const uint16_t usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask ) 
{
TCB_t *pxNewTCB;
BaseType_t xReturn;
StackType_t *pxStack;
	
	pxStack = (StackType_t*)pvPortMalloc((((size_t)usStackDepth ) * sizeof( StackType_t ))); //(1)

	if( pxStack != NULL )
	{
		pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );  //(2)

		if( pxNewTCB != NULL )
		{				
			pxNewTCB->pxStack = pxStack;  //(3)
		}
		else
		{
			vPortFree( pxStack );  //(4)
		}
	}
	else
	{
		pxNewTCB = NULL;		//(5)
	}
	if( pxNewTCB != NULL )
	{
		//(6)
		prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
		prvAddNewTaskToReadyList( pxNewTCB );(7)
		xReturn = pdPASS;
	}
	else
	{
		xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
	return xReturn;
}

(1)申请堆栈内存
(2)申请任务控制块内存
(3)将申请的堆栈大小赋值给任务控制块的堆栈大小
(4)如果任务控制块内存申请失败就释放上一步申请的堆栈内存
(5)如果堆栈内存申请失败就任务控制块就指向空
(6)内存申请成功后调用prvInitialiseNewTask()初始化任务
(7)调用prvAddNewTaskToReadyList()添加新创建任务到就绪列表中

调用prvAddNewTaskToReadyList()添加新创建任务到就绪列表中

prvAddNewTaskToReadyList()精简代码

static void prvInitialiseNewTask( 	TaskFunction_t pxTaskCode,
									const char * const pcName,
									const uint32_t ulStackDepth,
									void * const pvParameters,
									UBaseType_t uxPriority,
									TaskHandle_t * const pxCreatedTask,
									TCB_t *pxNewTCB,
									const MemoryRegion_t * const xRegions ) 
{
StackType_t *pxTopOfStack;
UBaseType_t x;

	pxTopOfStack = pxNewTCB->pxStack;  //(1)
		
	for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ )
	{
		pxNewTCB->pcTaskName[ x ] = pcName[ x ];  //(2)

	}
	pxNewTCB->uxPriority = uxPriority;  //(3)
	#if ( configUSE_MUTEXES == 1 )//(4)
	{
		pxNewTCB->uxBasePriority = uxPriority;
		pxNewTCB->uxMutexesHeld = 0;
	}
	#endif /* configUSE_MUTEXES */

	//(5)
	vListInitialiseItem( &( pxNewTCB->xStateListItem ) );
	vListInitialiseItem( &( pxNewTCB->xEventListItem ) );

	listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB );//(6)
	//(7)
	listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); 
	listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB );//(8)

	//(9)
	#if( portUSING_MPU_WRAPPERS == 1 )
	{
		pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged );
	}
	#else /* portUSING_MPU_WRAPPERS */
	{
		pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters );
	}
	*pxCreatedTask = ( TaskHandle_t ) pxNewTCB;//(10)
}

(1)获取任务块堆栈
(2)传递参数任务名
(3)传递参数优先级
(4)互斥信号量时优先级继承
(5)初始化列表项
(6)设置列表项xStateListItem的成员pvOwner指向当前任务控制块
(7)设置列表项xEventListItem的成员xItemValue
(8)设置列表项xEventListItem的成员pvOwner指向当前任务控制块
(9)pxPortInitialiseStack()初始化堆栈赋值给任务控制块的栈顶
(10)保存记录任务句柄

三、调用prvAddNewTaskToReadyList()添加新创建任务到就绪列表中

prvAddNewTaskToReadyList()精简代码

static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
{
	taskENTER_CRITICAL();//(1)
	{
		uxCurrentNumberOfTasks++;//(2)
		prvInitialiseTaskLists();//(3)
		prvAddTaskToReadyList( pxNewTCB );(4)
	}
	taskEXIT_CRITICAL();(5)

(1)进入临街资源区进行保护
(2)系统中任务数加一
(3)初始化列表
(4)将任务添加到就绪列表中,最后调度器就可以就绪列表中执行任务了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值