跳转到内容

微处理器设计/实时操作系统

来自维基教科书,开放世界中的开放书籍

实时操作系统

[编辑 | 编辑源代码]

实时操作系统 (RTOS) 是一种多任务操作系统,用于为实时应用程序请求提供服务。它必须能够在数据到来时处理数据,通常没有任何缓冲延迟。RTOS 广泛应用于我们周围的产品中,从军事、消费类到科学应用。RTOS 是许多嵌入式系统中使用的操作系统,因为它在允许实时应用程序更轻松地设计和扩展的同时,还能满足所需的性能要求。

它包含两个组件:“实时”和“操作系统”。“实时”表示操作系统必须在执行的关键操作中以及高可靠性情况下在确定的时间内做出响应。因此,RTOS 是一种支持实时应用程序和嵌入式系统的操作系统,它通过在所需期限内提供逻辑上正确的结果来实现。这些功能定义了其确定性计时行为和有限资源利用率的性质。

实时操作系统的分类

[编辑 | 编辑源代码]

RTOS 通常分为三种类型

  1. 硬实时:对错过截止日期的容忍度极低或为零。错过截止日期会导致系统出现灾难性后果。
  2. 固件实时:错过截止日期可能会导致质量下降无法接受。
  3. 软实时:可以错过截止日期,并且可以从错过截止日期中恢复。系统质量下降是可以接受的。

实时操作系统的特点

[编辑 | 编辑源代码]

一个基本的 RTOS 将具备以下功能

  • 多任务和抢占

RTOS 必须是多任务的和可抢占的,以支持实时应用程序中的多个任务。调度程序应该能够抢占系统中的任何任务,并在峰值负载下将资源分配给最需要它的任务。

  • 任务优先级

抢占定义了识别最需要资源的任务并将其分配给获取资源的控制能力。在 RTOS 中,这种能力是通过为每个任务分配适当的优先级来实现的。

  • 可靠且充足的任务间通信机制

为了使多个任务能够及时通信并确保彼此之间的数据完整性,需要可靠且充足的任务间通信和同步机制。

  • 优先级继承

为了允许实现具有严格优先级要求的应用程序,RTOS 在使用优先级调度时必须具有足够数量的优先级级别。

  • 预定义的短延迟

RTOS 需要对其系统调用的时间有准确的定义。

  • 内存管理控制

为了确保对中断的可预测响应,RTOS 应该提供一种方法让任务将其代码和数据锁定到真实内存中。

实时操作系统架构

[编辑 | 编辑源代码]

实时操作系统的架构取决于其部署的复杂性。优秀的 RTOS 可扩展以满足不同应用程序的不同需求。对于简单的应用程序,RTOS 通常只包含一个内核。对于更复杂的嵌入式系统,RTOS 可以是各种模块的组合,包括内核、网络协议栈和其他组件。

实时操作系统与通用操作系统

[编辑 | 编辑源代码]

许多非实时操作系统也提供类似的内核服务。通用计算操作系统和实时操作系统之间的关键区别在于实时操作系统需要“确定性”计时行为。正式地说,“确定性”计时意味着操作系统服务仅消耗已知且预期的時間。理论上,这些服务时间可以用数学公式表示。这些公式必须是严格的代数公式,不包含任何随机计时组件。服务时间中的随机元素会导致应用程序软件中的随机延迟,进而导致应用程序随机错过实时截止日期——对于实时嵌入式系统来说,这显然是不可接受的场景。

通用计算非实时操作系统通常非常不确定。它们的服務会向应用程序软件注入随机延迟,从而导致应用程序在意外的时间出现响应缓慢。如果你要求非实时操作系统开发人员提供描述其其中一项服务计时行为的代数公式(例如,从一个任务向另一个任务发送消息),你将永远不会得到一个代数公式。相反,非实时操作系统(如 Windows、Unix 或 Linux)的开发人员只会对你感到困惑。确定性计时行为根本不是这些通用计算操作系统的设计目标。

另一方面,实时操作系统通常比基本确定性更进一步。对于大多数内核服务,这些操作系统提供了恒定负载无关的计时。

实时操作系统中的内核

[编辑 | 编辑源代码]
“kernel” – the part of an operating system that provides the most basic services to application software running on a processor.  

实时操作系统 (“RTOS”) 的“内核”提供了一个“抽象层”,它向应用程序软件隐藏了应用程序软件将运行的处理器(或一组处理器)的硬件细节。在提供此“抽象层”时,RTOS 内核向应用程序软件提供了五类基本服务。

  1. 最基本的内核服务类别,位于最中心,是任务管理。
  2. 第二类内核服务是任务间通信与同步。
  3. 许多 RTOS 内核提供动态内存分配服务。
  4. 许多 RTOS 内核还提供“设备 I/O 管理器”类别的服务。
  5. 除了内核服务外,许多 RTOS 还提供许多可选的附加操作系统组件,用于提供文件系统组织、网络通信、网络管理、数据库管理、用户界面图形等高级服务。

任务调度

[编辑 | 编辑源代码]

