物联网实时操作系统1RTOS简介(上)

RTOS简介

1.1 背景

在大型计算机的世界里,操作系统(OS operating systems)已经存在了相当长的一段时间。最基本的操作系统可以追溯到20世纪50年代。到20世纪70年代中期,操作系统的概念、结构、功能和界面已经非常成熟。

微型系统大约在 1970年出现。在基于微处理器的设备中迅速应用操作系统似乎是合乎逻辑的。然而到直到20世纪80年代中期,几乎没有任何此类应用采用了可称为正式设计的实时操作系统。诚然,CP/M 于 1975年发布,后来由英特尔公司投入芯片。但它对实时领域的影响甚微;它的天然归宿是台式机。

有两个因素影响了实时操作系统的普及,一是机器的限制,另一个是围绕微型机的设计文化。早期的微型机在计算能力、运行速度和内存容量方面都相当有限。试图在此基础上建立操作系统结构是相当困难的。此外,大多数嵌入式系统编程人员几乎没有操作系统方面的背景知识。

如今,情况大为不同。现代嵌入式设计的主力是 16/32位复杂微控制器。这些微控制器成本低、性能高,集成了大量片上存储器和外设功能。市场上还有许多商用实时操作系统。但是,能做什么并不意味着就应该做什么,究竟为什么要在下一次设计中选择使用 RTOS呢?首先,我们需要考虑更基本的问题:我们应该如何解决嵌入式系统中的软件设计问题。这就是本章的重点。它为实用的设计技术奠定了基础,并确切地说明了 RTOS 如何与之相匹配。

1.2 生产高质量的软件

乍一看,本章一开始就谈软件质量似乎有些奇怪。这似乎与操作系统关系不大。事实上并非如此,我们可以从中学到一些宝贵的经验。

如果让你定义 "高质量 "软件的含义,你会怎么说?怎么样?

  • 正确地完成工作("功能 "正确性)。
  • 正确的时间完成任务("时间 "正确性)。
  • 行为应该是可预测的。
  • 行为应该是一致的。
  • 代码不应难以维护(低复杂性)。
  • 代码的正确性可以分析(静态分析)。
  • 代码行为可分析(覆盖率分析)。
  • 运行时性能应可预测。
  • 内存需求应可预测。
  • 如果需要,可以证明代码符合相关标准。

当然,您也可以根据自己的特殊要求对上述原则进行扩展。

请考虑将这些原则应用到下面这个相对简单的小型实时系统中。

这里的要求是通过改变液体流速来控制液体温度。具体做法如下

  • 使用温度传感器测量液体温度。
  • 将其与所需的温度值进行比较,然后
  • 生成控制信号,以设定控制冷却剂流量的执行器的位置。

软件必须执行

  • 数据采集
  • 信号线性化和缩放
  • 控制计算
  • 执行器驱动。

这是核反应堆控制系统中的安全关键 SIL 4(安全完整性等级Safety Integrity Leve 4)子系统。因此,禁止使用中断。

没有唯一的代码解决方案,但会采用以下形式:

我们所看到的是一个 "应用级"代码示例,在这里是一个单独的顺序程序单元。还请注意,低层次的细节并不为我们所知。

底层操作主要涉及系统硬件和相关活动。即使使用高级语言,程序员也必须具备机器硬件和功能方面的专业知识。这就凸显了与传统微机编程相关的问题:实现良好设计所需的硬件/软件专业知识。即使是这个简单的例子,程序员也需要相当程度的硬件和软件技能。

1.3 软件建模

制作运行程序有几个不同的阶段。

首先是软件设计,形成设计或逻辑模型。然后以源代码的形式实现,即物理模型。源代码经过编译、链接和定位("构建")后得到目标代码,即部署模型。最后,将目标代码加载到处理器上并执行,这就是运行时模型。请注意,在许多现代集成开发环境(IDE)中,编译和下载都是作为一项活动来处理的。

在这里,我们主要关注的是代码和运行时模型。我们暂时将设计模型放在一边,集中精力处理其他两个模型。

