我们正在编译嵌入式的 C/c + + 应用程序,部署在 bombarded 与电离辐射环境中的屏蔽设备。我们将使用 GCC,ARM 进行交叉编译。部署时,我们的应用程序生成一些错误数据,并更容易崩溃,我们希望。硬件此环境中,为设计和几年来在此平台上运行我们的应用程序。

还有我们可以到我们的代码中或可用于识别/解决软错误和内存损坏由单个事件 upsets引起的编译时改进所做的更改吗?任何其他开发人员有减少长时间运行的应用程序的软错误的有害影响的成功?

2016-04-24 19:09:40
问题评论:

我想说否,软件无法修复硬件故障。每个例程编写以捕捉错误,则会受到失败本身从相同的原因。如果可以将需要昂贵的 ECC 内存没有理由为例。

在内存更改值或处理器更改中的值?如果硬件环境设计,软件应该运行在非放射性环境运行的。

已用软件用在空间中,因此我会查看到另一个位置来查找工作的方法解决这一问题。

您正在使用哪种 MCU?主流的 ARM 是最有可能根本不合适。更好的替代方案是类似 Freescale MPC56,TI TMS570 等。这些具有锁步内核,ECC 和大量的错误检测和冗余硬件实现的。

"软件硬件故障无法修复?"当然可以或为准确起见,它可以弥补它们。奇偶校验、 纠错编码、 (cf.RAID) 的多个拷贝,甚至备份是硬件故障的软件启用的变通办法。

回答:

使用软件/固件开发环境的和测试miniaturized 卫星约 4-5 年工作 *,我愿意分享我在本文中的经验。

*(miniaturized 的卫星将单个事件更容易出现很多 upsets 不是更大的卫星,由于其相对较小,限制其电子组件的大小)

是非常简单而直接︰ 没有任何机制来恢复,从检测、 错误情况由软件/固件本身没有,至少,最低工作版本软件/固件地方出于恢复目的-并与硬件支持恢复一个复制(功能)。

现在,这种情况下通常处理的硬件和软件层中。在这里,根据请求,我将分享如何在软件方面。

  1. ..recovery 目的...提供能够刷新更新/重新编译/软件/固件在真实的环境中。这是高度 ionized 环境中任何软件/固件几乎必须功能。没有它,您可能有冗余的软件/硬件尽可能多为您想要但在一个点上,它们都将以失败。所以,要做好这项功能 !

  2. .......minimum 工作版本具有响应速度快、 多份副本时,您的代码的软件/固件的最低版本。这就像在 Windows 安全模式。不只一个,全功能版本的软件,有的软件/固件的最低版本的多个副本。最小的副本将通常有少得多比完整拷贝和大小几乎总是具有以下两个或三个功能︰

    1. 能够从外部系统,听命令
    2. 能够更新当前软件/固件,
    3. 监视的基本操作的内务处理数据的能力。
  3. ......复制地方...某处有冗余的软件/固件。

    1. 您可以不冗余硬件的情况下,尝试在 ARM uC 具有冗余软件/固件。通常这是通过让两个或多个完全相同的软件/固件在单独的地址的发送彼此的心跳,但每次只有一个将成为活动。如果一个或多个软件/固件已知反应迟钝,切换到其他软件/固件。使用这种方法的优点是我们可以根据功能上可以取代立即发生错误-没有与任何外部系统/当事方都有责任来检测和修复该错误的任何联系 (在附属的情况下,它通常是任务控制中心 (MCC))。

      [编辑]我响应Mehrdad注释中所示︰严格地讲,没有冗余硬件,这样做的缺点是您实际上不能消除所有单点故障。最起码,您仍然可以一个单点故障,交换机本身(或通常的代码的开头)。不过,对于有限 (例如 pico/femto 卫星) 的高度 ionized 环境中大小设备,减少到一个点而无需额外的硬件故障的单点仍将值得考虑。Somemore,用于切换代码段的当然是整个程序的显著降低中获取单个事件的风险的代码比少得多。

    2. 但如果您不这样做,您应可接触的设备和软件/固件更新您外部系统中有至少一个副本 (在附属的情况下,它是再次的任务控制中心)。

    3. 您也可以让副本中永久存储器存储在设备中可以触发恢复运行的系统软件/固件
  4. ..detectable 错误情况.错误必须检测,通常通过硬件错误纠正/检测电路或一小段代码错误更正/检测。最好将这些代码放入小,多个,并独立于主软件/固件。其主要任务是检查纠正。如果硬件电路/固件是可靠的 (例如,它是更多的辐射比其余的强化或有多个电路/logics),然后您可能会考虑进行纠错与它。但如果不是,它是更好一些,使其作为错误检测。通过外部的系统设备,可以更正。错误更正,您可以考虑制定 Hamming/Golay23,像一个基本错误校正算法的使用,因为它们可以更容易地实现电路软件中的两个。但这最终取决于您的团队的能力。错误检测时,正常情况下 CRC 用于。

  5. .支持恢复.hardware在此问题上,现在,进入最困难的方面。从根本上讲,恢复需要负责恢复应至少起作用的硬件。如果硬件被永久破坏 (通常发生后其电离性的总剂量达到一定级别),然后 (沮丧) 没有软件来帮助恢复的方法。因此,硬件都是暴露在高辐射级别 (例如卫星) 设备的至关重要的因素问题。[编辑]冗余硬件非常重要,对于阅读的评论。

