vesperW · 6月21日

MCUboot的几种模式

转自 | 瑞萨嵌入式小百科

随着嵌入式系统的发展,产品对于代码升级功能的需求越来越大。通过代码升级,可以实现诸如支持新功能,修复故障等目标。

代码升级本质上是对片上闪存flash(主要是code flash)进行擦除和写入的过程。由于需要在代码运行的同时实现对flash内容的操作,因此有些特别需要注意的部分。

如:假如在传输过程中出现异常,导致代码升级失败,设备能否从该状态正常启动并恢复至最近一次升级前的状态。还有,假如向芯片中烧录的新代码存在漏洞,或传输途径中遭到破坏,设备能否检测到这种异常并拒绝运行该代码。

另外,由于代码升级跟芯片的flash结构密切相关,因此该过程中是否涉及中断向量表重定位等也需考虑。

代码升级的实现方式多种多样,系统架构也千差万别,如何在众多方式中找到合适的升级方式,需要用户根据应用场景的需求进行评估。

在此,我们介绍一种面向32位微处理器的安全启动代码框架——MCUboot

MCUboot都有哪些特定呢?主要是以下几个:

  • 完全开源,持续更新
  • 支持各种升级模式:overwrite,swap,direct XIP(Execute In Place)和拷贝到RAM中执行
  • 对新固件Firmware进行安全校验,且安全校验的级别可根据实际需求选择
  • 可从升级异常中恢复

MCUboot相关的资源在哪里?你可进入MCUboot官网(MCUboot official website),源码全部托管在GitHub上:

https://www.trustedfirmware.o...

由于MCUboot是一个系统框架,因此它规定了对于芯片的flash划分,将整个芯片的存储空间划分为Bootloader、Primary Slot和Secondary Slot三个部分。某种意义上说,Primary Slot和Secondary Slot互为对方的备份,在不同的升级模式下,各slot的作用也有所不同,这一点我们在后续详细介绍。

对于一个32位单片机来说,客户可以自行移植MCUboot以适配当前产品。而瑞萨MCU的开发工具Renesas FSP集成了该功能,只需要动动鼠标即可对MCUboot相关的信息进行配置,就像添加一个普通的外设驱动那样。

灵活配置软件包FSP:

https://www.renesas.cn/cn/zh/...

我们以FSP对MCUboot的支持为例,对MCUboot的相关特性进行介绍。

首先介绍MCUboot支持的四种升级模式,分别是Overwrite、Swap、Direct XIP和加载到RAM中执行。由于FSP不支持第四种——加载到RAM中执行,因为我们重点介绍前三种。

Overwrite模式

image.png

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模块,则升级模式的修改界面如下所示。

image.png

FSP中MCUboot升级模式选项

注意:Overwrite Only和Overwrite Only Fast比较类似,唯一的区别是,后者仅将用到的sectors(此处可以理解为Flash Block)从Secondary Slot拷贝到Primary Slot,未用部分不拷贝。

Swap模式

image.png

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的擦除次数。写入次数和擦除次数相等。

END

作者:瑞萨嵌入式小百科,王瑾
来源:strongerHuang

推荐阅读

欢迎大家点赞留言,更多Arm技术文章动态请关注极术社区嵌入式客栈专栏欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。

推荐阅读
关注数
2881
内容数
262
分享一些在嵌入式应用开发方面的浅见,广交朋友
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息