nRF Connect SDK v3.0.2-Bootloader&TOA

目录

一、Bootloader基础

1.1 单片机执行流程

1.2 程序固件的签名

二、DFU

2.1 设备固件更新DFU

2.2 通过Bootloader运行DFU

2.3 通过应用程序运行DFU

2.4 无线固件 (FOTA)

2.5 实现DFU

2.6 DFU Target 库

2.7 FOTA 下载库

2.8 DFU 传输工具

2.8.1 nRF 设备上的 SMP 客户端

三、sysbuild

3.1 固件镜像

3.2 DTS分区

3.3 分区管理器分区

3.4 nRF connect SDK中的分区

四、启用MCUboot

4.1 固件镜像

4.2 双插槽更新规则

五、通过UART实现DFU

5.1 通过Bootloader实现

5.1.1 sysbuild.conf

5.1.2 mcuboot.conf

使用双插槽

使用单插槽

5.1.3 使能串口恢复

5.1.4 禁止终端中的UART

5.1.5 配置mcuboot.overlay

5.1.6 配置AuTerm

5.2 通过应用程序实现DFU

5.2.1 mcuboot.conf

 5.2.2 prj.conf

5.2.3 实验结果

六、镜像签名

5.1 签名创建

5.2 使能签名

5.3 验证签名

七、BLE实现FOTA

7.1 sysbuild.conf

7.2 prj.conf

7.3 创建两个镜像

镜像1

镜像2

7.4 利用nRF Connect Device Manager app烧录

7.4.1 搜索设备

7.4.2 连接

7.4.3 设置烧录文件

7.4.4 烧录

​编辑

7.4.5 查看烧录信息


一、Bootloader基础

1.1 单片机执行流程

单片机上电后从0x00000000开始执行代码,而此地址通常存储一级引导加载程序(ROM Bootloader)的地址,负责初始化基本硬件以及寻找用户程序区域。

用户程序区分为:引导程序加载区以及主应用程序区。当一级引导程序执行完毕后,开始执行第二个应用程序即Bootloader(引导加载程序,也叫不可修改引导加载程序或信任根(Root of Trust))并判断是否需要更新主程序区代码,最终执行主程序区代码。

特别的,可以有第二段可以修改的引导加载程序

1.2 程序固件的签名

现在,可以使用可信任的不可变引导加载程序,通过公钥加密技术来验证应用程序。互联网上有大量关于公钥加密技术的资源,所以如果你之前从未听说过这个,我们建议你查阅一下(特别是数字签名方面的内容)。
数字签名用于验证应用程序。简要说明其工作原理如下:
・开发者拥有一个私钥,此私钥不应与任何人共享,而应保密。
・从私钥生成一个公钥。
・公钥被嵌入到引导加载程序代码中。
・应用程序固件使用私钥进行签名。
・引导加载程序可以将公钥与签名进行匹配,以验证应用程序固件是否由私钥签名。这就保证了应用程序固件也来自开发者,因为只有开发者拥有该私钥。

二、DFU

DFU称为设备固件更新,是一种通过通信协议(如蓝牙、Wi-Fi、USB 等)更新设备的应用程序的技术。在嵌入式系统中,DFU 允许开发者或用户无需物理接触设备即可升级其固件,极大提升了产品的可维护性和用户体验。

2.1 设备固件更新DFU

直接通过通信接口例如UART直接修改设备自身的程序代码。而开发版中的程序烧写需要通过调试芯片,增加了成本。

2.2 通过Bootloader运行DFU

使用DFU时,需要让Bootloader进入DFU模式,应用程序不会执行,Bootloader会接受新固件数据。也称为串行恢复。

2.3 通过应用程序运行DFU

为了更安全的覆盖程序。通过将程序写入到ROM里,设备重启时,Bootloader会检查有无新的固件。若有,则会直接覆盖应用程序。这种方式称为双插槽DFU,缺点是很占空间。

为防止新应用程序出现故障无法运行,bootloader 检测到新应用程序有任何问题,它会将以前的应用程序交换。

2.4  无线固件 (FOTA)

无线信号上的 DFU,例如低功耗蓝牙、蜂窝物联网(LTE-M 和 NB-IoT)或 Wi-Fi,通常被称为无线固件 (FOTA)。由于无线协议很复杂,并且需要相对大量的内存才能运行,因此在 bootloader 中运行它们是不切实际的。因此,我们通常从应用程序将 FOTA 作为双插槽 DFU 运行。

2.5 实现DFU

nRF Connect SDK 使用 Zephyr 设备管理服务,通过串口协议或低功耗蓝牙在应用程序中实现 DFU,其中所使用的软件子系统名为 MCUmgr。其 Kconfig 选项可通过之前的链接查看,也能在 Kconfig 搜索中查找 “MCUMGR”。

2.6 DFU Target 库