除了上述预测由于单个事件不稳定的固件错误的建议,我想建议您可以︰

  1. 错误检测和/或子系统间的通信协议中的错误校正算法。这是另一种几乎必须具有才能避免从其他系统收到的不完整或损坏信号
  2. 在您阅读的 ADC 进行筛选。不要使用 ADC直接读取。经中间筛选器对其进行筛选,筛选器,或任何其他筛选器-永远不会信任一个读取值。示例的详细信息,不减的理由。

+ 1,但没有迷惑了我的一件事。您说: "如果一个或多个软件/公司已知反应迟钝,切换到其他软件/固件。"但是谁完全应当如何切换?不管它有,不是静止的单点故障吗?

@Mehrdad 在我们的应用程序,我们有多余的微控制器和冗余银行每微控制器。因此,发生了两个微控制器将会运行的但是一个稍微以后运行。这是确定是否实际运行的第一个微控制器。这两种微控制器有个别以及共享内存。UC 的任何运行时,它会更新共享的内存,这样其他 uC 知道将自身定位为备份。冗余的银行用来存储程序的用于恢复的精确副本。但那里了点...(继续)

@Mehrdad 较佳,因为我们支持冗余的微控制器外部的共享的内存 (作为消息相互"信箱") 谈到彼此,运行我们的应用程序。实际上它并没有出现这种情况,(即,当我们只有单个微控制器,但代码的多个副本) 可能需要在微控制器的监视程序计时器重置的微控制器,并从一开始,测试如果它可以运行的第一个副本,并决定是否需要使用第二个副本。但在这种情况下,一旦第一个副本给出错误结果,它将是单点故障

也就是说,单个微控制器中的多个银行可以减少了单点故障,但是,由于最终没有唯一一个使用,有的 uC 是仍然单点故障在地方 (在这种情况下在一开始的一开始) @Mehrdad

@Mehrdad 啊是的您是绝对正确。假设没有冗余硬件,则始终,在某处,某种程度上,单点故障。在我们的系统会发生什么情况是,即使共享的内存也是多余 (我们有三个,但是,如果使用轮询系统以确定正确的读取)。;) 在此处底线实际上是硬件。如果我们有多余的硬件-采用冗弱电源系统中,然后我们可以有完全分离系统。但只有当存在冗余的硬件系统。

