FreeRTOS-任务创建源码分析

本文深入分析了FreeRTOS任务创建的过程,包括任务堆栈和任务控制块的分配与初始化,以及如何将任务添加到就绪列表。任务创建接口、内存管理、任务初始化和就绪列表操作等关键步骤被详细探讨,对于理解FreeRTOS内核运作至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任务创建是FreeRTOS系统启动的第一个步骤,前面在启动调度器的时候先创建了空闲任务,然后再由调度器跳到任务里面去执行。任务创建函数里面做了很多的工作,先会为任务堆栈和任务控制块分配内存并初始化它们,然后将任务添加到就绪列表里面,等待调度器来调用。
任务创建的接口定义如下:

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 )
	

形参代表的意义如下:

pxTaskCode		任务函数入口地址		
pcName			任务名称
usStackDepth	任务堆栈大小	
pvParameters	传递给任务函数的参数
uxPriority		任务优先级
pxCreatedTask	任务控制块句柄

源码分析:

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;
	
		#if( portSTACK_GROWTH > 0 )
		{
			/* 如果堆栈向上增长,则先分配任务控制块 */
			pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );

			if( pxNewTCB != NULL )
			{
				/* 分配任务堆栈,具体内存分配实现在内存管理章节分析 */
				pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); 

				if( pxNewTCB->pxStack == NULL )
				{
					/* 堆栈分配失败就释放之前分配的任务控制块内存 */
					vPortFree( pxNewTCB );
					pxNewTCB = NULL;
				}
			}
		}
		#else
		{
		StackType_t *pxStack;

			/* 如果堆栈向下增长,则先分配任务堆栈 */
			pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) );

			if( pxStack != NULL )
			{
				/* 堆栈分配成功后分配任务控制块空间 */
				pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );
				if( pxNewTCB != NULL )
				{
					/* 初始化任务控制块的堆栈指针 */
					pxNewTCB->pxStack = pxStack;
				}
				else
				{
					/* 任务控制块分配失败就释放之间分配的任务堆栈内存 */
					vPortFree( pxStack );
				}
			}
			else
			{
				pxNewTCB = NULL;
			}
		}
		#endif

		if( pxNewTCB != NULL )
		{
			#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) 
			{
				/* 可以静态也可以动态分配的情况下默认使用动态分配内存 */
				pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB;
			}
			#endif 

			/* 初始化任务 */
			prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL );
			/* 把列表项添加到就绪列表中,优先级高过原来的话就请求一次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值