如何为BLE 设备实现OTA DFU 空中升级功能(上)?

本文介绍了如何为BLE外围设备实现空中(OTA)固件更新功能,重点讲解了Nordic的Buttonless OTA DFU过程。内容包括BLE设备的内存布局,DFU工作原理,以及如何通过SDK实现无按键升级。文中详细阐述了Bootloader、Application、SoftDevice的存储区域,DFU过程中的固件传输、校验和激活步骤,以及Buttonless DFU的实现方法,如公私钥对的生成和Bootloader设置的创建。此外,还探讨了固件升级的安全性,如校验和签名校验机制,以及单分区和双分区升级的区别。
摘要由CSDN通过智能技术生成

我们开发的BLE peripheral 设备通常都有代码升级的需求,不管是解决先前的bug,还是增加新的功能。我们常用的PC 或手机都是直接联网在线升级系统或软件的,BLE 这类不直接接入互联网且人机交互受限的嵌入式设备如何升级程序代码呢?很多BLE peripheral 仅留出一个BLE 无线通讯接口,我们如何通过OTA 方式实现BLE 程序代码的空中升级呢?我们如何将DFU OTA 功能或服务作为一个模块添加进我们的工程中呢?

一、BLE peripheral 如何实现DFU?

在博文ARM 代码烧录方案与原理详解 中谈到,要实现DFU(Device Firmware Update) 功能一般需要bootloader 启动引导代码,且bootloader 与application 代码是存储在不同flash 区域的。

1.1 Nordic Memory layout

如果开发过Nordic 工程,我们知道蓝牙协议栈softdevice 和application 代码也是存储在不同flash 区域的。DFU 实际上就是把新的程序代码下载到本地设备,经校验通过后,搬移到原程序代码存储区的过程。我们要了解DFU 工作原理,需要先了解nordic memory 布局:
Nordic Memory layout
Nordic memory 主要分为四个部分:

  • Application:我们实现业务逻辑的应用程序代码存放在该区域,用户需要掉电保护的一些自定义数据存储在Application data 区域,free 区域可用于暂存接收到的待升级固件代码、也可用于暂存本设备产生的数据;
  • SoftDevice(BLE Protocol Stack):Nordic 以HEX 文件形式提供的BLE 协议栈代码存放在该区域,我们根据芯片型号、SDK版本、业务需求等因素选择合适的softdevice 版本;
  • MBR(Master Boot Record):Nordic 引入MBR 主要是为了能借助DFU 更新Bootloader(我们可以借助Bootloader 将新的Application、Softdevice 或Bootloader 固件下载到某个Flash 空闲区域,完成校验后使用新的固件代码覆盖原来的代码,但bootloader 无法覆盖自身,需要借助MBR 完成新bootloader 固件覆盖旧代码的任务), 系统上电都是从MBR 启动的,所有的中断异常也都是首先由MBR 处理再转发给相应的处理程序,因此MBR 也管理系统启动流程,判断是否有bootloader 代码决定后续启动bootloader 还是直接启动application(MBR 代码不可更新);
  • MBR parameter storage:当Bootloader 需要更新自身时,将新的bootloader 固件下载到本设备flash 空闲区域并完成校验后,需要借助MBR 搬移新固件以覆盖旧代码。Bootloader 需要MBR 执行哪些指令以及指令参数如何设置,这些信息都保存在MBR parameter storage 区域(由于从bootloader 切换到MBR 需系统重置,这些指令及参数需要保存在Flash 中而非RAM 中);
  • Bootloader:主要用于更新固件代码(比如application、softdevice、bootloader),当我们有固件更新需求时,通过按键或者命令触发设备进入DFU 模式,bootloader 通过BLE、UART 或USB 方式将新的固件存储到本设备空闲flash 内(bootloader 可完全访问softdevice 的API), 对新的固件进行校验(比如私钥签名校验、Hash 完整性校验、CRC 校验等),校验通过后搬移新的固件以覆盖旧的固件(搬移bootloader 固件需借助MBR),然后激活新的固件,引导执行 application;
  • Bootloader settings:主要配合bootloader 完成DFU 过程,在Bootloader settings 区域记录当前固件的版本 / 大小 / CRC 值、设备广播名与绑定信息、固件校验信息(CRC32 值、SHA-256 哈希值、ECDSA_P256 数字签名等)、固件更新进度、固件激活进度 等信息。为了防止在写入 Bootloader settings(DFU 过程需要读写该区域信息) 时发生复位或掉电影响DFU 过程,SDK15 以后的版本引入了settings backup 机制(实际上就是复用了MBR parameter storage 区域),当写入Bootloader settings 时发生复位或掉电重启后,可以从settings backup 区域读取备份信息恢复DFU 过程。

