Zephyr Bootloader 开发指南¶
本文介绍 zephyr bootloader 使用方法,及相关 demo 展示的操作步骤配置。
相关工程位置:
Bootloader:
bootloader/mcuboot/boot/zephyr
App:
zephyr/samples_panchip/hello_world
文章分为三部分
功能说明:对 boot 的功能,区域划分做整体描述
工程编译烧录:包括 mcuboot 工程及 hello world(test sample)
mcuboot:编译时包括 5 种编译方式,对应 4 种升级方式(其中第四种 BOOT_DIRECT_XIP 方式,可以选择是否可以 revert)
hello_world:测试 app 程序,包括 2 种编译方式(以 code-partition 作为区分),编译后的固件通过 imgtool 处理有 2 种方式,区分升级程序是否为 confirmed 程序
演示说明: 对相对应得 5 种升级方式做演示说明
总结说明:补充一些说明
1 功能说明¶
mcuboot 为官方 bootloader 程序,支持的平台包括 zephyr/mynewt 等,我们基于 zephyr 平台,需要编译生成可与 zephyr 主程序交互的 boot 程序,来完成固件的解签,升级,标志固件信息等操作
参考官方连接:
zephyr 中关于 mcuboot 升级功能介绍
https://docs.zephyrproject.org/latest/guides/device_mgmt/dfu.html?highlight=mcuboot
mcuboot 官方文档介绍
https://docs.mcuboot.com/
https://docs.mcuboot.com/design.html 描述固件升级细节
mcuboot 关于 zephyr 应用介绍
https://www.mcuboot.com/documentation/readme-zephyr/
1.1 程序划分¶
带 bootloader 的程序,支持升级时,通常会按照以下区域进行划分
bootloader:0x0 地址程序,上电运行 bootloader 主程序
slot0_partition:app 主固件程序地址,作为 image 时,通常具有 header 和 tailer,并在 image 尾部有签名信息用来确认固件正确性可靠性,tailer 用来存放 magic pad 和升级固件信息(swap_type,copy_done,image_ok)
slot1_partition:app 待升级固件存放区域,形式如 slot1_partition,但升级后的 tailer 会被擦除
scratch_partition:可选区域,临时存放固件交换区域,相较于不带 scratch 的升级方式,此种类型固件搬运有一定保障性
storage_partition:存放存储内容区域,固件升级时通常可以选择不处理
1.2 image 格式¶
初始编译的 app 程序,对头部进行了 512 Bytes 的偏移用作 image header,主要存放固件版本固件大小等信息。
image 程序大小结束位置存放 hash 及签名信息,用来确认固件的完整正确性
image 总大小结束位置存放 image 的状态信息,用来管理升级交换方式
1.2.1 image header¶
大小:512 Bytes = 0x200
位置:存放于 image 头部区域
存放信息:
struct image_version { uint8_t iv_major; uint8_t iv_minor; uint16_t iv_revision; uint32_t iv_build_num; }; /** Image header. All fields are in little endian byte order. */ struct image_header { uint32_t ih_magic; uint32_t ih_load_addr; uint16_t ih_hdr_size; /* Size of image header (bytes). */ uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes). */ uint32_t ih_img_size; /* Does not include header. */ uint32_t ih_flags; /* IMAGE_F_[...]. */ struct image_version ih_ver; uint32_t _pad1; };
作用:存放固件版本固件大小等信息
1.2.2 image sign infor¶
位置:image 尾部
存放信息:
hash 值
根据固定 private + hash 值生成的签名信息
作用:存放 hash 值及签名信息
1.2.3 image trailer¶
位置:image 总大小的末尾
存放信息:
/* This is not actually used by mcuboot's code but can be used by apps * when attempting to read/write a trailer. */ struct image_trailer { uint8_t swap_type; uint8_t pad1[BOOT_MAX_ALIGN - 1]; uint8_t copy_done; uint8_t pad2[BOOT_MAX_ALIGN - 1]; uint8_t image_ok; uint8_t pad3[BOOT_MAX_ALIGN - 1]; uint8_t magic[16]; };
作用:用来判断 swap 类型,处理搬运信息,判断固件正确性以及固定 magic pattern 标识
1.2.4 imgtool¶
位于bootloader\mcuboot\scripts
的 imgtool 为处理原始 image 的 python 脚本,目的是生成待烧录到对应分区的 2 个 bin 文件(分为 Not Confirmed 和 Confirmed,此 2 个文件根据 pad 构建生成)
操作方式如下:
根路径下打开 cmd/powershell,执行如下指令
python bootloader\mcuboot\scripts\imgtool.py sign --key bootloader\mcuboot\root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.x --slot-size 0x10000 --pad --confirm build\hello_world_test_board\zephyr\zephyr.bin build\hello_world_test_board\zephyr\signed1.x.bin
–key :签名 key 信息,需要与 Bootloader config 宏所对应的解签方式对应
CONFIG_BOOT_SIGNATURE_TYPE_RSA
–header-size :header 大小固定 0x200 (Bytes)
–align :8
–version :version 版本1.x
–slot-size 0x10000:image tailer 存放末尾位置
–pad:为 image 添加 tailer,升级固件所必须的 pad magic 的添加命令
–confirm:为 image tailer 添加 confirm 信息,存在则升级方式为 permanent,否则为 test 方式
后接原始文件路径及生成固件路径
1.3 升级方式¶
固件升级分为 4 种方式,通过prj.conf
文件中进行四选一
if !SINGLE_APPLICATION_SLOT
choice
prompt "Image upgrade modes"
default BOOT_SWAP_USING_MOVE if SOC_FAMILY_NRF
default BOOT_SWAP_USING_SCRATCH
config BOOT_SWAP_USING_SCRATCH
bool "Swap mode that run with the scratch partition"
help
This is the most conservative swap mode but it can work even on
devices with heterogeneous flash page layout.
config BOOT_UPGRADE_ONLY
bool "Overwrite image updates instead of swapping"
help
If y, overwrite the primary slot with the upgrade image instead
of swapping them. This prevents the fallback recovery, but
uses a much simpler code path.
config BOOT_SWAP_USING_MOVE
bool "Swap mode that can run without a scratch partition"
help
If y, the swap upgrade is done in two steps, where first every
sector of the primary slot is moved up one sector, then for
each sector X in the secondary slot, it is moved to index X in
the primary slot, then the sector at X+1 in the primary is
moved to index X in the secondary.
This allows a swap upgrade without using a scratch partition,
but is currently limited to all sectors in both slots being of
the same size.
config BOOT_DIRECT_XIP
bool "Run the latest image directly from its slot"
help
If y, mcuboot selects the newest valid image based on the image version
numbers, thereafter the selected image can run directly from its slot
without having to move/copy it into the primary slot. For this reason the
images must be linked to be executed from the given image slot. Using this
mode results in a simpler code path and smaller code size.
endchoice
简单介绍四种方式的升级功能:
带 scratch 区的升级:BOOT_SWAP_USING_SCRATCH
此种方式对 flash 占用相对较大,升级时,分为三步
slot1_partition 搬运到 scratch_partition
slot0_partition 搬运到 slot1_partition
scratch_partition 搬运到 slot0_partition
不带 scratch 区的搬运升级:BOOT_UPGRADE_ONLY
直接将 slot1_partition 搬运到 slot0_partition
不带 scratch 区的交换固件:BOOT_SWAP_USING_MOVE
交换 slot0_partition 和 slot1_partition
不带 scratch 区的,不进行搬运的升级:BOOT_DIRECT_XIP
此种方式通过选择宏
CONFIG_BOOT_DIRECT_XIP_REVERT
决定是否 revert,分为 2 种子方式slot0_partition 和 slot1_partition 不需要搬运
但需要注意不同 partition 的 code 内,code_partion 对应的 slot_partion 需要在编译时对应,主要用于编译生成不同的 bin 文件时使用
例如,编译 slot1_partion 时,需要在 Devicetree 中进行相关对应
chosen { ... zephyr,code-partition = &slot1_partition; };
2 工程编译烧录¶
工程编译烧录介绍 mcuboot(bootloader project),以及 hello world 的编译,烧录方式
2.1 MCUBOOT¶
mcuboot 为 bootloader 的 project,包括五种编译方式,对应四种升级方式
2.1.1 功能概述¶
目前 Boot 程序可以完成以下功能
解密签名
判断固件信息进行 upgrade,有以下五种方式
带 scratch 区的升级
不带 scratch 区的搬运升级
不带 scratch 区的交换固件
不带 scratch 区的,不进行搬运的升级
不带 scratch 区的,不进行搬运的升级,并支持非 confirm 回退
程序跳转
2.1.2 环境要求¶
board: pan108xxb5_evb
uart (option): 显示串口log
2.1.3 编译和烧录¶
项目位置:bootloader/mcuboot/boot/zephyr
mcuboot 包括 5 种编译方式,需要在boot/zephyr/prj.conf
中关注 5 个 config 宏,根据选择升级方式,选择使用的宏
# chioce one upgrade type
CONFIG_BOOT_SWAP_USING_SCRATCH=y
CONFIG_BOOT_UPGRADE_ONLY=y
CONFIG_BOOT_SWAP_USING_MOVE=y
CONFIG_BOOT_DIRECT_XIP=y
CONFIG_BOOT_DIRECT_XIP_REVERT=y
方式一(默认):
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
方式二:
# chioce one upgrade type
CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
方式三:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
方式四:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
方式五:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
CONFIG_BOOT_DIRECT_XIP=y
CONFIG_BOOT_DIRECT_XIP_REVERT=y
示例:
以pan108xxb5_evb
为例,在SDK
目录打开 PAN1080 SDK CLI
后, 可以用如下命令执行编译和下载:
编译
west build -d build/mcuboot_test_board -b pan108xxb5_evb bootloader/mcuboot/boot/zephyr
下载
west flash -d build/mcuboot_test_board -r jlink
2.2 Hello World¶
hello_world 为 app 层对应演示 sample,可以区分编译链接 code 地址(通过 dts flash_map 中的 code_partition 映射),并在后续的工具处理中,可以选择是否为confirmed 固件
2.2.1 功能概述¶
当需要配合 mcuboot 进行升级跳转展示时,需要 hello world 完成以下功能
打印基础信息
hello_world
打印 image header 信息,包括 version 版本
2.2.2 环境要求¶
board: pan108xxb5_evb
uart (option): 显示串口log
2.2.3 编译链接¶
项目位置:zephyr/samples_panchip/hello_world
hello world 包括 2 种编译方式,对应 code_partition 位置不同,其中不需要搬运的升级方式,需要根据对应需要下载位置,修改01_SDK/zephyr/boards/arm/pan108xxb5_evb/pan108xxb5_evb.dts
中的 flash map 的 code_partition 进行修改
chosen {
...
zephyr,code-partition = &slot0_partition;
};
示例:
以pan108xxb5_evb
为例,在SDK
目录打开PAN1080 SDK CLI
后, 可以用如下命令执行编译,在对应工程 build 目录下生成zephyr.bin
:
west build -d build/hello_world_test_board -b pan108xxb5_evb zephyr/samples_panchip/hello_world
2.2.4 工具处理¶
imgtool 处理已编译的zephyr.bin
,包括对 image 固件添加 header(版本信息),对 image 结尾位置后进行签名,为升级时添加需要的 pad 及 confirm 信息
版本号生成
通过--version 1.x
命令 为固件添加具体固件版本信息,例如--version 1.0
即为固件添加版本为 1.0.0.0 的 image header 信息。
是否为 confirmed 固件,分为以下 2 类示例命令:
不含 confirm 的烧录固件示例如下:
zephyr 同级目录下打开 cmd/powershell 运行命令
python bootloader\mcuboot\scripts\imgtool.py sign --key bootloader\mcuboot\root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.x --slot-size 0x10000 --pad build\hello_world_test_board\zephyr\zephyr.bin build\hello_world_test_board\zephyr\signed1.x.bin
分别生成两个版本的 hello_world 程序,需要对应 signed.bin 文件的目录,例如分别生成 signed1.0.bin,signed1.1.bin
包含 confirm 的烧录固件示例如下:
zephyr 同级目录下打开 cmd/powershell 运行命令
python bootloader\mcuboot\scripts\imgtool.py sign --key bootloader\mcuboot\root-rsa-2048.pem --header-size 0x200 --align 8 --version 1.x --slot-size 0x10000 --pad ——confirm build\hello_world_test_board\zephyr\zephyr.bin build\hello_world_test_board\zephyr\signed_confirm1.x.bin
分别生成两个版本的 hello_world 程序,pad 构建为 confirmed,需要对应 signed.bin 文件的目录,例如分别生成 signed_confirm1.0.bin,signed_confirm1.1.bin
2.2.5 烧录¶
烧录时不是烧录原始的zephyr.bin
文件,需要将工具处理后的文件,通过 jflash 烧录至对应区域,分别为 0x10000 和 0x70000 区域,具体烧录地址在演示说明中对不同升级方式区分描述
3 演示说明¶
以下对 mcuboot 编译的五种升级方式,hello_world 编译并且通过工具处理的两种固件形式(是否经过 confirm 标识),进行测试现象描述说明:
三种搬运跳转升级方式(对应下文 Method1,2,3)说明
升级过程的验证进行时,主要方式是搬运 原有程序存在于 slot0,待升级固件(程序链接起始地址 0x10000 / slot0 地址)当通过某种方式(flash 烧录 / OTA 传输)存在于 slot1 时,重启会对程序进行搬运处理操作,三种方式处理细节有区别(下文会详细展示),最终将存放于 slot1 的程序搬运至 slot0,搬运结束后会进行一次跳转。
根据 slot1 存放的固件是否进行过 confirm 的 tailer pad 添加,区分为 confirmed 固件或者 not confirmed 固件。
confirmed 固件——第一次 reset 搬运后,固件之后会标记为 perm(permanent / 永久的),之后再 reset 便不会发生变化
not confirmed 固件–第一次 reset 时,固件搬运结束后跳转 slot0 运行,由于非 confirm 的固件,只能作为1次测试,此时 log 显示 test,第二次复位时,会将之前存在的固件进行 revert 操作,还原为之前 slot 存在的固件并跳转运行,输出 log revert,而之后再进行的复位,由于 revert 标准位的存在,便不会再次进行升级操作。
前三种方式验证时可以通过固件的版本来判断运行的是哪个固件,而固件版本本身不会影响升级是否进行。
两种跳转升级方式(对应下文的Method 4,5)说明
升级过程未进行搬运 程序编译链接时,需要按存放区域构建对应的链接地址(存放于 slot0 的固件需要 code-partition 链接 slot0 区域,而存放于 slot1 的固件需要 code-partition 链接 slot1 区域)当 slot0 或 slot1 区域只存在一个固件时,首次上电便会跳转存在固件的起始地址,而当 slot0,slot1 同时存在固件时,首次上电会对固件进行版本比对,跳转运行较高版本的固件。
Method 4 和 Method 5 升级方式区别在于,Method 5 支持对固件的 confirm 信息进行判断,版本比对在首次上电逻辑相同,而第二次上电时,上一次跳转的程序若为 not confirmed 固件,则会对上一固件进行擦除,并且跳转至另一区域固件,同样的,再次上电若仍为 not confirmed 固件,则会继续擦除,并最终进行3次复位后,在 flash code 区域不存在可运行的 image。
后两种方式的固件版本信息不仅可以用来区分跳转后的程序内容,还为跳转逻辑提供比对依据。
以下对 5 种模式构建了验证方式,参照例图,对运行模式的说明和演示。
mcuboot 编译方式 |
hello world 编译方式 |
hello world 工具处理 |
对应升级演示 |
---|---|---|---|
CONFIG_BOOT_SWAP_USING_SCRATCH=y |
code_partion = slot0_partition |
–pad |
Method1(Not confirmed) |
CONFIG_BOOT_SWAP_USING_SCRATCH=y |
code_partion = slot0_partition |
–pad –confirm |
Method1(confirmed) |
CONFIG_BOOT_UPGRADE_ONLY=y |
code_partion = slot0_partition |
–pad |
Method2(Not confirmed) |
CONFIG_BOOT_UPGRADE_ONLY=y |
code_partion = slot0_partition |
–pad –confirm |
Method2(confirmed) |
CONFIG_BOOT_SWAP_USING_MOVE=y |
code_partion = slot0_partition |
–pad |
Method3(Not confirmed) |
CONFIG_BOOT_SWAP_USING_MOVE=y |
code_partion = slot0_partition |
–pad –confirm |
Method3(confirmed) |
CONFIG_BOOT_DIRECT_XIP=y |
code_partion = slotx_partition |
–pad |
Method4(Not confirmed) |
CONFIG_BOOT_DIRECT_XIP=y |
code_partion = slotx_partition |
–pad –confirm |
Method4(confirmed) |
CONFIG_BOOT_DIRECT_XIP=y |
code_partion = slotx_partition |
–pad |
Method5(Not confirmed) |
CONFIG_BOOT_DIRECT_XIP=y |
code_partion = slotx_partition |
–pad –confirm |
Method5(confirmed) |
下述示例演示过程中,首先需要准备 2 种固件版本,烧录至 slot0(0x10000)的hello_world
程序通过 imgtool 处理为 1.0.0.0,作为原始固件,烧录至 slot1(0x70000)的hello_world
程序通过 imgtool 处理为 1.1.0.0,作为待升级固件。
烧录结束后,通过观察 reset 后的 log,可以验证不同方法下升级跳转后具体的运行版本是否符合预期。
3.1 Method 1¶
默认不带 scratch 区的交换固件
,mcuboot sample
的prj.conf
配置如下:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
boot 程序默认使用第三种方式不带 scratch 区的交换固件
进行跳转升级,升级流程如下图所示,confirmed 固件进行 1 步 reset,而不带 confirmed 固件需要 2 步 reset,分别运行:
3.1.1 Not Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为不含 confirmed 程序时:
复位第一次后,程序将打印 test 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 revert 信息,运行搬运跳转后,运行版本为 1.0.0.0
复位第三次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.0.0.0
3.1.2 Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为 confirmed 程序时:
复位第一次后,程序将打印 perm 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.1.0.0
3.2 Method 2¶
带 scratch 区的升级
,mcuboot sample
的prj.conf
配置如下:
# chioce one upgrade type
CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
boot 程序默认使用第三种方式不带 scratch 区的交换固件
进行跳转升级,升级流程如下图所示,confirmed 固件进行 1 步 reset,而不带 confirmed 固件需要 2 步 reset,分别运行:
3.2.1 Not Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为不含 confirmed 程序时:
复位第一次后,程序将打印 test 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 revert 信息,运行搬运跳转后,运行版本为 1.0.0.0
复位第三次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.0.0.0
3.2.2 Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为 confirmed 程序时:
复位第一次后,程序将打印 perm 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.1.0.0
3.3 Method 3¶
不带 scratch 区的搬运升级
,mcuboot sample 的prj.conf
配置如下:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
# CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
boot 程序默认使用第三种方式不带 scratch 区的搬运固件
进行跳转升级,升级流程如下图所示,confirmed 固件进行 1 步 reset,而不带 confirmed 固件需要 2 步 reset,分别运行:
3.3.1 Not Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为不含 confirmed 程序时:
复位第一次后,程序将打印 test 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.1.0.0
3.3.2 Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为 confirmed 程序时:
复位第一次后,程序将打印 perm 信息,运行搬运跳转后,运行版本为 1.1.0.0
复位第二次后,程序将打印 none 信息,不进行搬运,运行跳转后,运行版本为 1.1.0.0
3.4 Method 4¶
默认不带 scratch 区的,不进行搬运的升级
,mcuboot sample 的prj.conf
配置如下:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
CONFIG_BOOT_DIRECT_XIP=y
# CONFIG_BOOT_DIRECT_XIP_REVERT=y
固件准备流程发生变化:
hello_world
准备:
准备 primary image 时,01_SDK\zephyr\boards\arm\pan108xxb5_evb\pan108xxb5_evb.dts
中确认 code-partition 为 slot0_partition:
zephyr,code-partition = &slot0_partition;
准备 secondary image 时,01_SDK\zephyr\boards\arm\pan108xxb5_evb\pan108xxb5_evb.dts
中确认 code-partition 为 slot1_partition:
zephyr,code-partition = &slot1_partition;
分别通过 imgtool 生成不同版本的固件通过 jflash 进行烧录,升级流程如下图所示,confirmed 固件进行 1 步 reset,而不带 confirmed 固件需要 2 步 reset,分别运行:
3.4.1 Not Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为不含 confirmed 程序时:
最终 reset 通过版本判断,会通过 bootloader 程序跳转到不同的 partition,运行较高版本固件
3.4.2 Confirmed¶
当烧录至 slot 1(0x70000 / secondary image)的程序为 confirmed 程序时:
最终 reset 通过版本判断,会通过 bootloader 程序跳转到不同的 partition,运行较高版本固件
3.5 Method 5¶
默认不带 scratch 区的,不进行搬运的升级,支持回退版本的升级
,mcuboot sample 的prj.conf
配置如下:
# chioce one upgrade type
# CONFIG_BOOT_SWAP_USING_SCRATCH=y
# CONFIG_BOOT_UPGRADE_ONLY=y
# CONFIG_BOOT_SWAP_USING_MOVE=y
CONFIG_BOOT_DIRECT_XIP=y
CONFIG_BOOT_DIRECT_XIP_REVERT=y
固件准备流程发生变化:
hello_world
准备:
准备 primary image 时,zephyr\boards\arm\pan108xxb5_evb\pan108xxb5_evb.dts
中确认 code-partition 为 slot0_partition:
zephyr,code-partition = &slot0_partition;
并通过 imgtool 进行待升级固件生成带或者不带 confirmed 固件,留作后续使用。
准备 secondary image 时,zephyr\boards\arm\pan108xxb5_evb\pan108xxb5_evb.dts
中确认 code-partition 为 slot1_partition:
zephyr,code-partition = &slot1_partition;
并通过 imgtool 进行待升级固件生成带或者不带 confirmed 固件,留作后续使用。
通过 jflash 进行烧录不同的固件到对应区域(如 slot0 需要对应 0x40000,slot1 需要对应 0x50000),升级流程如下图所示,confirmed 固件进行 1 步 reset,而不带confirmed 固件需要 3 步 reset,分别运行:
3.5.1 Not Confirmed¶
当烧录至 slot 0(0x40000/secondary image)的程序为不含confirm程序,烧录至slot 1(0x50000/secondary image)的程序为不含confirm程序时
复位第一次后,运行compare后,跳转到slot1_partition,运行版本为1.1.0.0
复位第二次后,擦除slot1后,跳转到slot0_partition,运行版本为1.0.0.0
复位第三次后,擦除slot0后,无运行版本
3.5.2 Confirmed¶
当烧录至 slot 0(0x40000 / secondary image)的程序为 confirmed 程序,烧录至 slot 1(0x50000 / secondary image)的程序为 confirmed 程序时:
最终 reset 通过版本判断,会通过 bootloader 程序跳转到不同的 partition,运行较高版本固件。
4 总结说明¶
以上为目前所有可以支持的升级方式说明,通过 hello_world sample 进行演示:
带 scratch 区的有助于理解搬运过程,但后续由于空间限制不一定采用。
不带 scratch 区的升级主要先以目前 method1 带搬运的升级作为主要验证方式,后续在 1024KB 上只需要替换适配 board.dts 文件,即可对其他 sample(flash 占用较大的程序)进行支持。
不搬运的方式同样可以在项目中考虑,如 method4,method5,不搬运的方式对 flash 使用具有一定好处,但对编译烧录方式有一定限制如上文述。