4、硬件冗余架构(二):非相似余度设计(不同处理器、不同操作系统)、硬件监控与自检测(BIT)

各位同学,咱们接着聊硬件冗余。上一章讲了同构冗余,就是三块一模一样的板子互相投票。这一章咱们聊聊更高级的玩法——非相似余度。说白了,就是故意让几个通道不一样。

你可能会问:这不是给自己找麻烦吗?一样的板子多好维护。嗯,我刚开始也有这个疑问。直到我在项目中亲眼看到一次事故——三块同型号的飞控计算机,因为同一个芯片批次有隐藏缺陷,在高空低温环境下同时失效。飞机差点失控。从那以后,我对非相似余度就格外重视。

4.1 为什么需要非相似余度?

同构冗余有个致命弱点:共因故障。什么意思?就是同一个原因导致所有通道一起挂掉。

  • 同样的处理器,同样的设计缺陷
  • 同样的操作系统,同样的漏洞
  • 同样的编译器,同样的代码生成bug
  • 同样的元器件批次,同样的老化特性

你想想看,如果三个通道用的都是同一款飞思卡尔处理器,那这个处理器一旦有隐藏的浮点运算错误,三个通道会同时算错。三取二表决?三个都错,表决出来还是错的!

核心思想:非相似余度就是让不同通道用不同的处理器、不同的操作系统、甚至不同的编程语言来实现同样的功能。这样,一个通道的故障不会传染给其他通道。

4.2 非相似余度的典型架构

我个人习惯把非相似余度分成三个层级。咱们一个一个来看。

4.2.1 处理器级非相似

这是最基础的做法。两个通道用完全不同的处理器架构。

通道 处理器 架构 特点
通道A PowerPC(如MPC5674) RISC 浮点强,航空级
通道B ARM Cortex-R系列 RISC 实时性好,生态成熟
通道C x86(如Intel Atom) CISC 算力高,兼容性好

我在项目中遇到过这样的情况:PowerPC通道的浮点运算在特定温度下会偶尔出错,但ARM通道完全正常。这就是非相似的价值——同样的算法,不同的硬件实现,错误模式完全不同

4.2.2 操作系统级非相似

光换处理器还不够。操作系统也得换。

  • 通道A:VxWorks 653(分区操作系统,ARINC 653标准)
  • 通道B:Linux with PREEMPT_RT(实时补丁)
  • 通道C:裸机运行(无操作系统,直接跑主循环)

你可能会问:裸机?现在还有人用裸机?

嗯,这里要注意。裸机虽然原始,但它没有操作系统的调度抖动,没有中断延迟的不确定性。在一些极端安全关键的场景下,裸机反而是最可靠的。我见过一个老工程师,坚持在备份通道用裸机,他说:「操作系统越复杂,出鬼的地方越多。」虽然偏激,但有一定道理。

4.2.3 编程语言级非相似

这个层级容易被忽略。不同通道用不同的编程语言实现同样的控制律。

  • 通道A:C语言(手工编码,效率高)
  • 通道B:Ada语言(强类型,安全性高)
  • 通道C:Simulink自动生成代码(模型驱动,可追溯)

为什么要这么折腾?因为编译器也有bug。C编译器、Ada编译器、Simulink代码生成器,它们出错的模式完全不同。三个通道同时因为编译器bug而出错?概率极低。

避坑指南:我曾经在一个项目中,三个通道都用C语言,只是换了不同的编译器。结果GCC和IAR在某个位运算优化上行为不一致,导致三个通道的交叉监控一直报错。排查了整整两周。后来我学乖了——要么用不同语言,要么至少用不同编译器版本。

4.3 非相似余度的交叉监控

非相似余度有个麻烦事:三个通道算出来的结果,不可能完全一样。

为什么?因为浮点精度不同、处理器字长不同、编译器优化不同。你让PowerPC和ARM算同一个PID控制律,结果在小数点后第6位肯定有差异。

所以,交叉监控不能直接比数值。得用容差比较。

// 非相似通道的交叉监控示例
// 通道A(PowerPC)和通道B(ARM)的输出比较

#define TOLERANCE 0.001f  // 容差阈值

