FreeRTOS-启动任务调度器源码分析

本章基于FreeRTOS的启动任务调度器源码分析,后续将会上传其它我对FreeRTOS的源码分析过程及理解,首先来认识一下任务调度器。

任务调度器:
任务调度器主要用于实现任务的切换,任务并不是我们所熟知的函数,而是指一段占有独立内存空间,专门用于处理一组逻辑事件的任务块。最直观的对比理解就像是可以有多个while函数,以前我们写代码都是一个main函数一个while循环,我们会在while循环里面做完所有的事,当任务大起来以后,我们会将各个功能分为多个函数来写,使用状态机的方式来实现逻辑操作,有时我们还需要借助各种中断来置位标志位,然后等待main里面的while轮询去执行。这个就是单任务系统,又称为前后台系统,中断服务函数为前台,main的操作为后台程序。这种操作方式的实时性非常差,由于是while轮询,没轮到就只能一直等着,对于简单的应用程序是够用的,但是一旦应用大起来就力不从心了。因此这里引入多任务的实现方式,相当于可以写多个while来处理我们的代码,显然这更符合我们的处理事件的逻辑,但是CPU只有一个,又如何做到一心多用呢,实际上操作系统是通过定时器中断来隔一阵子切换一个while,并不是真的是并行处理着两个while,这种处理方式我们叫做并发,各个while各占用一段时间,由任务调度器来决定下一个while是谁,具体怎么切换的就是任务调度器的工作了。

说到任务调度一定离不开堆栈,堆栈也是OS的基础,堆栈可以引起很多话题,下面只做个简单的介绍,后面代码会具体分析。

堆栈:笼统地讲,堆栈操作就是对内存的读写操作,在我们执行main函数的时候,我们在里面定义变量,修改变量实际上都是在操作堆栈,堆栈这里理解为内存即可,每定义一个变量,都会占用一定的内存空间,比如int类型变量就是4字节的内存空间,也就是占用4字节的堆栈空间,main这个进程的堆栈大小我们可以自行定义,但不能超过CPU的最大内存。如果将一块大的内存分为多个小的堆栈内存,不就可以实现类似多个main进程一样的效果了吗,每个进程使用自己的那块堆栈,大家并行不悖,当需要跳转的时候使用任务调度器进行一下堆栈切换就好了。

FreeRTOS能实现效果上多个任务的同时运行,由于任务调度器在各个任务之间的切换非常快,所以效果上看起来就像是所有的任务同时运行一样,这章主要分析FreeRTOS是如何启动任务调度器的(包括启动调度器前的准备工作和堆栈切换),至于调度器如何根据时间片和优先级来实现任务间的切换后面会继续分析源码的实现。


以一段初始化开始,一般我们在使用FreeRTOS之前都会先定义一个启动任务,然后启动任务调度器,如下:

int main()
{
	/* 初始化外设 */
	init_periph();
	/* 创建开始任务 */
	xTaskCreate((TaskFunction_t)start_task,         /* 任务函数 */
				(const char*   )"start_task",		/* 任务名称 */
				(uint16_t      )START_STK_SIZE,		/* 任务堆栈大小 */
				(void*         )NULL,				/* 传递给任务函数 */
				(UBaseType_t   )START_TASK_PRIO,	/* 任务优先级 */
				(TaskHandle_t* )&StartTask_Handler);/* 任务句

你可能感兴趣的:(FreeRTOS)