大多数 RTOS 使用一种名为“基于优先级的抢占式调度”的方案来调度任务。它基本上为每个进程分配一个优先级,如果在任何时间点,调度程序运行准备运行的最高优先级进程。每个进程都运行到完成,除非被抢占。调度程序负责在任务之间进行 CPU 时间共享。每次基于优先级的抢占式调度程序收到来自外部世界的触发器(如开关闭合)或软件触发器(如消息到达)的提醒时,它都必须执行以下 5 个步骤

  1. 确定当前正在运行的任务是否应该继续运行。
  2. 如果不是,确定哪个任务应该接下来运行。
  3. 保存已停止的任务的环境(以便它稍后可以继续运行)。
  4. 设置接下来运行的任务的运行环境。
  5. 允许此任务运行。

这 5 个步骤一起被称为"任务切换"

固定时间任务切换

[编辑 | 编辑源代码]

在评估操作系统时,完成任务切换所需的时间是一个重要的考量因素。一个简单的通用计算(非抢占式)操作系统可能只在计时器滴答的时候进行任务切换,例如每隔十毫秒。因此,如果在 10 毫秒内需要进行任务切换,实际的任务切换将只在当前 10 毫秒周期结束时进行。这种延迟在大多数实时嵌入式系统中是不可接受的。

实际上,"实时"并不意味着 "尽可能快";而意味着 "实时"需要一致、可重复、已知的定时性能。虽然非实时操作系统可能对少量任务执行一些更快的任务切换,但它也可能在下次执行相同任务切换时引入较长的延迟。实时操作系统的优势在于它已知、可重复的定时性能,这通常也比非确定性任务调度器在软件系统中存在大量任务的情况下的性能更快。通常情况下,当任务数量超过 5 或 10 个时,实时操作系统比其非实时竞争对手表现出快得多的任务切换时间。

任务间通信和同步

[编辑 | 编辑源代码]

大多数操作系统,包括 RTOS,都提供各种机制来实现任务之间的通信和同步。这些机制在多个任务的抢占式环境中是必要的,因为没有它们,任务可能会传递错误的信息或以其他方式相互干扰。

例如,一个任务可能在更新数据表的中途被抢占。如果一个抢占它的第二个任务从该表中读取数据,它将读取一部分新更新的数据和一部分尚未更新的数据。这些更新和旧的数据区域组合在一起可能不正确,或者甚至可能没有意义。RTOS 提供的任务间通信和同步机制是为了避免这些类型的错误。大多数 RTOS 提供多种机制,每种机制都针对从任务到任务可靠地传递不同类型的信息进行了优化。嵌入式系统中任务间最常见的通信方式可能是从一个任务传递数据到另一个任务。大多数 RTOS 提供一种消息传递机制来执行此操作。每条消息可以包含一个数据数组或缓冲区。

确定性和高速消息传递

[编辑 | 编辑源代码]

任务间消息通信是不同操作系统表现出不同计时特性的另一个领域。大多数操作系统实际上在通过消息队列从任务传递消息时会复制两次消息。第一次复制是从消息发送任务到操作系统拥有的 RAM 内存 "秘密" 区域,第二次复制是从操作系统 "秘密" RAM 区域到消息接收任务。显然,这在时间上是不确定的,因为这些复制活动随着 消息 长度的增加而花费更长时间。一种避免这种不确定性并加速性能的方法是让操作系统复制消息的指针并将该指针传递给消息接收任务,而不移动消息内容。为了避免访问冲突,操作系统随后需要返回到消息发送任务并删除其对消息指针的副本。对于大型消息,这消除了对冗长复制的需要,并消除了不确定性。

动态内存分配

[编辑 | 编辑源代码]

动态内存分配是指执行程序请求操作系统分配给它一块主内存。程序然后使用这块内存来执行某些操作。服务时间的确定性也是动态分配 RAM 内存领域的一个问题。许多通用计算非实时操作系统提供来自所谓的 "堆" 的内存分配服务。堆会遭受一种称为 "外部内存碎片" 的现象,这会导致堆服务性能下降。外部碎片是指空闲内存被分成小块,并且与分配的内存交织在一起。这是某些存储分配算法的弱点,因为它们未能有效地排序程序使用的内存。结果是,虽然有空闲存储可用,但实际上是不可用的,因为它被分成单个太小而无法满足应用程序要求的碎片。

可以通过 "垃圾收集"(碎片整理)软件解决这种碎片问题。不幸的是,"垃圾收集" 算法通常是极度不确定的 - 在堆服务中注入随机出现的随机持续时间的延迟。这些通常在通用计算非实时操作系统的内存分配服务中看到。

实时操作系统通过完全避免内存碎片和 "垃圾收集" 以及它们带来的后果来解决这种延迟问题。RTOS 提供非碎片内存分配技术,而不是堆。它们通过限制提供给应用程序软件的内存块大小的种类来做到这一点。虽然这种方法不如内存堆的方法灵活,但它们确实避免了外部内存碎片,并避免了对碎片整理的需求。

华夏公益教科书