forked from EmbeddedTeam/app_photomagnetic
Implement device firmware upgrade using MCUboot Serial Recovery over usart1 (reusing the existing protocol UART). The application layer handles upgrade commands (0xFF) to trigger bootloader entry, while MCUboot manages the actual firmware swap with RSA signature verification. Key additions: - sysbuild.conf to enable MCUboot bootloader with signing key - mcuboot.conf with serial recovery and watchdog feed settings - Kconfig option APP_DFU (default y) with conditional compilation - dfu.cpp module for DFU initialization - Upgrade command callback in com.hpp (bootmode_set + sys_reboot) - Documentation for upgrade procedures and change notes
252 lines
7.3 KiB
Markdown
252 lines
7.3 KiB
Markdown
# 光磁头固件在线升级方案 — 更改说明
|
|
|
|
## 1. 方案概述
|
|
|
|
采用 **MCUboot Serial Recovery** 方案,复用 usart1 协议口实现固件升级。
|
|
|
|
- 应用层正常运行时,usart1 由 0x7EE7 协议占用
|
|
- 收到升级命令后,应用层直接重启
|
|
- MCUboot 接管 usart1,等待 3 秒看是否有 mcumgr 命令
|
|
- 主板在 3 秒内发送 mcumgr 命令 → 进入 serial recovery 模式
|
|
- 主板上传签名固件 → MCUboot 验证签名 → swap → 重启运行新固件
|
|
|
|
**关键特性**:
|
|
- 零额外硬件(复用 usart1)
|
|
- 应用层不运行 mcumgr,与 0x7EE7 协议零冲突
|
|
- MCUboot 内置 RSA 签名验证
|
|
- 升级中断电可回滚,设备不会变砖
|
|
|
|
---
|
|
|
|
## 2. 涉及的文件
|
|
|
|
### 2.1 新建文件
|
|
|
|
| 文件 | 用途 |
|
|
|---|---|
|
|
| `sysbuild.conf` | 启用 MCUboot bootloader + 签名密钥路径 |
|
|
| `sysbuild/mcuboot.conf` | MCUboot 配置:serial recovery、签名、喂狗 |
|
|
| `sysbuild/mcuboot.overlay` | MCUboot 设备树覆盖(当前为空,保留扩展) |
|
|
| `src/dfu.cpp` | DFU 模块初始化确认打印 |
|
|
| `doc/固件升级方案.md` | 详细升级方案文档 |
|
|
|
|
### 2.2 修改文件
|
|
|
|
| 文件 | 改动 |
|
|
|---|---|
|
|
| `include/com.hpp` | 新增 `DfuCommand` 回调(条件编译 `CONFIG_APP_DFU`),处理 0xFF 指令 |
|
|
| `CMakeLists.txt` | 已有 `zephyr_sources_ifdef(CONFIG_APP_DFU src/dfu.cpp)` 控制 |
|
|
| `Kconfig` | 已有 `config APP_DFU default y` |
|
|
|
|
### 2.3 未修改文件
|
|
|
|
| 文件 | 说明 |
|
|
|---|---|
|
|
| `boards/dr2501a/dr2501a_g0b0ce.dts` | flash 分区已就绪(boot=48KB, slot0/1=200KB, storage=64KB) |
|
|
| `prj.conf` | 无需额外配置(应用层不运行 mcumgr) |
|
|
| `boards/use_ms.overlay` | 传感器配置,无改动 |
|
|
|
|
---
|
|
|
|
## 3. 配置说明
|
|
|
|
### 3.1 sysbuild.conf
|
|
|
|
```
|
|
SB_CONFIG_BOOTLOADER_MCUBOOT=y
|
|
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="${ZEPHYR_BASE}/../bootloader/mcuboot/root-rsa-2048.pem"
|
|
```
|
|
|
|
- 启用 MCUboot bootloader
|
|
- 开发阶段使用 MCUboot 自带的 RSA-2048 密钥
|
|
- 量产时替换为自生成密钥
|
|
|
|
### 3.2 sysbuild/mcuboot.conf
|
|
|
|
```
|
|
CONFIG_MCUBOOT_SERIAL=y # 启用 serial recovery
|
|
CONFIG_BOOT_SERIAL_UART=y # 使用 UART 接口
|
|
CONFIG_BOOT_SERIAL_ENTRANCE_GPIO=n # 禁用 GPIO 按钮检测
|
|
CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y # 等待 mcumgr 命令触发
|
|
CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=3000 # 等待 3 秒
|
|
CONFIG_BOOT_WATCHDOG_FEED=y # 喂狗(避免升级过程中看门狗复位)
|
|
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y # RSA 签名验证
|
|
CONFIG_BOOT_ERASE_PROGRESSIVELY=y # 渐进擦除(优化升级速度)
|
|
```
|
|
|
|
### 3.3 条件编译
|
|
|
|
DFU 功能通过 `CONFIG_APP_DFU` 控制:
|
|
- `y`(默认):编译 dfu.cpp,com.hpp 中包含 0xFF 指令处理
|
|
- `n`:完全移除 DFU 功能(零开销)
|
|
|
|
---
|
|
|
|
## 4. 协议扩展
|
|
|
|
### 4.1 新增指令:0xFF 升级命令
|
|
|
|
| 子命令 | 方向 | 行为 |
|
|
|---|---|---|
|
|
| `0x01` | 主板→小板 | 进入升级模式(直接重启) |
|
|
| `0x02` | 主板→小板 | 查询升级状态 |
|
|
| `0x02` | 小板→主板 | 回复 0x00 = 应用层正常运行 |
|
|
|
|
### 4.2 帧格式
|
|
|
|
```
|
|
进入升级模式:
|
|
主板 → 小板: [7E E7] [FF] [01] [01] [CRC_L] [CRC_H]
|
|
小板: 无回复(直接重启)
|
|
|
|
查询升级状态:
|
|
主板 → 小板: [7E E7] [FF] [02] [00] [CRC_L] [CRC_H]
|
|
小板 → 主板: [7E E7] [FF] [02] [01] [00] [CRC_L] [CRC_H]
|
|
```
|
|
|
|
---
|
|
|
|
## 5. 升级流程
|
|
|
|
### 5.1 首次构建与烧录(需要调试器)
|
|
|
|
```bash
|
|
# 构建(MCUboot + 应用)
|
|
west build -p auto -b dr2501a_g0b0ce/stm32g0b0xx \
|
|
--sysbuild app/app_photomagnetic \
|
|
-d build
|
|
|
|
# 烧录(一次性)
|
|
west flash -d build
|
|
```
|
|
|
|
### 5.2 后续升级(通过 UART,不需要调试器)
|
|
|
|
```
|
|
步骤1: 主板发送升级命令
|
|
主板 → 小板: [7E E7] [FF] [01] [01] [CRC_L] [CRC_H]
|
|
|
|
步骤2: 小板重启,MCUboot 接管 usart1
|
|
MCUboot 等待 3 秒看是否有 mcumgr 命令
|
|
|
|
步骤3: 主板切换到 mcumgr 模式(3 秒内)
|
|
mcumgr --conntype=serial --connstring='dev=/dev/ttyUSBx,baud=115200' \
|
|
image upload -e zephyr.signed.bin
|
|
|
|
步骤4: 标记待测试
|
|
mcumgr image test <hash>
|
|
|
|
步骤5: 复位触发 swap
|
|
mcumgr reset
|
|
|
|
步骤6: MCUboot 验证签名 → swap → 重启运行新固件
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 签名密钥管理
|
|
|
|
### 6.1 开发阶段
|
|
|
|
使用 MCUboot 自带的开发密钥:
|
|
```
|
|
${ZEPHYR_BASE}/../bootloader/mcuboot/root-rsa-2048.pem
|
|
```
|
|
|
|
sysbuild.conf 中已配置,构建时自动签名。
|
|
|
|
### 6.2 量产阶段
|
|
|
|
```bash
|
|
# 生成自定义密钥对
|
|
pip install imgtool
|
|
imgtool keygen -k keys/my-signing-key.pem -t rsa-2048
|
|
|
|
# 更新 sysbuild.conf
|
|
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="${APP_DIR}/keys/my-signing-key.pem"
|
|
```
|
|
|
|
> ⚠️ 私钥必须安全保管,丢失后无法签名新固件。
|
|
|
|
### 6.3 签名验证流程
|
|
|
|
```
|
|
构建时:imgtool 用私钥签名 → zephyr.signed.bin
|
|
运行时:MCUboot 用公钥验证 → 验证通过才 swap
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Flash 分区布局
|
|
|
|
| 分区 | 偏移 | 大小 | 用途 |
|
|
|---|---|---|---|
|
|
| boot_partition | 0x00000 | 48KB | MCUboot bootloader |
|
|
| slot0_partition | 0x0C000 | 200KB | 应用镜像(当前运行) |
|
|
| slot1_partition | 0x3E000 | 200KB | 升级镜像(待 swap) |
|
|
| storage_partition | 0x70000 | 64KB | NVS 存储 |
|
|
|
|
分区已在 `dr2501a_g0b0ce.dts` 中定义,无需修改。
|
|
|
|
---
|
|
|
|
## 8. 安全机制
|
|
|
|
| 机制 | 说明 |
|
|
|---|---|
|
|
| 镜像签名 | RSA-2048 签名验证,公钥烘焙进 bootloader |
|
|
| 未确认自动回滚 | test 模式下重启未确认 → MCUboot 自动回滚到原固件 |
|
|
| 升级中断保护 | 升级中断电 → MCUboot 回滚,设备不会变砖 |
|
|
| 等待超时 | 3 秒内无 mcumgr 命令 → 正常启动应用 |
|
|
|
|
---
|
|
|
|
## 9. 主板端配合
|
|
|
|
### 9.1 升级时序
|
|
|
|
```
|
|
t=0ms: 主板发送升级命令 [7E E7][FF][01][01][CRC]
|
|
t=100ms: 小板重启
|
|
t=200ms: MCUboot 启动,开始等待 mcumgr 命令
|
|
t=200ms~3200ms: 主板发送 mcumgr 命令(必须在 3 秒内)
|
|
t=3200ms: MCUboot 超时,正常启动应用(如果没收到 mcumgr)
|
|
```
|
|
|
|
### 9.2 关键约束
|
|
|
|
- 主板必须在小板重启后 **3 秒内** 发送 mcumgr 命令
|
|
- 波特率:115200(与应用层协议一致)
|
|
- 升级完成后,小板自动重启运行新固件
|
|
- 主板需检测小板重启(等待新固件的 ID 帧),然后切回 0x7EE7 协议模式
|
|
|
|
---
|
|
|
|
## 10. 注意事项
|
|
|
|
1. **首次烧录需要调试器**:MCUboot + 应用首次烧录需要 J-Link/OpenOCD;后续升级全部通过 UART
|
|
2. **3 秒窗口**:主板必须在小板重启后 3 秒内发送 mcumgr 命令,否则 MCUboot 会正常启动应用
|
|
3. **签名密钥**:开发阶段使用默认密钥(不安全);量产必须替换为自生成密钥
|
|
4. **降级保护**:开发阶段建议关闭(`CONFIG_BOOT_DOWNGRADE_PREVENTION=n`),方便回退
|
|
5. **usart1 共享**:应用层协议和 mcumgr 在不同阶段使用同一 UART,不会冲突
|
|
6. **DFU 开关**:通过 `CONFIG_APP_DFU`(Kconfig)控制,默认启用;设为 n 可完全移除 DFU 功能
|
|
|
|
---
|
|
|
|
## 11. 文件清单
|
|
|
|
```
|
|
app/app_photomagnetic/
|
|
├── sysbuild.conf # [新建] 启用 MCUboot
|
|
├── sysbuild/
|
|
│ ├── mcuboot.conf # [新建] MCUboot 配置
|
|
│ └── mcuboot.overlay # [新建] MCUboot 设备树(当前为空)
|
|
├── include/
|
|
│ └── com.hpp # [修改] 新增 0xFF 升级命令处理
|
|
├── src/
|
|
│ └── dfu.cpp # [新建] DFU 模块初始化
|
|
└── doc/
|
|
├── 固件升级方案.md # [新建] 详细方案文档
|
|
└── 升级更改说明.md # [新建] 本文档
|
|
```
|