9

为嵌入式设备升级软件通常有可能使设备“变砖”,例如,如果在将软件写入 FLASH 的过程中发生电源故障。两个问题:

  1. 有哪些实施升级机制的最佳实践,以尽量减少设备“变砖”的可能性?
  2. 有哪些最佳实践可以使升级过程安全可靠,以便在将软件安装到 FLASH 时发生电源故障等事件可以从中恢复?
4

9 回答 9

11

这完全取决于应用程序的重要性。两种基本方法(备份和引导加载程序)有时也会结合使用。

许多系统都有一个只读引导加载程序(如redboot),然后是两组闪存(通常在同一芯片上)。然后引导加载程序有一个标志来选择从哪个银行引导。然后标志将根据升级(失败或成功)等事件发生变化。

因此,在升级时,正在运行的版本会将新负载复制到备份库中,检查校验和,切换启动标志,然后重新启动设备。设备在新的银行上重新启动,并带有新的负载。重新启动后,新负载可以将自身复制到备份库中。

通常还有一个带有硬件复位的看门狗定时器。这样,如果固件变得异常,它无法启动看门狗,硬件重置将重新启动设备,引导加载程序将寻找正常的负载。

Open Mesh 项目就是这种方法的一个很好的例子。

于 2009-05-18T12:51:00.657 回答
4

进一步来说...

将替换映像下载到内存区域,而不会覆盖任何当前程序空间。等到下载完成,然后计算和比较 CRC。

如果空间确实是个问题,您可以执行“默认备份”又名“恢复模式”之类的事情,但不破坏性地执行此操作要巧妙得多。

如果你真的很聪明……你可以对 FLASH 进行一次写入更新,以指导设备从新的代码位置启动。这将在两个完全独立的代码段之间进行 ping/pong。这是您可以执行此操作的最安全方法:

  • 总是有一个不可更新的恢复引导加载程序(Nano-loader),如果一切都出错了,它可以被通知以某种方式加载新代码。
  • 两个独立的程序空间
  • 每个程序空间都有一个“CRC”字段、一个“烧录编号”(高于其他代码页的编号)和一个“无效”字(所有 F - 不需要擦除即可更新“无效”标记)
  • 下载完成后,验证 CRC。如果好的话,在旧版本的程序空间上刻录“无效”标记。
  • Nano-loader 检查“无效”标记以了解引导到哪个。如果它们都有效,请进行 CRC 检查。如果它们仍然有效,则采用较高的烧伤编号条目

哦,当人们说校验和时......不要“检查总和”......做一个正确的CRC。

于 2009-05-18T13:08:35.427 回答
2

内部闪存上的校验和,如果 CRC/校验和不起作用,则使用默认备份。这样,如果设备得到不正确的校验和,则它知道升级不完整,并且可以重置为存储在另一台设备上的默认/以前的固件。

这需要一些预引导(可能在引导加载程序中)来检查校验和。一段静态代码。

编辑:进一步评论其他地方。如果您想检查错误的固件,而不仅仅是损坏的固件,您的校验和/校验数据也可以封装版本信息(以及对该标头的检查)我认为 Linksys 路由器会这样做,这可能会使它们在使用自定义固件重新刷新时出现问题。

于 2009-05-18T12:38:07.797 回答
2

校验和很好,但只能让您免于刷新损坏的数据。如果您在具有有效校验和但针对不同产品型号的图像文件中闪存怎么办。在紧急损坏的情况下可以访问的只读默认引导加载程序是我见过的最好的东西。

于 2009-05-18T12:43:14.543 回答
2
  1. 无论如何都要在内存中保留一个只读引导加载程序
  2. 在引导加载程序中,允许从可用输入源(SD 卡、RS232 等)重新加载新程序存储器的故障保护方法(例如,在重启期间按住按钮 X)。
于 2009-05-18T13:10:31.400 回答
2

