STM32F4 OTA 升级双 App 方案设计与实现

1. 引言

在嵌入式产品实际部署中,固件升级是保障设备功能迭代与缺陷修复的关键能力。对于 STM32F4 系列 MCU,OTA(Over-The-Air)升级通常需要结合 Bootloader 与 App 分区设计。本文围绕「双 App」架构展开,说明如何通过两个独立 App 分区实现升级失败回滚、断电保护与版本切换,提升升级过程的可靠性与安全性。

2. 双 App 方案概述

双 App 方案的核心思想是:在 Flash 中划分两个独立的 App 分区(App A 与 App B),Bootloader 根据标志位或版本信息决定启动哪一个 App。升级时,将新固件写入当前未运行的 App 分区,校验通过后切换启动标志,从而在升级失败时仍可回退到旧版本运行。

该方案相比单 App 方案的优势在于:

  • 升级失败可回滚:新固件写入备用分区后先校验,校验失败不切换标志,继续运行旧固件。
  • 断电保护:写入过程中断电,未完成的分区不参与启动,系统仍可正常启动。
  • 版本切换灵活:支持 A/B 分区交替升级,便于灰度发布与版本回退。

3. Flash 分区规划

以 STM32F407 为例,其 Flash 大小为 1MB,起始地址 0x08000000。典型分区规划如下:

分区名称 起始地址 大小 说明
Bootloader 0x08000000 64KB 引导程序,负责校验与跳转
App A 0x08010000 448KB 当前运行固件
App B 0x08080000 448KB 备用固件分区
Flag 区 0x080FF000 4KB 存储启动标志与版本信息

分区大小可根据实际固件体积调整,但需保证 Bootloader 与两个 App 分区互不重叠,且各分区起始地址按 Flash 扇区边界对齐。

4. Bootloader 设计

Bootloader 是双 App 方案的核心,负责完成以下工作:

  1. 读取启动标志:从 Flag 区读取当前应启动的 App 分区编号。
  2. 校验 App 有效性:对目标 App 分区进行 CRC 或 SHA 校验,确认固件完整。
  3. 跳转执行:设置 MSP 与 PC 指针,跳转到 App 的复位向量。

若目标 App 校验失败,Bootloader 自动切换到另一分区启动,实现故障回退。以下为 Bootloader 跳转核心代码示例:

c 复制代码
typedef void (*pFunction)(void);

void jump_to_app(uint32_t app_addr)
{
    uint32_t msp = *(volatile uint32_t *)app_addr;
    pFunction jump = (pFunction)(*(volatile uint32_t *)(app_addr + 4));

    if ((msp & 0xFFF00000) != 0x20000000) {
        return;  /* MSP 非法,拒绝跳转 */
    }

    __set_MSP(msp);
    jump();
}

5. App 端设计要点

App 端需要配合 Bootloader 完成升级流程,主要包括以下设计要点:

  • 中断向量表重定位:App 编译时需将中断向量表偏移到自身分区起始地址,运行时通过 SCB->VTOR 设置偏移。
  • 固件接收与写入:通过串口、Wi-Fi 或以太网接收升级包,按扇区擦写备用分区。
  • 升级标志写入:固件写入并校验完成后,更新 Flag 区中的启动标志,通知 Bootloader 下次启动新分区。
  • 版本上报:App 启动后向服务器上报当前版本号,便于后台管理升级状态。

中断向量表重定位示例:

c 复制代码
SCB->VTOR = APP_A_ADDR;  /* 或 APP_B_ADDR */

6. 升级流程设计

完整的双 App 升级流程如下:

  1. 设备运行在 App A,服务器下发新固件包。
  2. App A 接收固件,写入 App B 分区,并计算校验值。
  3. 写入完成后,App A 将启动标志切换为 App B,并复位重启。
  4. Bootloader 校验 App B 固件有效,跳转执行 App B。
  5. App B 启动后上报新版本号,升级完成。

若步骤 2 或步骤 3 失败,启动标志未切换,设备继续运行 App A,升级失败不影响当前功能。

7. 升级失败回滚机制

双 App 方案天然支持失败回滚,具体机制如下:

  • 写入失败:新固件写入备用分区过程中出错,备用分区标记为无效,Bootloader 继续启动原分区。
  • 校验失败:新固件写入完成但 CRC 校验不通过,不切换启动标志。
  • 运行失败:新固件启动后运行异常,可通过看门狗或心跳超时触发回滚标志,Bootloader 下次启动旧分区。

运行失败回滚需要 App 在启动早期设置「运行成功」标志,若超时未设置,Bootloader 判定启动失败并回退。

8. 注意事项与工程实践

在实际工程落地时,需要注意以下几点:

  • Flash 扇区对齐:STM32F4 扇区大小不一,分区边界必须落在扇区起始地址,避免擦写越界。
  • 编译链接脚本:App A 与 App B 使用不同的链接脚本,分别指定 Flash 起始地址与中断向量表偏移。
  • 固件包格式:建议在固件包头加入魔数、版本号、长度与 CRC,便于 Bootloader 校验。
  • 升级包加密:对固件进行加密传输,防止固件被逆向或篡改。
  • 双备份策略:Flag 区可存储两份标志,防止标志写入过程中断电导致状态丢失。

9. 总结

双 App 方案为 STM32F4 OTA 升级提供了可靠的容错机制,通过分区隔离、启动标志切换与校验回滚,有效解决了升级失败、断电中断等常见问题。该方案适用于对可靠性要求较高的量产设备,是嵌入式 OTA 设计中值得优先考虑的架构之一。

相关推荐
ACP广源盛1392462567318 分钟前
高速 USB 切换方案选型笔记:10Gbps 全通道同步开关 LH6828@ACP 评估
笔记·硬件架构·国产芯片
abc light1 小时前
ARM 裸机开发(6)——时钟树与定时器
arm开发·单片机·fpga开发
sbjdhjd10 小时前
网工进阶笔记:H3CSE 园区网全栈技术与协议汇总
网络·笔记·云计算·ssh·网络工程·vlan·aaa
吠品10 小时前
智谱开源 ZCode 之后,真正的考试才开始
单片机·嵌入式硬件·1024程序员节
海绵宝宝的月光宝盒13 小时前
14-AutoCAD-阵列命令应用与案例实战(AR)
经验分享·笔记·自动化·课程设计·制造·学习方法·cad
白山编程大哥15 小时前
接口幂等性是什么?如何设计?
笔记
ACP广源盛1392462567315 小时前
6 盘位存储扩展方案选型笔记:YLB3116 @ACP评估记录
笔记·硬件架构·硬件工程·国产芯片
小李不想当小白15 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
LCG米15 小时前
STM32驱动W5500以太网模块实测:TCP吞吐瓶颈定位、TX指针回绕陷阱与断线重连保活落地
stm32·单片机·嵌入式硬件·tcp/ip
创界工坊工作室17 小时前
63-基于STC89C52霍尔传感器的智能化电能表设计
stm32·单片机·嵌入式硬件·51单片机·proteus