嵌入式固件升级要点总结
一、“双分区 + Bootloader” 核心框架
鉴于 MCU 资源有限,如 RAM/ROM 较小,结合 RTOS 任务调度特性与外部 FLASH 存储扩展需求,主流采用 “Bootloader 引导 + 双固件分区” 架构,从根源上规避升级失败致设备变砖风险。
1.1存储分区规划
需在外部 FLASH(或 MCU 内置 FLASH + 外部 FLASH 组合)划分独立分区,明确各区域功能与地址范围,防止读写冲突。典型分区如下:
Bootloader 分区:承担启动校验、升级触发判断、固件刷写及引导跳转职责,是升级的关键保障。依据 MCU 架构(如 ARM Cortex-M 需含中断向量表重映射代码),通常设为 5 - 16KB,优选内置 FLASH 以获高启动优先级。
固件 A 分区(主):存放当前稳定运行固件,按固件实际大小再加 20% 冗余空间(预留功能扩展),因外部 FLASH 容量大,故存放于此。
固件 B 分区(备):作为接收新固件的临时缓冲区,升级完成后可与 A 分区互换角色(双活备份),与 A 分区等大以保障新固件完整存储,置于外部 FLASH。
升级信息分区:存储升级状态(如 “待升级”“升级中”“升级成功”)、固件版本号、校验值等元数据,设为固定大小(如 512B - 4KB,按需设计结构体),存于外部 FLASH 独立扇区,避免擦写干扰。
备份分区(可选):用于存放当前固件备份,以便升级失败回滚,与 A 分区等大,置于外部 FLASH。
关键适配点:提前规划外部 FLASH 扇区擦写策略(如按块擦除,防频繁擦写同一扇区),借助 SPI/I2C 接口驱动确保读写稳定;在 RTOS 环境为分区操作分配独立任务,并设合理优先级(如 Bootloader 任务优先级高于应用任务)。

1.2升级流程设计
结合 MCU/RTOS 特性,流程注重 “轻量化” 与 “容错性”,避免过多占用系统资源。
升级触发:支持两种触发方式以适配不同场景。自动触发由 RTOS 定时任务读取升级指令(如从串口、CAN、OTA 模块接收 “升级请求” 帧),校验指令合法后设 “待升级” 标志(写入升级信息分区);手动触发可通过硬件按键(如长按复位 + 功能键)或调试指令强制进入 Bootloader 模式,适用于设备离线升级。
固件传输:依通信接口选传输协议并优化数据包设计。低速场景(如串口)用 XModem/YModem 协议(带校验分片传输);高速场景(如 SPI、以太网)可自定义轻量级协议(如帧头 + 长度 + 数据 + CRC32)。在 RTOS 中通过消息队列接收数据包,防止阻塞主线程,并设超时重传机制(如 3 次重传失败则终止传输,恢复原固件运行)。
固件校验:采用双重校验确保完整性,防范恶意固件写入。每接收一包数据,计算 CRC16/CRC32 校验值与数据包携带校验值比对,有误则要求重传;新固件完整写入 B 分区后,计算整个固件的 MD5/SHA256 值,与升级指令中的 “预期校验值” 比对,不匹配则丢弃固件并触发回滚。
固件刷写:基于外部 FLASH 特性优化擦写逻辑。先擦除 B 分区对应扇区(外部 FLASH 按 “扇区擦除” 最小单位操作,不可字节级擦除),再逐页写入新固件数据。刷写任务与传输任务分离,通过信号量同步状态(如 “传输完成” 后释放信号量,触发刷写)。
引导跳转:Bootloader 据升级状态决定引导方向。升级成功则更新升级信息分区的 “固件标识”(如将 “当前固件” 指向 B 分区),复位后 Bootloader 引导 B 分区固件启动;升级失败则保留 “当前固件” 指向 A 分区,引导原固件启动;若开启备份分区,可自动从备份分区恢复 A 分区固件。
二、核心模块开发
2.1 Bootloader 模块
Bootloader 是升级方案基础,针对 MCU 架构(如 Cortex - M、MIPS)优化代码,避免依赖 RTOS(确保裸机环境可运行)。上电后先初始化时钟、外部 FLASH 接口及最小系统资源,再读取升级信息分区的 “升级标志”。若无升级需求,直接跳转到 A 分区固件的中断向量表(需重映射向量表地址,如 Cortex - M 通过 SCB->VTOR 寄存器配置);有升级需求则进入升级模式,初始化通信接口等待接收新固件。同时具备 “自我保护” 能力,如检测到固件刷写过程中掉电,下次启动时不执行跳转,重新进入升级模式。
2.2 外部 FLASH 驱动模块
针对不同型号外部 FLASH(如 W25Q64、GD25Q128),驱动实现标准化接口并适配 RTOS 任务调度。提供 FLASH_Init ()(初始化 SPI/I2C 通信)、FLASH_EraseSector ()(扇区擦除)、FLASH_WritePage ()(页写入)、FLASH_ReadData ()(数据读取)等接口以隐藏硬件差异。在驱动中添加互斥锁,防止多任务同时操作 FLASH 引发数据冲突;擦写操作耗时长时,通过回调函数通知应用层状态。
2.3 升级管理模块(RTOS 层)
在 RTOS(如 FreeRTOS、RT - Thread)中封装升级逻辑,通过多任务协同实现异步升级。划分通信任务(接收外部升级指令及固件数据包存入消息队列)、校验任务(从消息队列读取数据完成分片与全量校验)、刷写任务(校验通过后调用 FLASH 驱动写入 B 分区,更新升级信息分区状态)、监控任务(定时检查升级进度,超时或出错触发回滚机制)。合理分配 RAM 缓冲区(如设 1KB - 4KB 接收缓冲区,匹配 FLASH 页大小),避免内存溢出,利用事件标志组同步多任务状态。
三、关键保护
掉电保护:在升级信息分区记录 “刷写偏移量”,掉电后重启,Bootloader 可据偏移量续传固件,无需从头传输;刷写时先更新 “临时状态”,全部完成后再修改 “正式状态”(原子操作,防状态不一致)。
回滚机制:升级失败(如校验不通过、刷写中断),Bootloader 自动引导 A 分区原固件启动;若开启备份分区,通过 FLASH_Copy () 接口将备份分区数据恢复到 A 分区。
异常处理:RTOS 中通过任务监控(如 Watchdog)检测升级任务是否卡死,超时则重启设备并进入 Bootloader 模式。