这是 nRF Connect SDK 特定的库,用于处理固件更新。它会检查接收到的更新类型并相应处理,比如将用于 MCUboot 的应用程序更新写入 mcuboot_secondary 槽位;若收到调制解调器增量升级,就直接将新固件交给调制解调器。该库不处理传输,仅负责处理更新。

2.7 FOTA 下载库

对于连接到互联网的应用程序,nRF Connect SDK 提供此库。它首先使用 HTTP (S) 下载固件,然后将接收到的固件镜像交给 DFU Target。若有需要,也可以自定义方式传输固件更新并在应用程序中手动使用 DFU Target。

2.8 DFU 传输工具

为了从个人电脑或手机传输 DFU,我们需要安装一些工具。接收 DFU 的设备对于 MCUmgr 来说被称为 SMP 服务器。发送 DFU 的设备对于 MCUmgr 来说被称为 SMP 客户端。换句话说,开发套件(DK)通常是 SMP 服务器,而个人电脑通常是 SMP 客户端。

2.8.1 nRF 设备上的 SMP 客户端

使用 mcumgr smp_client 库,也可以在其他 nRF 设备上运行 SMP 客户端。在 LwM2M 客户端示例中可以看到这样的例子。

三、sysbuild

用于将多个不同的应用构建到一个设备上当做一个项目,避免重复构建。

分区的意义是:防止模块间的冲突;对于多镜像系统,可以明确镜像的启动地址。

flash结构为:引导程序镜像、多个镜像以及数据分区。

3.1 固件镜像

指的是独立构建、烧录以及运行的二进制文件,如BLE协议栈、引导加载程序、安全固件等。

3.2 DTS分区

是一种适用于单个镜像的分区方式,通过在dts文件中进行设置,从而为每个镜像单独进行配置。适用于小型项目。

3.3 分区管理器分区

是一种适用于所有的镜像的分区方式,需要进行统一的配置,适用于大型项目。

相比DTS分区更加灵活,因为DTS分区一旦定义后就无法修改。而分区管理器可以使用yaml文件调整分区大小。

需要通过以下配置启用它。

SB_CONFIG_PARTITION_MANAGER=y

3.4 nRF connect SDK中的分区

分为DTS分区、动态分区以及静态分区

DTS分区:单镜像

动态分区:基于分区管理器,是DFU\FOTA的默认方案

静态分区:需要提前在pm_static.yml文件进行分区配置,对于部分示例需要提前启用静态分区

四、启用MCUboot

只需在 sysbuild.conf 文件中添加

SB_CONFIG_BOOTLOADER_MCUBOOT=y

此时,构建系统会将MCUboot添加进应用当中,并且不包含DFU。默认情况下,添加 MCUboot 会将设备划分为双槽:mcuboot_primary 和 mcuboot_secondary

4.1 固件镜像

固件镜像(Firmware Image)是嵌入式系统或设备中存储的完整软件包,通常包含设备运行所需的所有代码和数据,其具体组成因设备类型和架构而异。nRF镜像包含以下部分:Bootloader、操作系统内核(Kernel)、文件系统(Filesystem)以及应用程序

用于 DFU的固件镜像必须正确格式化并签名(一种安全机制)。为此,MCUboot 提供了一个名为 imgtool.py 的脚本。在 nRF Connect SDK 中,该工具在构建过程中会自动用于生成 MCUboot 输出的构建文件。app.update 是 DFU 默认使用的文件。如果我们想确切了解构建系统是如何生成此文件的,可以通过命令行使用 west -v build .... 进行构建。

4.2 双插槽更新规则

MCUboot 有两个插槽:主插槽与辅助插槽。当 MCUboot 使用两个插槽时,在 DFU 期间新的固件镜像会被发送到 mcuboot_secondary。然后,如果辅助插槽有 “Test(测试)” 或 “Confirm(确认)” 标志,MCUboot 将交换镜像。这些标志可以在应用程序中设置,也可以在上传之前在镜像本身设置,或者由上传工具设置。
如果一个镜像被标记为 “confirm”,MCUboot 将永久地将其交换到主插槽。
如果一个镜像被标记为 “test”,MCUboot 将在一次复位周期内将其交换到主插槽。除非在运行时该镜像随后被确认,否则 MCUboot 将在下次复位时把旧的应用程序交换回主插槽。

五、通过UART实现DFU

5.1 通过Bootloader实现

5.1.1 sysbuild.conf

添加以下代码,mcuboot默认使用双插槽

#启用mcuboot
SB_CONFIG_BOOTLOADER_MCUBOOT=y
#不使用双插槽
SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y

5.1.2 mcuboot.conf

创建sysbuild文件夹,并且在文件夹下创建mcuboot.conf

#启用mcuboot的LOG
CONFIG_LOG=y
CONFIG_MCUBOOT_LOG_LEVEL_INF=y

此时创建构建build,输出的结果如下