如果使用现代工具集,开发和处理这些工作非常简单。然而,无法自动化的是将源代码结构分配到源代码组件。程序员需要做出这些关键决定,我们将在处理设计模型时再次讨论这个话题。

代码模型为我们提供了软件的静态视图。相比之下,运行时模型是代码、数据和处理器的组合。它被定义为一个软件流程,在嵌入式领域也被称为任务(这一术语存在争议,稍后会有更多论述)。简单地说,一个任务代表一个顺序程序的执行。

我们暂且将运行时模型称为任务模型。

代码模型的更改可能(通常会)影响任务分配模型。因此,开发人员必须充分理解并记录它们之间的关系。

1.4 时间和定时的重要性

三代飞机有一个三轴自动稳定系统。从根本上说,现实世界中需要完成的工作是相同的

每种飞机所采用的技术却大相径庭。基于微处理器的系统与其他两种系统的本质区别在于:离散操作与连续操作。

在连续("模拟")电子系统中,如果需要,所有操作都可以同时进行("并发")。不仅如此,处理过程也是瞬时完成的。但这在以处理器为基础的系统中是不可能实现的,因为这些系统从根本上说是离散运行的:

  • 处理器一次只能做一件事(顺序机器),而且
  • 操作需要时间--事情不会立即发生。

这两个因素让我们在设计工作中倍感焦虑。因此,如果您在不了解系统时序需求的情况下就开始开发,那么您就要做好准备,迎接令人讨厌的意外。

有鉴于此,让我们重温一下之前的设计练习,可以看出任务代码

  • 以连续循环的方式执行。
  • 在每个循环中完成工作("run-to-completion"语义)。
  • 有完成工作的截止日期 (Td)。
  • 完成工作需要时间(任务执行时间 - Te task execution time)。
  • 以固定间隔或周期重复("周期性 "运行 - Tp periodic)。
  • 在空闲期间不做任何事情(空闲时间 Ts spare)。
  • 需要定时机制来控制周期时间(这里我们最有可能使用硬件定时器来跟踪)。

在这个特殊的设计中,Tp和Td是系统要求,Te取决于我们的代码解决方案,而Ts则是我们最终得到的结果。例如,假设Tp为100毫秒,Te为5毫秒,则 Ts值为95毫秒。由此可见,处理器每100毫秒执行代码 5毫秒,利用率(U Utilization)为 5%。

这些数字对设计有何影响?首先,在嵌入式系统中,任务在每次启动时都要运行到完成点。其次实用的系统必须有一些空闲时间。第三,代码能在一段时间内执行并不意味着其性能是可以接受的。输入到输出的处理延迟("延迟" latency)可能会导致整个系统的行为出现问题。

参考资料

1.5 处理多个工作

上例中的代码结构可以让我们构建出最好的软件。但是,如图所示,它只包含一个程序单元中的一个定义明确的作业。那么,这种方法的扩展性如何呢?例如,在处理多个作业时,是否有可能达到单作业设计的质量?这取决于具体情况,我们很快就会看到。

假设我们被要求为基于微处理器的双轴摇摄和俯仰摄像机稳定器系统制作软件。因此,总体工作或功能 "稳定图像 "由两个子工作组成:

假设各轴的时序要求如下:

  • 摇镜头:25赫兹采样率(每秒25次,Tp=40毫秒)。
  • 倾斜50Hz采样率(Tp=20ms)。

现在我们不仅要运行代码单元,还要以不同的速率运行它们。这就需要一些总体协调软件:一种执行控制 "引擎"。

每个代码单元都以 C 语言函数的形式实现,例如

  • 代码单元 1(函数 1):RunPanStabilizer();

  • 代码单元 2(函数 2):RunTiltStabilizer();

请注意,这样写是为了清晰,而不是为了提高效率。

我们在这里看到的是合理设计方法的基础。然而,它仍然只是基础,有很大的缺陷。

热门相关:洪荒二郎传   戏精老公今天作死没   金粉   上神来了   金粉