对FreeRTOS的深入理解(二)

        接着对FreeRTOS的深入理解(一),上文是从任务创建开始进入这个操作系统,那么跳过自己创建任务的步骤,也是可以的,理由在下文就会清晰。本文讲述的是任务调度器初始化及开始调度的部分,希望各位大佬看见错了不要喷我谢谢,这些文章只是我对于FreeRTOS的源码个人的理解与整理。

        我们从vTaskStartScheduler();这个开启任务调度的API出发,首先,FreeRTOS会先创造一个空闲任务,当然会根据是使用什么样的分配方式来创建这个空闲任务,一般是动态分配。这个空闲任务的创建就解释了为什么我说创建自己任务的步骤可以跳过,因为这里固定会有一个空闲任务,这样的话你的所有任务列表的初始化是一定能得到保证的。

/* The Idle task is being created using dynamically allocated RAM. */
xReturn = xTaskCreate(	prvIdleTask,
						"IDLE", configMINIMAL_STACK_SIZE,
						( void * ) NULL,
						( tskIDLE_PRIORITY | portPRIVILEGE_BIT ),
						&xIdleTaskHandle );

        

        第二步会去创建一个定时器任务,也就是xTimerCreateTimerTask();。在这里面,首先FreeRTOS会去初始化两个关于定时器的列表,一个是pxCurrentTimerList(这里认为是一个为当前正在运行的定时器列表,即其中存储了当前正在执行的定时器),还有一个是pxOverflowTimerList(其中存储了因为某些原因(比如定时器事件太多)而无法立即执行的定时器),然后会去创建一个关于TIMER的消息队列,并且在注册表中注册消息队列,下文有一些关于这个消息队列的描述,对应源码如下几句:

xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );
vQueueAddToRegistry( xTimerQueue, "TmrQ" );

做完这些FreeRTOS会去创建一个定时器任务(注意此处为任务,上文为消息队列),这个定时器创建出来,作用可以从他的任务句柄中查看,其任务句柄为prvTimerTask,进入后源码如下:

static void prvTimerTask( void *pvParameters )
{
TickType_t xNextExpireTime;
BaseType_t xListWasEmpty;

	/* Just to avoid compiler warnings. */
	( void ) pvParameters;

	#if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )
	{
		extern void vApplicationDaemonTaskStartupHook( void );

		/* Allow the application writer to execute some code in the context of
		this task at the point the task starts executing.  This is useful if the
		application includes initialisation code that would benefit from
		executing after the scheduler has been started. */
		vApplicationDaemonTaskStartupHook();
	}
	#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */

	for( ;; )
	{
		/* Query the timers list to see if it contains any timers, and if so,
		obtain the time at which the next timer will expire. */
		xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );

		/* If a timer has expired, process it.  Otherwise, block this task
		until either a timer does expire, or a command is received. */
		prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );

		/* Empty the command queue. */
		prvProcessReceivedCommands();
	}
}

开始有一个宏定义的if是你有没有开启守护进程,关于守护进程的具体用法和详细概念作者实力有限,说不太出来,反正简单而言守护进程 (daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。 很多守护进程在系统引

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值