一、什么是任务系统
单片机裸跑的时候一般都是在main函数里面用 while (1) 做一个大循环来完成所有的处理,即应用程序是一个无限的循环,循环中调用相应的函数完成所需的处理。这个就是单任务系统,也称为前后台系统,中断服务函数作为前台程序,大循环 while (1) 作为后台程序。
FreeRTOS是一个抢占式的实时多任务系统。
高优先级的任务可以打断低优先级任务的运行而取得CPU的使用权。高优先级的任务执行完成以后重新把CPU的使用权归还给低优先级的任务,这个就是抢占式多任务系统的基本原理。
二、任务(Task)的特性
在使用RTOS的时候一个实时应用可以作为一个独立的任务。每个任务都有自己的运行环境,不依赖于系统中的其他的任务或者RTOS调度器。任何一个时间点只能有一个任务运行,具体运行哪个任务是由RTOS调度器来决定的,RTOS调度器因此就会重复的开启、关闭每个任务。任务不需要了解RTOS调度器的具体行动,RTOS调度器的职责是确保当一个任务开始执行的时候其上下文环境(寄存器值,堆栈内容等)和任务上一次退出的时候相同。为了做到这一点,每个任务都必须有个堆栈,当任务切换的时候将上下文环境保存在堆栈中,这样当任务再次执行的时候就可以从堆栈中取出上下文环境,任务恢复运行。
任务特性:
-
- 简单
-
- 没有使用限制
-
- 支持抢占
-
- 支持优先级
-
- 每个任务都拥有堆栈导致了 RAM 使用量增大
-
- 如果使用抢占的话必须仔细的考虑重入的问题
三、任务状态
FreeRTOS 中的任务永远处于下面几个状态中的某一个。
运行态
当一个任务正在运行时,那么就说这个任务处于运行态,处于运行态的任务就是当前正在使用处理器的任务。如果使用的是单核处理器的话那么不管在任何时刻永远都只有一个任务处于运行态。
就绪态
处于就绪态的任务是那些已经准备就绪(这些任务没有被阻塞或者挂起),可以运行的任务,但是处于就绪态的任务还没有运行,因为有一个同优先级或者更高优先级的任务正在运行。
阻塞态
如果一个任务当前正在等待某个外部事件的话就说它处于阻塞态,比如说如果某个任务调用了函数 vTaskDelay() 的话就会进入阻塞态,直到延时周期完成。任务在等待队列、信号量、事件组、通知或互斥信号量的胡思后也会进入阻塞态。任务进入阻塞态会有一个超时时间,当超过这个超时时间任务就会退出阻塞态,即使所等待的事件还没有来临。
挂起态
像阻塞态一样,任务进入挂起态以后也不能被调度器调用进入运行态,但是进入挂起态的任务没有超时时间。任务进入和退出挂起态通过调用函数 vTaskSuspend() 和 xTaskResume()。
任务状态之间的转换如图: