如何使用只能逐块擦除的闪存进行增量更新?
简单的答案是肯定的 - 如果您想要高可靠性,您需要足够的闪存块来支持引导加载程序和 A/B 代码映像。在激活新映像之前,您可以编写整个内容、验证它并可能重试。
然而,这是一种昂贵/可靠的策略,您可以采取一些措施来减少开销。对 OTA 更新的低级支持也可能作为设备固件或操作系统的一部分,因此除非您想学习,否则您可以避免自己动手。此功能可描述为FOTA
。
对代码库进行分区允许增量更新,最好的情况是引导加载程序能够启动网络连接、下载和验证代码,而无需任何后备用户代码。使用本地网关,可以从低成本端点委派此任务的管理。
许多设备都有少量的字擦除闪存,即使失败了,您通常也可以设置位而无需擦除整个块。这些功能可用于操作跳转表并将以块大小块更新的代码拼接在一起。即使您最初计划使用完整的 A/B 代码空间,当代码库增长太多时,您可能需要退回到更复杂的方案。
为了阐明可以通过复杂的无线固件解决方案实现的功能,引导加载程序和潜在的主要通信堆栈可以保持驻留,同时重新刷新完整的剩余用户应用程序空间。这不需要任何开销(特别是如果块分区是软的)。在通信栈需要升级的场景下,下载验证时可以临时使用一般用于应用代码的区域。实现这一点需要 SoC 中的一些支持,但考虑到这一点而设计的第 2 代和第 3 代设备确实已经存在。
我想尽可能减少刷机的需要,并尽可能减少设备完全变砖的风险。无线闪存微控制器时是否有现有策略?
除了执行相对静态的更新的代码之外,您还需要在存储中保留两个图像:一个活动图像和一个备份图像。每当您需要更新时,请在备份中进行更新,然后将其切换为活动状态。稳定后,更新旧的活动映像,它现在应该是您的备份。
考虑到这一点,您可以在更新两个图像时使用磨损均衡算法。此类算法的代码可能占用总存储量的 10-15% 左右,但在延长设备寿命方面非常值得。
磨损均衡通常由闪存控制器管理,它使用磨损均衡算法来确定每次对数据进行编程时使用哪个物理块。固态硬盘 (SSD) 磨损均衡有两种类型:动态和静态。动态磨损均衡池擦除块并为下一次写入选择具有最低擦除计数的块。
另一方面,静态磨损均衡选择具有最低总擦除计数的目标块,必要时擦除该块,将新数据写入该块,并确保当静态数据块的块擦除计数低于一定的门槛。由于闪存控制器的开销,移动数据的这一额外步骤会降低写入性能,但静态磨损均衡比动态磨损均衡更有效,可延长固态设备的使用寿命。
飞思卡尔半导体为其 Kinetis 微控制器描述了一种强大的无线固件升级方法。
它被称为:程序闪存交换。
使用闪存交换的系统
在具有两个或更多支持交换的内部闪存块的设备中,每个闪存块的内存基址可以交换。因此,每个闪存块的地址位置将在设备的逻辑存储器映射中交换。复位后,内置闪存交换系统本质上是通过闪存块在逻辑存储器映射中的位置来选择执行哪个软件。这使得代码备份系统更加易于编程。您可以在擦除/编程另一个块的同时执行一个块。在 Kinetis 设备上,闪存交换系统监视/控制从旧应用程序切换到新应用程序的所有步骤;在这些步骤之一期间断电的情况下,有额外的可靠操作保证。
好处
- 易于编程。应用程序总是在内存映射中的较低块之外执行。
- 功率损耗容忍。
- 不需要引导加载程序。主应用程序的启动没有延迟。
- 非常适合多任务操作系统。最小的应用程序停机时间。在多任务系统中,可以在后台任务运行时继续执行主应用程序任务以更新应用程序的新副本。
- 代码的备份副本。可以恢复到已知的工作应用程序。
缺点
- 存储备份副本所需的额外闪存空间。
您可以更新块,然后交换它们。
链接的文档包含详细说明。
它确保更安全的固件升级,但由于它需要更多的闪存,当然成本更高。还没有适用于任何类型的微控制器,只有那些支持内部闪存块互换。