NASA 已上放射检验纸张软件。它描述了三个主要任务︰

  1. 定期监视内存的错误,然后清理掉那些错误,
  2. 可靠的错误恢复机制,和
  3. 能够重新配置如果不能再工作。

请注意,内存扫描速率应频繁的多比特的错误很少发生,因为大多数ECC内存可以从单个位错误,多比特错误中的恢复。

可靠的错误恢复包括 (通常重新启动之前错误的点处的进程) 的控制流转移、 资源发布和数据恢复。

对于数据恢复其主要建议是为了避免它,需要通过中间数据视为为临时性的以便在重新启动之前错误也会回退数据到可靠的状态。这听起来类似于数据库中的"交易记录"的概念。

他们讨论技术尤其适合于如 c + + 面向对象的语言。例如

  1. 基于软件的 ECCs 连续内存对象
  2. 按合同编程︰ 验证前置条件和后置条件,则检查要验证的对象是仍处于有效状态。

这实际上听起来这语言可以很好地进行。因为永远不会更改值后,如果它们已损坏您可以只需返回到原始定义 (它是什么它应该),并且您不会意外地执行相同的操作两次 (由于缺乏副作用)。

RAII 是坏事,因为您不能依赖于其正常或甚至完全执行。它随机可能损坏您的数据等。您真的想您能获得的尽可能不变性和错误更正机制之上的。它是更加容易,只需丢弃损坏的东西比尝试并修复它们以某种方式 (究竟如何知道足以回到正确的旧状态?)。可能想要使用愚蠢而不是语言,尽管-超过它们帮助优化可能会造成损害。

谢谢。已删除的 RIAA。

@PyRulez︰ 纯语言是一种抽象、 硬件不纯。编译器,这是非常很好地隐藏的区别。如果您的程序具有它逻辑上不应再后使用步骤 X 值,编译器可能会覆盖其计算步骤 X + 1 中的值。但这意味着不能返回。更正式地说,可能的规定纯语言形式的程序向非循环图,这意味着两种状态是等效的会同时从可访问状态是等效的。此合并会破坏路径通向这些状态的差异。

由于某种原因我感觉这些都导致后到观看原始位代码。一旦您有一组数字,所有您需要做是确保它们不会更改特定分区中。然后只需重新模式数字,如果它们移动或消失。其他分区用于数据存储等。

以下是一些想法和建议︰

更有创意地使用 ROM。

任何可以存储在 ROM 中。而不是计算的事情时,存储在 ROM 中查找表 (请确保您的编译器输出为只读部分中查找表 !打印出在运行时检查内存地址 !)将您的中断向量表存储在 ROM 中。当然,运行某些测试,以确定可靠性如何您的 ROM ram 进行比较。

堆栈用于最佳 RAM。

SEUs 堆栈中的可能是最容易受到的崩溃,因为它是,比如索引变量、 状态变量、 返回地址和指针的各种端口的通常活动。

实现计时器嘀嗒信号和监视程序计时器例程。

您可以运行"健全检查"例程,每个计时器开始计时,以及要处理锁定系统的监视程序例程。主代码可能还会定期自动增加的计数器,以指示进度,并健全性检查例程可确保这发生了。

在软件中实现错误纠正代码

您能够检测和/或更正错误的数据,您可以添加冗余。这将可能使处理器暴露于辐射的时间更长,从而提高错误的可能性,因此必须考虑权衡的处理时间。

请记住缓存。

请检查您的 CPU 高速缓存的大小。您具有访问或修改的数据最近多半还会在高速缓存内。我认为至少可以禁用某些缓存 (最大性能成本);您应尝试此事件可查看缓存是如何易受 SEUs。Hardier 比内存缓存是否可以定期读取和重写关键数据,以确保它保持在高速缓存中然后将 RAM 带回行。

巧妙使用页面错误处理程序。