bool cross_monitor(float val_a, float val_b) {
    float diff = fabs(val_a - val_b);
    
    if (diff < TOLERANCE) {
        return true;   // 一致
    } else {
        // 记录差异,但不立即判错
        log_difference(val_a, val_b, diff);
        return false;  // 不一致
    }
}

这个容差怎么定?我建议你通过实际飞行数据来标定。在地面跑几百个小时的仿真,统计两个通道的差异分布,然后取3σ作为容差。别拍脑袋定,否则你会被误报搞疯。

4.4 硬件监控与自检测(BIT)

非相似余度再牛,也得知道硬件是不是好的。这就引出了BIT——Built-In Test,内建自检测。

BIT分三种,咱们一个一个说。

4.4.1 上电BIT(PBIT)

飞机上电时执行。主要检查:

  • 处理器能否正常启动
  • 内存读写是否正常
  • Flash校验和是否正确
  • 各接口能否初始化

PBIT通过后,系统才能进入工作模式。如果PBIT失败,直接报「硬件故障」,飞机不能起飞。

4.4.2 周期BIT(CBIT)

系统运行过程中,每个控制周期都执行。主要检查:

  • 看门狗是否正常喂狗
  • 电压、温度是否在范围内
  • 通信链路是否正常
  • 内存是否出现单比特翻转

CBIT不能影响正常控制律的执行。我一般把CBIT放在控制周期的空闲时间里跑,或者用DMA来做,不占用CPU。

4.4.3 维护BIT(MBIT)

飞机在地面维护时执行。这是最全面的检测:

  • 所有传感器通道的精度测试
  • 舵机回路的全行程测试
  • 非易失存储器的全片擦写测试
  • 冗余通道的交叉比对测试

MBIT通常需要外部测试设备配合。我记得有一次,MBIT发现一个舵机的反馈电位计有磨损,在地面就换了。要是飞到天上才发现,后果不堪设想。

重要提醒:BIT的设计原则是「故障检测率要高,虚警率要低」。检测率低了,故障漏掉;虚警率高了,频繁报错,地勤人员会麻木,最后真故障反而被忽略。我见过一个项目,BIT虚警率高达30%,地勤直接把BIT报警线给拔了——这是最危险的做法。

4.5 非相似余度的故障处理策略

当非相似通道出现不一致时,怎么处理?我总结了几种策略:

  1. 多数表决:三个通道,两个一致就采用那个结果。但非相似通道的差异可能让三个结果都不一样。
  2. 优先级表决:给每个通道设定优先级。比如通道A优先级最高,通道B次之,通道C最低。不一致时,以高优先级为准。
  3. 动态权重:根据每个通道的历史可靠性动态调整权重。最近经常出错的通道,权重降低。
  4. 降级运行:如果两个通道都挂了,剩下的一个通道独立运行,但功能降级——比如只保留基本的俯仰和滚转控制,去掉自动配平等高级功能。

我个人比较推荐「动态权重+降级运行」的组合。既灵活又安全。但实现起来确实复杂,需要大量的飞行数据来训练权重模型。

4.6 本章小结

非相似余度,说白了就是「不要把鸡蛋放在同一个篮子里」。处理器不同、操作系统不同、编程语言不同,让共因故障的概率降到最低。

BIT则是给硬件做「体检」。上电体检、周期体检、维护体检,三层体检确保硬件健康。

这两者结合起来,才能构建真正高可靠的飞控系统。我做了十几年飞控,见过太多因为共因故障导致的事故。非相似余度虽然成本高、设计复杂,但跟人命比起来,这些都不算什么。

一句话总结:同构冗余防随机故障,非相似冗余防共因故障。两者缺一不可。

非相似余度架构与BIT检测体系 通道A 处理器:PowerPC 系统:VxWorks 653 语言:C语言 编译器:GCC 通道B 处理器:ARM Cortex-R 系统:Linux RT 语言:Ada 编译器:GNAT 通道C 处理器:x86 Atom 系统:裸机 语言:Simulink生成 编译器:代码生成器 交叉监控(容差比较) 容差阈值:0.001 | 差异记录 | 故障隔离 BIT内建自检测体系 上电BIT (PBIT) 周期BIT (CBIT) 维护BIT (MBIT) 非相似余度 + BIT = 高可靠飞控系统

专注资料整理