要回答这两个问题,并且无论任何特定的硬件资源如何:

  • 确保在运行任何应用程序代码之前(在启动时或下载完成后),引导加载程序对应用程序进行 CRC 检查。如果它无效,则引导加载程序不会运行代码。

  • 如果引导加载程序决定它不能运行应用程序代码,它必须能够向用户发出信号,并重新开始下载。

如果处理器没有足够的闪存来存储备份应用程序,或者在完成下载之前没有足够的 RAM 来存储新的应用程序,那么这些显然变得更加重要。

在这些情况下,下载的文件有一个小标题是有意义的,它允许引导加载程序确定文件是否适合系统。该标头也可以具有 CRC。如果标头对该系统有效,并且 CRC 正确,则引导加载程序可以擦除闪存(但不是自身!),并继续下载。如果不是,它会在不触及现有应用程序代码的情况下中止。

于 2009-05-18T19:13:29.683 回答
2

根据我的经验,这取决于你的成本点,如果你能负担得起设备上两倍的代码/数据空间,并且可以重新启动,它很简单,将新版本存储在你所有额外的空间中,做正确的事对新图像进行校验和检查,我还建议对新固件映像进行更深入的检查,因为如果不这样做,它可能会被欺骗,例如某种加密密钥可以保证新图像的来源。您也可以使用外部存储器来执行此操作,例如在一个使用 PIC 的项目中,我有一个用于新固件映像的外部 EEPROM 和一个标志,如果在启动时设置该标志,它将从 EEPROM 加载一个新图像。

如果你不是那么幸运,即你买不起那个空间,那么生活会变得更加有趣,并且可能没有保证的方法可以完全避免更新期间失败的机会。在所有情况下,引导加载程序都应该在一个写保护的内存中,如果你能负担得起空间,应该有一些基本形式的外部连接,我已经完成了引导加载程序中带有非常简单的 USB 驱动程序的系统和带有非常简单的 UDP 的系统只有网络堆栈。如果更新期间出现故障,这两种方法都可以让您至少对设备有一个新的想象。在这些情况下,我强烈建议将引导加载程序放在只读内存区域中,您将失去更新它的能力,但乱线更新也不会让您拥有一个完全变砖的设备。

最后一种可能性是系统需要在运行时更新其代码的某些部分……这真的很棘手,通常需要对内存中函数的位置进行复杂的控制,并在内存布局中提前进行重大规划才能实现。它不是很有趣,但它是可行的。

于 2009-05-20T20:08:51.220 回答
1

我知道这个问题已经得到解答,但有些人需要更高的可靠性。如果你的项目真的是关键任务,你可以走这条路。

基本计划是始终有一个不会失败的备份计划。

  1. 有 PIC 或其他可以对真实处理器的闪存进行编程的微控制器。你让它在一个数据块上使用校验和,并通过串口、usb甚至以太网接口(别笑这并不难)这个设备不能在现场重新编程(或者甚至永远)所以你总是有备用计划。PIC 可以通过 PPP/SLIP 或 ehternet 运行 Web 服务器,因此与它的接口并不一定很尴尬。谷歌 TCP 精益。尽量不要偷笑。(现场 适合工作)将编程端口放在其他地方。不保证安全。

  2. 该程序在主 CPU 上运行并运行它自己的引导加载程序。您拥有三个程序:引导加载程序、维护程序和真实程序。

这允许升级引导引导进程以及程序。您可以在一些额外的闪存中运行备份引导加载程序,使用看门狗重置您并在不引导时使用备份。

因此,您拥有可升级的嵌入式应用程序、可升级的引导加载程序和可升级的维护模式。以及不会失败的备份模式。

希望没有人需要发现这很有用。

于 2009-12-01T05:43:38.737 回答
0

在一些实验室(而不是消费类)设备上,我见过用编程器电路构建的电路板。在最坏的情况下,您可以打开机箱,插入编程器并重新加载默认软件——或将其发回让您执行相同操作。'当然,这需要真金白银。

我的一些项目中使用的一些定制板具有可替换的 ROM。这更便宜,但不太方便。

于 2009-05-18T14:57:24.570 回答