我们正在编译一个嵌入式 C++ 应用程序,该应用程序部署在受 电离辐射 轰击的环境中的屏蔽设备中。我们正在为 ARM 使用 GCC 和交叉编译。部署后,我们的应用程序会生成一些错误数据,并且崩溃的频率超出了我们的预期。硬件是为这个环境设计的,我们的应用程序已经在这个平台上运行了好几年。
我们是否可以对代码进行更改,或者可以进行编译时改进以识别/纠正由 单事件干扰 引起的 软错误 和内存损坏?是否有其他开发人员成功地减少了软错误对长时间运行的应用程序的有害影响?
原文由 rook 发布,翻译遵循 CC BY-SA 4.0 许可协议
从事 小型卫星 软件/固件开发和环境测试工作约4-5年*,我想在这里分享我的经验。
*( _小型卫星比大型卫星更容易发生单事件扰动,因为其电子元件的尺寸相对较小且有限_)
现在,这种情况通常在硬件和软件层面都得到处理。在这里,应您的要求,我将分享我们在软件层面可以做些什么。
……恢复目的…… 提供在真实环境中更新/重新编译/重新刷新您的软件/固件的能力。对于高度电离环境中的任何软件/固件来说,这 几乎是必备的 功能。如果没有这个,您 可以 拥有任意数量的冗余软件/硬件,但在某一时刻,它们都会爆炸。所以,准备这个功能!
…最低工作版本… 在您的代码中具有响应式、多副本、最低版本的软件/固件。这就像 Windows 中的安全模式。不要只拥有一个功能齐全的软件版本,而是拥有软件/固件最低版本的多个副本。最小副本的大小通常比完整副本小得多,并且几乎总是 只有 以下两个或三个特征:
…复制…某处… 在某处有冗余软件/固件。
严格来说,如果没有冗余硬件,这样做的缺点是您实际上 无法 消除 所有 单点故障。至少,您仍然会遇到 一个 单点故障,即 _开关本身_(或者通常是代码的开头)。尽管如此,对于在高度电离环境中受尺寸限制的设备(例如微微/毫微微卫星),在 没有 额外硬件的情况下将单点故障减少到一个点仍然值得考虑。此外,用于切换的一段代码肯定会比整个程序的代码少得多——显着降低了其中出现单事件的风险。
但是,如果您不这样做,您的外部系统中应该至少有一个副本,它可以与设备联系并更新软件/固件(在卫星情况下,它又是任务控制中心)。
您还可以将副本保存在设备的永久内存存储中,可以触发该副本以恢复正在运行的系统的软件/固件
…可检测的错误情况。 错误必须是 可检测 的,通常由硬件 纠错/检测电路 或一小段代码进行纠错/检测。最好将此类代码小而多,并 独立 于主要软件/固件。它的主要任务 只是 检查/纠正。如果硬件电路/固件是 _可靠的_(例如它比其余的更耐辐射 - 或具有多个电路/逻辑),那么您可能会考虑使用它进行纠错。但如果不是,最好将其作为错误检测。可以通过外部系统/设备进行校正。对于纠错,您可以考虑使用 Hamming/Golay23 等基本纠错算法,因为它们可以更容易地在电路/软件中实现。但这最终取决于您团队的能力。对于错误检测,通常使用 CRC。
…支持恢复的硬件 现在,谈到这个问题上最困难的方面。最终,恢复需要负责恢复的硬件 至少 可以正常工作。如果硬件永久损坏(通常在其 总电离剂量 达到一定水平后发生),那么(遗憾地)软件无法帮助恢复。因此,对于暴露在高辐射水平的设备(例如卫星)来说,硬件无疑是最重要的问题。
除了上述由于单事件扰动而导致固件错误的建议之外,我还建议您:
子系统间通信协议中的错误检测和/或纠错算法。为了避免从其他系统收到不完整/错误的信号,这是另一个几乎必须具备的
过滤您的 ADC 读数。 不要 直接使用 ADC 读数。通过中值过滤器、均值过滤器或任何其他过滤器对其进行过滤 - 永远不要 相信单个读数值。采样更多,而不是更少 - 合理。