嵌入式设备中使用的操作系统称为 RTOS ( 实时操作系统 )。在嵌入式设备中,实时任务至关重要,而定时在其中起着非常重要的作用。实时任务是时间确定性的,这意味着对任何事件的响应时间始终是恒定的,因此可以确保任何特定事件将在固定时间发生。 RTOS 旨在以非常精确的时序和高度的可靠性运行应用程序。 RTOS 还可以通过单个内核帮助执行多任务。
FreeRTOS 是一类用于嵌入式设备的 RTOS,其规模很小,可以在 8/16 位微控制器上运行,它的使用范围不仅限于这些微控制器。这是一个完全开源的代码,可在 github 上找到。如果我们了解 RTOS 的一些基本概念,那么使用 FreeRTOS 就会非常容易,因为它具有详细记录的API,可以直接在代码中使用,而无需了解代码的后端部分。
由于 FreeRTOS 可以在 8 位 MCU上 运行,因此它也可以在 Arduino Uno 开发板上运行。我们只需要下 载FreeRTOS 库,然后开始使用 API 来实现代码。
☛ RTOS是如何运作的?
在开始运行 RTOS 之前,让我们看看什么是任务。任务是一段可调度在 CPU 上执行的代码。因此,如果要执行某些任务,则应使用内核延迟或中断来安排任务。这项工作由内核中存在的 Scheduler 完成。在单核处理器中,调度程序可帮助任务在特定时间段内执行,但看起来不同的任务正在同时执行。每个任务都根据赋予它的优先级运行。
现在,让我们看看如果要创建一个以一秒钟为间隔的 LED 闪烁任务并将该任务置于最高优先级的情况,RTOS 内核中会发生什么。
除了 LED 任务外,内核还会创建另一个任务,称为空闲任务。当没有任务可执行时,将创建空闲任务。此任务始终以最低优先级 ( 即 0 优先级 ) 运行。如果我们分析上面给出的时序图,可以看出执行从一个 LED 任务开始,并运行了指定的时间,然后在剩余时间里,空闲任务一直运行到滴答中断发生为止。然后,内核根据任务的优先级和 LED 任务的总经过时间来决定必须执行的任务。 1 秒完成后,内核会再次选择执行 LED 任务,因为它比空闲任务具有更高的优先级,我们也可以说 LED 任务抢占了空闲任务。如果有两个以上具有相同优先级的任务,则它们将以循环方式运行指定的时间。
在状态图下方,它显示了非运行任务切换到运行状态。
每个新创建的任务都进入 ” 就绪 ” 状态 ( 部分处于非运行状态 )。如果创建的任务( Task1 ) 的优先级高于其他任务,则它将进入运行状态。如果此正在运行的任务被其他任务抢占,则它将再次回到就绪状态。否则,如果使用阻塞 API 阻塞了 task1,则 CPU 将不会参与该任务,直到用户定义的超时时间为止。
如果使用 Suspend API 将 Task1 挂起处于运行状态,则T ask1 将进入 ” 挂起 ” 状态,并且调度程序无法再次使用它。如果在挂起状态下恢复Task1,则它将返回到就绪状态,如框图所示。
以上就是任务如何运行和更改其状态的基本思想。
☛ RTOS中的常用术语
⑴ 任务 ( Task ):这是一段可在 CPU 上调度执行的代码。
⑵ 调度器 ( Scheduler ):它负责从就绪状态列表到运行状态中选择任务。经常实施调度程序,以便它们使所有计算机资源处于繁忙状态( 例如在负载平衡中 )。
⑶ 抢占 ( Preemption ):这是暂时中断已经执行的任务的动作,目的是在没有协作的情况下将其从运行状态中删除。
⑷ 上下文切换 ( Context Switching ):在基于优先级的抢占中,调度程序将每个 systick 中断上正在运行的任务的优先级与就绪任务列表的优先级进行比较。如果列表中有任何任务的优先级高于正在运行的任务,则会发生上下文切换。基本上,在此过程中,不同任务的内容将保存在各自的堆栈存储器中。
⑸ 调度策略的类型:
① 抢先式调度 ( Preemptive Scheduling ):在这种类型的调度中,任务以相等的时间片运行,而不考虑优先级。
② 基于优先级的抢占式 ( Priority-based Preemptive ):高优先级任务将首先运行。
③ 协作调度 ( Co-operative Scheduling ):上下文切换仅在运行任务的协作下发生。任务将连续运行,直到调用任务产量 ( task yield ) 为止。
⑹ 内核对象 ( Kernel Objects ):为了发信号通知任务执行某些工作,使用了同步过程。要执行此过程,将使用内核对象。一些内核对象包括事件、信号量、队列、互斥量、邮箱等。
通过以上讨论,我们对 RTOS 概念有了一些基本的想法,现在我们可以在 Arduino 中实现 FreeRTOS 项目。因此,让我们首先在 Arduino IDE 中安装 FreeRTOS 库。
☛ 安装 Arduino FreeRTOS 库
打开Arduino IDE,然后转到 Sketch -> Include Librar y-> Manage Libraries。搜索 FreeRTOS 并安装库,如下所示。
现在,重新启动 Arduino IDE。该库提供了一些示例代码,也可以在 File -> Examples -> FreeRTOS 中找到,如下所示。
☛ FreeRTOS 使用手册
详细的使用说明可参考: 掌握 FreeRTOS 实时内核——实操教程 及 FreeRTOS V10.0.0 参考手册 。