如果标记为不存在的内存页面,CPU 将发出页面错误,当您尝试访问它时。您可以创建页面错误处理程序不为读的请求提供服务之前一些检查。(PC 操作系统用于透明地加载已交换的页面存盘。)

对重要的事情 (这可能是一切) 使用汇编语言。

与程序集语言中,知道什么是在寄存器和什么是在 RAM 中;知道使用何种特殊的内存表 CPU,而您可以设计以迂回的方式降低风险的事情。

使用objdump实际看一下生成的程序集语言,并计算出每个例程占用了多少代码。

如果您正在使用一个大像 Linux 操作系统,然后您想问的问题;没有太多的复杂性和很多了,错误。

请记住这是一个游戏的概率。

注释者说

每个例程编写以捕捉错误,则会受到失败本身从相同的原因。

虽然是这样,(比如) 100 字节的代码和数据所需的检查例程函数中的错误的机会正确是比其他地方出错的可能性小得多。如果您的 ROM 是非常可靠,几乎所有代码/数据都是实际 ROM 中可能性则更好。

使用冗余硬件。

使用相同的代码使用两个或更多相同的硬件设置。如果结果不同,应触发重置。具有三个或更多设备可以使用的"投票"的系统来识别哪一种,已遭到破坏。

如今,没有可通过硬件,从而节省了处理时间的 ECC。第一步就是挑选具有内置的 ECC 的微控制器。

某处后面我看来是对其中的冗余体系结构明确可不相同 avionics (可能是航天飞机?) 飞行硬件 (和由不同的团队) 的引用。这样可减轻减少的所有投票系统同时崩溃的可能性的硬件/软件设计中的系统错误的可能性时面临着相同的输入时间。

@PeterM: AFAIK,还声明为 Boeing 777 飞行软件︰ 通过这三种编程语言中的三个小组的三个版本。

@DanEsparza 内存通常具有电容器 (DRAM) 或几个晶体管中存储数据的反馈 (SRAM)。一个放射事件可以错误充电/放电电容,或更改反馈循环中的信号。ROM 通常不需要写入的能力 (至少没有特殊情况下和/或较高电压),因此可能本质上更稳定在物理级别。

@DanEsparza︰ 有多个类型的 ROM 的记忆库。如果"ROM"模拟方法即 eeprom 或闪存 readonly 在 5v 但-可编程-在-10v,然后实际上该"ROM"则仍然易于受到电离。也许只需不到其他人。但是,有好家伙坚定等掩码 ROM基于保险丝的 PROM我认为需要大量真正严重的辐射开始出现故障。但是我不知道如果那里仍会生产。

您也可以对感兴趣算法容错能力的主题丰富的宣传资料。这包括旧作业︰ 写排序正确对其输入进行排序时固定数目的比较将会失败 (或,稍有更邪恶的版本中,当 asymptotic 的失败次数比较随log(n) n比较)。

开始读取的位置是 Huang 和当年的 1984年纸张"的矩阵操作算法基于容错能力"。他们的想法是有一个大致类似于 homomorphic 的加密计算 (但它并不是相同的因为他们正试图在操作级别的错误检测/纠正)。

最近该纸张的后代是 Bosilca、 Delmas、 Dongarra 和 Langou 的"应用于高性能计算的算法基于容错能力".

我的确很喜欢您的响应。这是数据完整性,更通用软件的做法,我们最终产品中将使用一种算法基于的故障容错解决方案。谢谢 !

为放射性环境编写代码不是真的任何不同于任何任务关键型应用程序编写代码。

