AVR嵌入式评估板执行固件更新的技巧和诀窍
几乎所有的嵌入式系统都需要能够在现场更新其固件,从而添加新特性或修复漏洞。然而,固件现场更新可能会颇具挑战性,因为开发人员必须编写自己的引导程序或从第三方元器件供应商处购买引导程序。
有一个较为简单的方法。本文将介绍如何使用很多微都会内置但通常会被忽视的设备固件更新(DFU)功能。
固件更新选项
从头开始开发引导程序并非易事。开发人员需要解析他们的闪存空间,以便多个应用可以共存。然后,他们还需要开发几种方法在不使用编程工具的情况下将其编译的二进制程序转移到微中。这需要他们开发自己的通信协议或者需要添加外部存储器以存储新映像而增加了系统的复杂性。他们还要增加其微上的内存容量。
同样地,软件本身也会变复杂,因为引导程序需要设置系统状态及确定跳转到应用代码是否安全。
使用定制引导程序可以为开发人员提供其应用非常需要的灵活性,但很多无需开发人员工作量的应用可以采用一种固件更新标准:USB标准的内置设备固件更新(DFU)类。这可用于通过其USB端口在现场更新微的应用代码,从而大大减少固件升级过程和开发周期。
DFU已经普遍使用,这使得一些微供应商(如STMicroelectronics)甚至都提供了执行硬编码到其ROM中的更新所需的软件。那些没有提供的,通常会提供如何支持DFU的示例代码。
选择适合DFU的微
支持DFU的最简单方法是选择一个已经在其ROM中包含DFU的微,如STMicroelectronics的STM32IoTDiscovery节点和STM32F429Discovery套件上的设备。
图1:STMicroelectronicsSTM32IoTDiscovery节点基于运行STM32L475MCU(其中包含用于固件更新的DFU模式功能)的ARM®Cortex®-M4核。此特定设备设计用作IoT节点
STM32IoTDiscovery节点是一种低成本开发板,设计用作IoT传感器节点。该开发板包括几个不同的接口,用于连接Wi-Fi和蓝牙等板。让人感兴趣的是,板载STM32L475为开发人员提供在设计用于连接互联网的设备上测试和使用DFU功能的能力。
对于只想在独立的正常设备上测试DFU的开发人员来说,STM32F429Discovery套件是STM32F4系列微的知名、低成本开发套件。我们来讨论开发人员如何着手开始在这些微上测试DFU。
图2:STMicroelectronicsSTM32F429Discovery套件基于ARM®Cortex®-M4核。这个低成本开发板的MCU还包括用于进行固件更新的DFU模式功能。
一个简单的DFU示例
每个微访问DFU的方式都不同。通过一个简单的示例来看一看开发人员如何在运行STM32L475MCU的设备上更新其固件。
如前所述,STM32微包括内置到其ROM中的DFU引导程序。要访问该引导程序,开发人员需要在MCU启动时拉动其中一个BOOT引脚将其接地。BOOT引脚控制MCU启动时所处的模式,如从闪存、RAM中启动,或者我们首选的DFUUSB模式。
使用DFU准备要供用户下载的应用不需要开发人员进行任何额外的工作。GNU编译器收集(GCC)以及很多其他工具链支持在编译应用时生成DFU文件。在这里,开发人员的唯一诀窍是确定该文件的存储位置:跟所有典型应用一样,要找到.dfu文件,可以参见调试或对象文件夹。
DFU文件与二进制格式、s-record格式和十六进制文件等其他应用记录格式非常相似。文件格式包括通过USB中继转发、处理、然后写入闪存内指定位置的地址和数据信息。该过程无缝连接,使开发人员很少(如果有的话)需要检查正被使用的协议。这些都是在后台进行的,可帮助降低固件更新过程和开发工作的复杂性。
开发人员可以使用几个不同的工具通过DFU将他们的应用转移到微中。dfu-util是可以使用的一般命令行工具。它在Linux和Windows®上都以开源软件包形式提供。如果开发人员使用STM工具链,他们就可以利用STMicroelectronics应用DfuSe(图3)。
图3:STMicroelectronicsDfuSe工具可用于编程由GCC等编译器生成并加载到适合DFU的微中的DFU文件
DfuSe是WindowsGUI实用工具,可检测已在DFU模式下通电并通过USB连接到计算机的任何STM32设备。开发人员可以检索编程供应商和产品ID等信息。如果没有对闪存空间采取适当的安全保护,他们甚至可以复制MCU的存储内容并使用上传操作框将其存储在计算机上。
使用DfuSe时,开发人员一般只使用“升级”或“验证操作”部分。在此区域,开发人员可以选择其DFU应用文件,然后选择升级按钮。然后,DfuSe将自动协调固件更新过程,直到整个文件已成功加载到MCU。然后,开发人员可以选择验证映像已成功接收。一经验证,BOOT引脚就可以设置回其默认配置,如引导至闪存,然后选择‘离开DFU’模式加载并执行更新的固件。
在没有DFU支持的设备上使用DFU
只是因为微不在ROM内提供DFU引导程序,并不意味着开发人员仍不能利用DFU功能。DFU属于USB类,在很多USB堆栈中都受支持。这表示,开发人员同样能向其应用框架简单的添加DFU功能,且仍能执行DFU更新。
例如,MicrochipTechnology的AT32UC3A3不具有内置的DFU模式(图4)。开发人员可以遵照描述DFU工作原理及开发人员应当如何将其微配置为适当支持DFU的简单应用说明。
图4:AT32UC3A3UC3-A3XPLDAVR®32MCU32位AVR嵌入式评估板不包括片载DFU,但可以添加上支持DFU固件更新特性的框架USB代码
执行固件更新的技巧和诀窍
在现场更新固件并不一定只能从适合DFU的微中进行。开发人员可以决定更新固件的替代方法是否必要或更加实用。在这种背景下,开发人员应记住关于其固件更新过程的几个技巧。其中包括:
使用校验和或哈希验证将写入微内存的应用。
选择内存足够的微存储固件的备份件,以便发生错误时可以回滚固件版本。
验证在微具有内置闪存加载程序时,终端用户不会意外触发该程序。
确保任何软件引导程序均已编译且针对尺寸进行优化。
锁定闪存外设,使应用无法从内存中读取出且不能被反向工程。
务必确保栈指示器、向量表和程序计数寄存器均设置为适当的应用值。
考虑按KL46ZFreedom板的演示使用采用了USBMSD的拖放更新之类的替代更新方法(图5)。
图5:NXPSemiconductor的KL46ZFreedom板是一种低成本开发板,默认不支持DFU。开发人员可以使用USBMSD之类将新固件映像拖放到内存中的替代更新方法
总结
几乎所有嵌入式系统都需要在现场更新应用代码以避免回调的方法。从头开始创建引导程序或者修改现有引导程序可能会增加开发周期的复杂性和集成问题。
反之,开发人员可以使用内置到USB标准中的经过充分证明的DFU功能来快速、高效、毫不费力的执行现场升级。为了让这个过程顺利进行,开发人员需要仔细检查其微并确定DFU是否已内置到其微中或者它们是否需要包括支持DFU功能的软件堆栈。