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