使用双插槽

此时的mcuboot有两个插槽:mcuboot_primary和mcuboot_secondary

输出结果

使用单插槽

内存情况

输出结果 

/ {
    aliases {
        mcuboot-button0 = &button2;
        mcuboot-led0 = &led2;
    };
};

5.1.3 使能串口恢复

在mcuboot.conf中配置,使用UART通过Bootloader进行DFU

CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_UART=y

5.1.4 禁止终端中的UART

在mcuboot.conf中配置

CONFIG_UART_CONSOLE=n

LED标志mcuboot处于串口恢复模式

CONFIG_MCUBOOT_INDICATION_LED=y

5.1.5 配置mcuboot.overlay

/ {
    aliases {
        mcuboot-button0 = &button2;
        mcuboot-led0 = &led2;
    };
};

5.1.6 配置AuTerm

选择正确的串口,点击MCUmgr

点击connect

选择想烧录的二进制文件,并选择no action。因为没有使用双插槽,不需要设置test或confirm。

5.2 通过应用程序实现DFU

5.2.1 mcuboot.conf

使用双插槽

SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=n

 5.2.2 prj.conf

添加以下代码

# STEP 5.2 - Enable mcumgr DFU in application
# Enable MCUMGR 
CONFIG_MCUMGR=y  # Enable MCUMGR management for both OS and Images
CONFIG_MCUMGR_GRP_OS=y
CONFIG_MCUMGR_GRP_IMG=y  # Configure MCUMGR transport to UART
CONFIG_MCUMGR_TRANSPORT_UART=y  # Dependencies
# Configure dependencies for CONFIG_MCUMGR 
CONFIG_NET_BUF=y
CONFIG_ZCBOR=y
CONFIG_CRC=y  # Configure dependencies for CONFIG_MCUMGR_GRP_IMG 
CONFIG_FLASH=y
CONFIG_IMG_MANAGER=y  # Configure dependencies for CONFIG_IMG_MANAGER 
CONFIG_STREAM_FLASH=y
CONFIG_FLASH_MAP=y  # Configure dependencies for CONFIG_MCUMGR_TRANSPORT_UART 
CONFIG_BASE64=y

5.2.3 实验结果

修改版本为

按照5.1.6节的内容,烧录进去,重启后得到两个分区,并且版本为修改后的版本(这里因为使用了set按钮,将这个镜像作为confirm,于是slot0中的confirmed被勾选了。默认是没有的,因为烧录的时候是test配置)

六、镜像签名

签名是指一种镜像的安全机制,只有持有有效密钥的人员才能对设备进行DFU操作。对设备固件更新(DFU)镜像进行签名可确保其真实性和完整性。使用私钥生成加密签名并将其附加到 DFU 镜像上。设备使用相应的公钥来验证签名,确认镜像来自可信来源且未被篡改。公钥会从私钥自动生成并存储在 MCUboot 镜像中。下图为签名机制的示意图,开发人员拥有私钥,Bootloader根据私钥生成公钥以验证身份,验证成功后允许DFU写入。

5.1 签名创建

首先,创建一个cmd终端,安装依赖(路径设置为自己路径 )

pip install --user -r C:\ncs\v3.0.2\bootloader\mcuboot\scripts\requirements.txt

 更新pip版本至最新

python -m ensurepip
python -m pip install --upgrade pip

创建签名,保存在当前目录下

python C:\ncs\v3.0.2\bootloader\mcuboot\scripts\imgtool.py keygen -t ecdsa-p256 -k private_key.pem

格式如下

5.2 使能签名

在sysbuild.conf中进行配置

#指示密钥位置
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="\${APP_DIR}/private_key.pem"
#设置密钥类型
SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y

构建并烧录

5.3 验证签名

构建另一个签名并修改sysbuild.conf配置文件

python C:\ncs\v3.0.2\bootloader\mcuboot\scripts\imgtool.py keygen -t ecdsa-p256 -k do_not_use_this_key.pem
#指示密钥位置
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="\${APP_DIR}/private_key.pem"

 重新烧录得到以下结果

七、BLE实现FOTA

7.1 sysbuild.conf

使能mcuboot

SB_CONFIG_BOOTLOADER_MCUBOOT=y

7.2 prj.conf

使能BLE实现FOTA

CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y

7.3 创建两个镜像

镜像1

不修改任何代码

镜像2

修改version

VERSION_MAJOR = 3
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION =

修改main.c

#define RUN_LED_BLINK_INTERVAL  200

7.4 利用nRF Connect Device Manager app烧录

7.4.1 搜索设备

设备名称为Nordic_LBS,可以利用SMP的uuid搜索

7.4.2 连接

7.4.3 设置烧录文件

7.4.4 烧录

7.4.5 查看烧录信息

点击上图中,右上角的advance。随后点击images中的read。若想要切换image,点击confime,随后重启即可。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值