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