除了已经提到什么,下面是一些其他提示︰

  • 使用日常"面包和黄油"安全措施,应该存在于任何一知半解的嵌入式系统︰ 内部的监视程序,内部低电压检测、 内部时钟显示器。这些事情甚至不需要提及 2016 年,它们是几乎每个现代微控制器的标准。
  • 如果您有一个安全和/或面向汽车的 MCU,它会监视程序的某些功能,如给定的时间窗口中,您需要刷新监视程序内的。如果您有一个关键的实时系统,这是首选。
  • 一般情况下,使用适合于这些类型的系统,以及玉米涂漆的数据包在收到不一般主流废话 MCU。如今几乎每个 MCU 制造商拥有专用 Mcu (TI、 Freescale,瑞萨公司、 ST 等 Infineon 等) 的安全应用程序的设计。这些已经有很多内置的安全功能,包括锁步内核︰ 即有 2 CPU 内核执行相同的代码,他们必须相互一致。
  • 重要说明︰ 您必须确保内部 MCU 寄存器的完整性。都是可写的硬件外围设备的所有控制和状态寄存器可能位于 RAM 内存,因此容易受到攻击。

    保护自己免受寄存器损坏,最好是选择使用内置微控制器"写入-一旦"寄存器的功能。此外,您需要将所有硬件寄存器的默认值存储在 NVM 和复制下这些值在收银机到定期。您可以以同样的方式确保完整性的重要变量。

    注意︰ 始终使用防御性编程。您需要设置所有的含义 MCU 和而不仅仅是由应用程序中注册。您不希望某些随机硬件外围突然唤醒。

  • 有各种各样的方法来检查 NVM 或内存中的错误︰ 校验和、"行走模式",软件 ECC 等等等等。如今,最佳解决方案是不使用任何一种,而是使用 MCU 与内置 ECC 和类似的检查。由于在软件中进行这种操作复杂,并且错误和意外的问题,因此会导致本身的错误检查。

  • 使用冗余。在两个完全相同的"镜像"段,必须始终是相同的则可以存储易失性和非易失性内存。每个段可能有附加的 CRC 校验和。
  • 避免使用外部 MCU 外部记忆库。
  • 实现默认中断服务例程/默认值的所有可能的中断/异常的异常处理程序。甚至没有使用。默认例程应执行任何操作除关闭自己中断源。
  • 理解和接纳的防御性编程的概念。这意味着您的程序需要处理所有可能的情况,甚至那些在理论上不能出现。示例.

    高质量关键固件检测,尽可能的多个错误,然后安全地忽略它们。

  • 未正确指定行为所依赖的永远不会写的程序。很可能这种行为可能巨大变化与放射或电磁干扰引起的意外的硬件更改。确保您的程序是受这种至极的最好办法是使用静态 analyser 工具以及类似 MISRA,编码标准。这还将有助于与防御性编程和定时出 bug (为什么不要检测任何类型的应用程序中的 bug?)。
  • 重要提示︰ 不实施任何依赖的静态存储持续时间变量的默认值。也就是说,不相信.data.bss的默认内容。可能有任意数量的初始化实际使用该变量的点到点之间的时间,有可能已经出充足的时间受到损坏的内存。相反,编写程序,以使所有此类变量设置 NVM 从中运行时前第一次使用此类变量时的时间。

    在实践中这意味着,如果在文件范围内或作为static声明一个变量、 永远不应该使用=对其进行初始化 (或者还可以但是毫无意义的因为您不能依赖于值呢)。始终设置在运行时,只需在使用前。如果它是可能重复更新 NVM 的此类变量,然后做到。

    同样在 c + +,不依赖于静态存储持续时间变量的构造函数。已调用公共"设置"例程,它还可以调用在以后运行时,在直接从调用方应用程序 constructor(s)。

    如有可能,"复制下"启动代码该初始化.data.bss (和 c + + 构造函数的调用) 完全删除,以便您收到链接器错误消息,如果您编写的代码依赖于此类。许多编译器可以选择跳过此操作,通常称为"最小/快速启动"或类似。

    这意味着,任何外部库必须进行检查,以便它们不包含任何此类的依赖。

  • 实现并定义的安全状态的程序,您将恢复在发生严重错误时。

  • 实现错误报告/错误日志系统始终是有帮助的。
请输入您的翻译

Compiling an application for use in highly radioactive environments

确认取消