Zephyr使用DFU

本文说明zephyr如何进行dfu升级

zephyr以下面的形式完成dfu: bootloader: mcuboot image下载: mcumgr image管理和烧写: zephyr dfu支援mcuboot image格式

原理简介 链接到标题

mcuboot分区 链接到标题

mcuboot有4个分区 boot_partition: 装载mcuboot slot0_partition:装载由mcuboot引导运行的image slot1_partition: 用于下载升级的image scratch_partition: 用于交换slot0和slot1

正常引导运行 链接到标题

CPU上电后从boot_partition开始运行mcuboot,mcuboot对slot0进行检查,如果存在image且检查通过,则跳到slot0上执行zephyr image

下载image 链接到标题

slot0 image下载image 链接到标题

在slot0内的zephyr image内包含了mcumgr功能,通过mcumgr可以把升级image下载到slot1

mcuboot升级 链接到标题

编译是通过配置可以让mcuboot支援GPIO检查进入recovery模式,然后通过mcumgr下载升级image到slot1,目前zephyr上只配置了nrf52840_pca10059支援这种模式,我向mcuboot提交了一个pr支援zephyr所有board通过uart检查进入recovery mode,但一直没有被review,需要的小伙伴可以执行merge: https://github.com/JuulLabs-OSS/mcuboot/pull/456

image升级 链接到标题

下载了新的image到slot1后,做交换slot的flag设置,再次重启时mcuboot会先检查flag,发现需要交换slot,就将slot0和slot1的内容交换,已scratch_partition做为数据交换区,如果交换过程中出错,会将slot0和slot1做恢复。交换成功后mcuboot对slot0进行检查,检查通过调到slot0上开始执行新的image。

使用 链接到标题

Bootloader 链接到标题

按照Zephyr使用mcuboot编译烧写mcuboot

image准备 链接到标题

按照Zephyr使用mcuboot编译烧写一个image,并编译签名好另一个准备用于DFU的image,后面简称DFU-image。 image的配置文件需要有下面几个选项

#image按MCUBOOT link
CONFIG_BOOTLOADER_MCUBOOT=y

#启用mcumgr
CONFIG_MCUMGR=y

#启动mcumgr image管理
CONFIG_MCUMGR_CMD_IMG_MGMT=y

#启动mcumgr的uart smp传输协议
CONFIG_MCUMGR_SMP_UART=y

#启动mcumgr的bt smp传输协议
CONFIG_MCUMGR_SMP_BT=y

#配置bt
CONFIG_BT_L2CAP_TX_MTU=260
CONFIG_BT_RX_BUF_LEN=260
CONFIG_BT_GATT_READ_MULTIPLE=n
CONFIG_NET_BUF_USER_DATA_SIZE=8

Host工具安装 链接到标题

在ubuntu 18.04下执行下面命令进行安装mcumgr命令行工具用于升级

go get github.com/apache/mynewt-mcumgr-cli/mcumgr

升级 链接到标题

准备好的DFU-image可通过蓝牙也可以通过串口进行下载

通过蓝牙下载 链接到标题

sudo /home/frank/go/bin/mcumgr -conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image upload ~/work/project/nrf52_moderate/apps/moderate_mcuboot/build/zephyr.signed.bin 

通过串口下载 链接到标题

mcumgr --conntype serial --connstring=/dev/ttyUSB0,baud=115200 image upload ~/work/project/nrf52_moderate/apps/moderate_mcuboot/build/zephyr.signed.bin 

注意下载前需要确保没有其它串口工具占用/dev/ttyUSB0

下载速度 链接到标题

目前发现无论是串口还是蓝牙,下载速度均只有4KB/s

切换image 链接到标题

下载完后可以用下面命令查看image的情况

mcumgr --conntype serial --connstring=/dev/ttyUSB0,baud=115200 image list

如下

Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: 0ca78338236de874e6606ba471b5b0865927fdc799073f1fbac2541b8ded3d4a
 slot=1
    version: 1.0.0
    bootable: true
    flags: 
    hash: 7decd49223b668ddabd20ad66dfd1fef4a03a003cac460c24f91e03cea2d1847
Split status: N/A (0)

用下面命令测试新的image

mcumgr --conntype serial --connstring=/dev/ttyUSB0,baud=115200 image test 7decd49223b668ddabd20ad66dfd1fef4a03a003cac460c24f91e03cea2d1847

可以看到slot的 flags变为pending

Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: 0ca78338236de874e6606ba471b5b0865927fdc799073f1fbac2541b8ded3d4a
 slot=1
    version: 1.0.0
    bootable: true
    flags: pending
    hash: 7decd49223b668ddabd20ad66dfd1fef4a03a003cac460c24f91e03cea2d1847
Split status: N/A (0)

重启后mcuboot将交换slot0和slot1执行,通过image list观察image可以看到slot0和1已经发生交换

Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active
    hash: 7decd49223b668ddabd20ad66dfd1fef4a03a003cac460c24f91e03cea2d1847
 slot=1
    version: 1.0.0
    bootable: true
    flags: confirmed
    hash: 0ca78338236de874e6606ba471b5b0865927fdc799073f1fbac2541b8ded3d4a

此时如果重启又会恢复原来的slot.如果确认需要升级,用下面的命令确认交换,完成升级

mcumgr --conntype serial --connstring=/dev/ttyUSB0,baud=115200 image confirm

可以看到

Images:
 slot=0
    version: 1.0.0
    bootable: true
    flags: active confirmed
    hash: 7decd49223b668ddabd20ad66dfd1fef4a03a003cac460c24f91e03cea2d1847
 slot=1
    version: 1.0.0
    bootable: true
    flags: 
    hash: 0ca78338236de874e6606ba471b5b0865927fdc799073f1fbac2541b8ded3d4a
Split status: N/A (0)

参考 链接到标题

https://docs.zephyrproject.org/latest/guides/device_mgmt/dfu.html https://mcuboot.com/mcuboot/readme-zephyr.html https://mcuboot.com/mcuboot/design.html