随着嵌入式系统的发展,产品对于代码升级功能的需求越来越大。通过代码升级,可以实现诸如支持新功能,修复故障等目标。
代码升级本质上是对片上闪存flash(主要是code flash)进行擦除和写入的过程。由于需要在代码运行的同时实现对flash内容的操作,因此有些特别需要注意的部分。如:假如在传输过程中出现异常,导致代码升级失败,设备能否从该状态正常启动并恢复至最近一次升级前的状态。还有,假如向芯片中烧录的新代码存在漏洞,或传输途径中遭到破坏,设备能否检测到这种异常并拒绝运行该代码。另外,由于代码升级跟芯片的flash结构密切相关,因此该过程中是否涉及中断向量表重定位等也需考虑。
代码升级的实现方式多种多样,系统架构也千差万别,如何在众多方式中找到合适的升级方式,需要用户根据应用场景的需求进行评估。
在此,我们介绍一种面向32位微处理器的安全启动代码框架——MCUboot。
MCUboot都有哪些特定呢?主要是以下几个:
完全开源,持续更新
支持各种升级模式:overwrite,swap,direct XIP(Execute In Place)和拷贝到RAM中执行
对新固件Firmware进行安全校验,且安全校验的级别可根据实际需求选择
可从升级异常中恢复
MCUboot相关的资源都在哪里呢?您可进入MCUboot官网(MCUboot official website),源码全部托管在GitHub上。页面下有一个md文件,作为MCUboot的官方介绍。
由于MCUboot是一个系统框架,因此它规定了对于芯片的flash划分,将整个芯片的存储空间划分为Bootloader、Primary Slot和Secondary Slot三个部分。某种意义上说,Primary Slot和Secondary Slot互为对方的备份,在不同的升级模式下,各slot的作用也有所不同,这一点我们在后续详细介绍。
对于一个32位单片机来说,客户可以自行移植MCUboot以适配当前产品,而Renesas FSP(Flexible Software Package灵活软件包)已经帮客户实现了该适配,对于Renesas RA系列产品来说,MCUboot相关的大多数配置均可通过界面简单添加和配置,就像添加一个普通的外设驱动那样。
灵活配置软件包FSP
我们以FSP对MCUboot的支持为例,对MCUboot的相关特性进行介绍。
首先介绍MCUboot支持的四种升级模式,分别是Overwrite、Swap、Direct XIP和加载到RAM中执行。由于FSP不支持第四种——加载到RAM中执行,因为我们重点介绍前三种。
Overwrite模式
MCUboot Overwrite模式图解
对于Overwrite模式来说,起点是芯片中烧录了Bootloader和User Application v1.0(初始版本),上电后Bootloader分别检查Secondary Slot和Primar Slot中的内容,由于此时Secondary Slot为空,因此Bootloader检查Primary Slot中Image(映像文件)的完整性,确认其合法后会跳转到Primary Slot中的User Application v1.0中执行(此时PC指针运行在Primary Slot中,黄色的Execution箭头标识)。
代码运行的过程中收到了升级请求,则会接收新Image并烧录到Secondary Slot中。对于接收新Image的途径,则完全依赖用户应用程序的实现,可以是USB、网口、Modbus等。烧录完成后,会执行一条软复位指令,使得芯片回到复位向量表处开始执行Bootloader,此时Bootloader发现Secondary Slot中有一个新的代码,假如它的版本是v2.0,高于Primary Slot中的v1.0,则会将Secondary Slot中的内容拷贝到Primary Slot中,然后将Secondary Slot擦除。
如果比较整个过程的起始状态和结束状态,我们会发现,芯片中运行的代码从低版本的v1.0变成了高版本的v2.0,实现了代码的升级。
从Overwrite模式的流程不难看出它的一些特点:
由于代码设计比较简单,因此Bootloader带来的代码量较小。因此能够留更多的空间给应用程序使用。
Overwrite不支持代码回滚。即假如芯片中烧录了新Image,则升级完成后旧Image不复存在。
代码仅在Secondary Slot中备份而非执行,最终需拷贝到Primary Slot中执行,因此升级所用的Application Image进行编译/链接的地址始终为Primary Slot地址空间。
由于整个过程中需要对flash进行两次擦除(Primary Slot和Secondary Slot)一次写入(Primary Slot),因此整个Boot的过程依赖flash的特性,主要是擦写速度。
对于Renesas RA系列产品来说,假如在Stack中添加了MCUboot模块,则升级模式的修改界面如下所示。
FSP中MCUboot升级模式选项
注意:Overwrite Only和Overwrite Only Fast比较类似,唯一的区别是,后者仅将用到的sectors(此处可以理解为Flash Block)从Secondary Slot拷贝到Primary Slot,未用部分不拷贝。
Swap模式
MCUboot Swap升级模式图解
从系统框图来说,Swap模式和Overwrite模式相比,在flash划分上多了Scratch area,用于存储两个slot交换的中间内容。
为简化说明,对于Swap模式来说,依然假设起点是芯片中烧录了Bootloader和User Application v1.0 (位于Primary Slot),代码运行过程中收到了升级指令,接收来自外部的新Image (User Application v2.0),并烧录到Secondary Slot中,完成后执行软复位,芯片重新回到Bootloader中运行。此时Bootloader判断Secondary Slot有更高版本v2.0的代码,检查其完整性,确定合法后将Primary Slot中的内容和Secondary Slot中的内容以Block为单元进行交换。
交换完成后,Primary Slot保存了高版本v2.0的Image,而Secondary Slot中保存了低版本v1.0的Image,代码依然在Primary Slot中执行。
Swap模式下的初始状态,Primary Slot中运行的是低版本v1.0 Image,而完成升级后的结束状态下,Primary Slot中运行的是高版本v2.0 Image,因此完成了一次升级。
从Swap模式的流程可以看出它的一些特点:
支持代码回滚/回退/降级。由于升级完成后,低版本v1.0 Image依然存储在芯片中,因此若在高版本v2.0 上发现bug需要修复,则可以重新执行升级程序使得代码回到v1.0。
由于代码功能较为复杂,因此Bootloader带来的代码量较大。其他条件一致的情况下,Swap模式的代码是最大的。又由于保留了Scratch area用于代码交换,因此留给应用程序的空间就更小了。
整个升级过程中对于Primary Slot和Secondary Slot均执行擦和写各一次,因此Boot时间较长。
由于flash专门划分了Scratch area用于对两个Slot进行代码交换,在升级过程中,会对该区域进行多次擦写。具体的擦写次数取决于Scratch area大小和Slot大小,简单的计算方式为,利用Primary Slot除以Scratch area得到的结果,即对Scratch area的擦除次数。写入次数和擦除次数相等。
全部0条评论
快来发表一下你的评论吧 !