由于MBR 需要知道Bootloader、MBR parameter storage、SoftDevice、Application 代码的存储地址,Bootloader 也需要知道Bootloader settings、MBR parameter storage 信息的存储地址,上面每个存储区域的地址范围对于确定的Nordic 芯片和Softdevice 版本都有默认值(主要是不同Nordic 芯片可供Application 使用得flash 空间大小不同,不同版本的softdevice 代码占用flash 空间大小不同):
nordic Memory range

1.2 Device Firmware Update process

BLE 连接通信需要两个设备BLE Peripheral / Slave 和BLE Central / Master,DFU 过程也需要两个设备DFU target 和 DFU controller。DFU target 是要接收新的固件并升级固件的设备(比如手环、心率带等),DFU controller 是发送新的固件并控制升级过程的设备(比如手机、网关等)。DFU 固件升级流程图如下:
Process flow on the DFU target
首先,进入DFU mode 的方式有如下四种:

// .\nRF5_SDK_17.0.2_d674dde\examples\dfu\secure_bootloader\pca10040_s132_ble\config\sdk_config.h

// <h> DFU mode enter method 
//==========================================================
// <e> NRF_BL_DFU_ENTER_METHOD_BUTTON - Enter DFU mode on button press.
#define NRF_BL_DFU_ENTER_METHOD_BUTTON 1

// <q> NRF_BL_DFU_ENTER_METHOD_PINRESET  - Enter DFU mode on pin reset.
#define NRF_BL_DFU_ENTER_METHOD_PINRESET 0

// <q> NRF_BL_DFU_ENTER_METHOD_GPREGRET  - Enter DFU mode when bit 0 is set in the NRF_POWER_GPREGRET register.
#define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1

// <q> NRF_BL_DFU_ENTER_METHOD_BUTTONLESS  - Enter DFU mode when the Boolean enter_buttonless_dfu in DFU settings is true.
#define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0

比较常用的是下面这两种方式:

  • 按键式ButtonPress DFU:DFU target 上电时长按某个按键进入DFU 模式,适合有按键的设备使用;
  • 非按键式Buttonless DFU:DFU target 接收到命令后自动进入DFU 模式,整个升级过程DFU target 不需要任何人工干预,适合完全封装无按键的设备使用。该方式需要DFU target application 能够接收并处理进入DFU 模式的命令,Nordic SDK 示例工程 ble_app_buttonless_dfu 可以在接收到来自DFU controller 的升级命令后,将寄存器NRF_POWER->GPREGRET bit 0 设置为1,系统触发软件复位,从MBR 启动Bootloader,Bootloader 检测到满足进入DFU mode 的条件(NRF_POWER->GPREGRET 值为0xB1),便进入DFU 模式开始固件升级过程。

DFU target 进入DFU mode 后,开始等待接收数据,这里分为两个阶段:

  • Receive init packet and Prevalidation:DFU target 先接收到init packet,主要包含firmware 类型、大小、版本、hash 值、固件支持的硬件版本和softdevice ID、固件签名类型及数字签名等信息,DFU target 接收完init packet 后对这些信息进行前期Prevalidation,主要是校验待升级的固件是否由受信任方提供、是否跟当前固件和硬件兼容等。如果预校验通过,则更新Bootloader settings page 并准备开始接收firmware;
  • Receive firmware and Postvalidation:DFU target Prevalidation OK 后,开始接收firmware data,每接收4 KB 数据(也即1 page)回复一次CRC 校验值,直到整个固件接收完毕,对其进行Postvalidation,主要是Hash 完整性校验。如果后期校验通过,就会invalidate 无效化当前固件,更新Bootloader settings page 并触发软件复位。

固件传输过程,根据传输方式的不同,可以分为有线升级和无线升级两种:

  • Wired DFU:通过有线通信方式来传输固件,比如UART、USB 等(目前Nordic SDK 仅对nRF52840 支持USB DFU);
  • Wireless DFU(OTA DFU):通过无线通信方式来传输固件,比如BLE、ANT 等。

固件校验过程,根据是否需要校验数字签名,也可分为开放升级和安全升级两种:

  • Open DFU:不对新的固件进行数字签名校验(bootloader 除外),且优先使用Single-bank 升级方式(目前Nordic SDK 仅支持通过USB 传输固件的方式进行Open DFU);
  • Secure DFU:需要对新的固件进行数字签名校验,以防止恶意攻击者伪造固件被接受并升级,特别是对OTA DFU 应要求数字签名校验(Nordic SDK 建议对所有固件进行数字签名校验)。

完成固件传输和校验后,就开始进行copy new firmware 的过程了,实际上就是使用新的固件覆盖旧的固件。根据新固件和旧固件占用的存储分区个数,可分为双分区升级和单分区升级两种:

  • Dual-bank DFU:将接收到的新固件先暂存在空闲存储区Bank 1 中,完成数字签名校验和完整性校验后,再擦除现有固件代码(假设存储在Bank 0 中&#
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流云IoT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值