Tasks and Task Management
任务和任务管理
介绍
任务是 RTOS 应用程序的主要构建模块之一。它是一个具有自身上下文的独立功能单元,本质上是一个小型的独立程序。RTOS 应用程序通常由多个任务组成,彼此互不知道对方的存在。应用设计者需要通过其他 RTOS 组件(如队列)来让它们共享数据或相互等待。
任务
包含定义任务的数据的数据结构称为任务块(TCB)。TCB可能包含诸如堆栈指针、堆栈大小、MPU设置、任务的优先级、任务的状态等信息。它帮助内核管理任务,例如,切换上下文。
任务函数定义了其功能。它有一个入口点,可以在其中放置需要一次性执行的内容,如初始化局部变量。它必须不能返回,这意味着在入口点之后,任务函数内部将有一个无限循环。要停止任务的执行可以通过API调用来删除它。多个任务也可以使用同一任务函数的实现。任务函数还可以在创建任务时定义参数。
作为每个任务都是一个独立的功能单元,每个都需要一个独立的执行环境。因此,每个任务都有自己的栈,局部数据如变量、函数参数或函数返回地址可以保存在这里。如果任务被调度程序切换出去,其当前上下文,如处理器寄存器等,将保存在任务的栈上,而被换入任务的上下文将从新任务的栈中恢复。
可以为一个任务分配一个优先级值,调度器使用该值来确定在多个任务已经准备好运行时应该执行哪个任务。‘
综上所述,每个任务都有一个状态。任务状态可以分为以下两组:
- 正在运行:当前正在处理该任务函数
- 没有运行
- 准备:该任务已经准备好执行,但另一个具有更高或相同优先级的任务正在运行。
- 阻塞:任务正在等待事件,例如已经过特定事件或队列中的数据可用。使用此状态,以便在等待时不使用处理时间(不轮询事件)。如果事件没有在某个事件框架内发生,则可能会生成超时,并且任务可以转到就绪状态,但可能希望处理超时条件。
- 挂起:应用程序通过API调用(
vTaskSuspend
)挂起任务,因此不适用任何处事件。它一直保持这种状态,直到通过林一个API调用(vTaskResume
)恢复。
任务管理
一个RTOS应用程序通常有几个任务组成。在具有单个核的处理器中,任务时候只能运行一个任务,因此所有的任务都必须共享可用的处理时间。调度程序用于决定哪个任务应该处于运行状态。他决定将哪个任务设置为正在运行状态的方式是通过调用调度策略。它还定义了何时应该执行上下文切换。
基于优先级优先调度
调度程序确保处于就绪态或运行态的最高优先级任务正在运行。因此,只要有一个比正在运行的任务更高优先级的任务进入就绪态,较低优先级的正在运行的任务就会被抢占并切换出去。
时间切片
如果在就绪和运行状态下的多个任务共享相同的特权,并且在这些状态中处于最高优先级,则使用时间切片来共享这些任务之间的处理时间。非时间切片定义为RTOS的两次定时中断之间的时间。每次中断时,调度程序从准备交换的列表中选择另一个任务。
示例
协同调度
如上图展示了一个合作式调度的示例。假设应用程序由三个任务组成,任务A优先级最高,任务B和C优先级相同但较低。在t1