本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。

本系列描述我对书中内容的理解。本文章描述嵌入式安全性和可靠性模式之五:通道模式。

通道模式 (Channel Pattern) 相较于我们之前讨论过的模式,在规模上更大。通道模式主要用于支持中至大规模的冗余设计,以协助在运行时检测故障的发生,并根据其应用方式,可能在出现此类故障的情况下仍能继续提供服务。

摘要

通道 (channel) 是一种包含从原始数据采集、一系列数据处理、控制执行器全过程的软件(也可能包含硬件)的架构结构。通道的优势在于,它提供了一个独立、自包含的功能单元,可以通过不同的复制方式来应对不同的安全性和可靠性问题。也就是说,通过构建通道,我们可以创建多个相同的处理路径,当某一路径出现故障时,其他路径仍能确保数据处理和系统操作的连续性,从而提升系统的容错能力和整体可靠性。

问题

通道模式 是大规模冗余的基本构建元素,可以以不同方式运用以解决安全性和可靠性问题。

模式结构

模式结构图如下所示:
在这里插入图片描述
上图中所示的 泛化 在 C 语言中可能仅是概念性的,因为在 C 语言中不存在真正的继承机制。其基本思想是,通过一系列 关联 将软件对象组织起来,使数据经历一系列的数据转换步骤,最终得出可以控制一个或多个执行器的输出。在这整个处理过程中,数据类型可以根据具体应用变化(例如,原始数据可能是 double 类型,但经过处理后变成 int 类型输出给执行器),也可能是始终保持同一类型不变。

  • 泛化:UML 中的 泛化 定义了一般元素和特殊元素之间的分类关系;
  • 关联:UML 中的 关联 表示类与类之间的连接,关联关系使一个类知道另外一个类的属性和方法。

有关 UML 的更多基本知识参考我的博文:《C 嵌入式系统设计模式 03:UML 表示法》

模式详情

传感器驱动

从一个或多个传感器获取物理数据,并将其放入通道进行处理。

抽象的数据转换

这是一个概念性示意图。在面向对象的语言或实现中,可以使用真正的泛化(即继承)机制,但在 C 语言中,更多的是作为一个概念性想法来表述意图,而非直接指导实现细节。此类有两个可选 关联

  1. 自身关联:即列表中的下一个转换步骤。这表示有一系列数据转换步骤,前一个转换的输出是下一个转换的输入。

  2. 输出执行器驱动关联:直接指向输出设备驱动。

具体的数据转换

此类负责对输入的数据值(来自传感器或前一个 具体的数据转换类 )执行数学变换,并生成输出结果(发送给序列中的下一个 具体的数据转换类或者 执行器驱动)。在简单情况下,可能只需要单一的 具体的数据转换类,但在更为复杂的应用场景中,可能存在多个不同的具体数据转换类。每一个具体的数据转换类都会对数据进行特定的处理和转换,从而构成整个数据处理通道的核心部分,确保数据在传输过程中逐步转化成适合执行器驱动设备所需的形式,最终驱动物理动作或控制设备行为。

执行器驱动

这个类利用计算出的输出值来驱动一个或多个执行器,例如电动机、灯光或加热装置等。

通过接收并解析从 具体的数据转换类 传来的数据,该类能够对这些数值进行实时控制,将其转化为实际物理操作指令。比如,当接收到调节电机转速的信号时,它会依据该信号控制电机的实际转动速度;对于灯光执行器,则会调整灯光的亮度、颜色或开关状态;而对于加热单元,则会调控其功率输出,进而改变温度设定。这类类通常与硬件交互紧密,是实现系统自动化控制的关键组件。

效果

在简单形式下,通道本身能提供的价值有限,它的真正价值在于使用多个通道实例的组合。通过不同的方式整合通道以及数据转换,可以有效地解决安全性和可靠性问题。

一般来说,采用多通道模式的优点包括:

  • 明确的故障识别机制:通过对比不同通道的数据或状态,能够更容易地发现和定位潜在的系统故障。
  • 提供冗余保障:依赖于特定的通道使用模式,可以设计多个通道作为备份,在主通道失效时继续提供服务,或者确保系统进入一个“故障安全状态”,即使部分组件发生故障,整个系统也能维持在一个相对安全的状态下运行。

然而,采用这种多通道模式也有其固有的缺点:

  • 额外内存消耗:无论是代码空间还是数据存储,都需要为每个额外的通道实例分配资源,随着通道数量的增加,整体内存需求也会相应增长。
  • 处理时间增加:处理来自多个通道的数据,尤其是涉及到数据融合或比较判断时,需要额外的计算资源和处理时间。
  • 硬件成本提升:在硬件层面,为实现冗余和多重通信路径,可能需要更复杂的电路设计或更多的硬件模块,这无疑会增加项目的总体成本。

实现策略

该模式可以通过真正的泛化实现,但在 C 语言等编程环境中,通常会将 抽象的数据转换 视为某种 具体的数据转换 类的占位符;

数据流经通道的方式主要有两种主要策略:

  1. 串行处理:最简单的方法是对获取的一个数据元进行一系列的转换,并在获取下一个数据元之前将其输出到执行器(actuator)。在这种情况下,数据按照顺序逐个经过各个转换阶段。
  2. 并行处理:而在更高带宽的应用场景中,同一时间可能有多个数据实例存在于通道内,对于每一个转换阶段都有一个对应的数据实例。这样,数据从一个转换传递到下一个转换的同时,所有其他的数据实例也都在同步进行传递。这意味着多个数据可以同时在不同的转换环节被处理,提高了系统的吞吐量和实时性。

相关模式

此模式提供了中到大规模的冗余机制,是许多其他模式的基础,包括本章后面将要讨论的 受保护单通道模式同构冗余模式。其他相关的模式还包括 三重模块冗余 (TMR) 模式,其中三个通道并行运行并对结果进行表决;以及 合理性检查(Sanity Check)模式,其中轻量级的第二通道对主通道的合理性进行校验。后面提及的两种模式并不包含在这本书的讨论范围内,若想要深入了解,参阅作者的另一部著作:《Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems》。

实例

见原书。






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