做嵌入式开发时,产品一旦部署到现场,最头疼的就是固件更新。拆机、接线、上编程器——这三板斧在消费级产品上根本行不通。OTA(Over the Air)就是来解决这个问题的:通过蓝牙等无线连接直接给MCU换固件。
但OTA在实现层面并不是“把新固件发过去就完事”。Flash怎么分区、IAP程序放哪里、用户程序还能不能正常跑,这些在选型和架构设计阶段就需要明确。
一、BLE OTA无线升级
BLE系列芯片的固件升级详细流程参考:
安卓蓝牙OTA升级工具
iOS蓝牙OTA升级工具
很多开发者第一次看SDK例程时会被 BackupUpgrade_OTA、OnlyUpdateApp_IAP、JumpIAP 这些名字绕晕。其实只要抓住两个维度——升级通道(无线还是有线)和Flash管理策略(后台式还是非后台式)——三种方式的边界就很清晰了。
下面按方式一、方式二、方式三逐一拆解,重点讲清楚每种方式下Flash怎么分区、升级流程怎么走、烧录时该合并哪些文件。
方式一:无线后台式升级(双区备份)
适用场景:Flash 资源充裕,APP和LIB都需要支持升级。
方式一的核心特征是双区备份。整个用户Code区被切成四块,以CH系列常见的448KB CodeFlash为例:
| 区域 | 大小 | 内容 |
|---|---|---|
| JumpIAP | 4K | 跳转IAP的引导代码 |
| imageA(APP) | 216K | 用户应用程序 |
| imageB(OTA) | 216K | OTA备份区,暂存新固件 |
| imageIAP | 12K | IAP编程升级代码 |
上电后先跑IAP程序,然后跳转到APP执行用户功能。APP运行时通过无线方式接收完整的OTA升级文件,存到imageB备份区。接收完成后软复位进入IAP,IAP把备份区的新固件拷贝到APP区覆盖旧固件,最后跳回APP运行新固件。
这个过程中APP一直在正常运行,新固件下载对使用者无感,所以叫后台式或静默式升级。优点是APP+LIB都能升级,缺点是Flash要对半分使用,216K的APP区实际可用空间有限。
方式二:无线非后台式升级(单区+固定库)
适用场景:Flash资源紧凑,LIB固定不需要升级。
方式二采用APP+IAP+LIB的架构,Flash分区如下:
| 区域 | 大小 | 内容 |
|---|---|---|
| JumpIAP | 4K | 跳转IAP的引导代码 |
| imageA(APP) | 44K | 用户应用程序 |
| imageB(IAP) | 16K | OTA升级代码 |
| LIB | 128K | 固定库(蓝牙协议栈等) |
上电先跑IAP,由IAP跳转APP执行用户程序。升级时APP触发条件(比如0xFFE3通道下传数据),软复位进入IAP,IAP通过无线方式接收新固件直接写入APP区覆盖旧固件,完成后跳转APP执行新程序。
升级期间APP正常功能无法使用,属于非后台式。LIB区域固定不参与升级,所以升级文件体积小、速度快。代价是LIB无法通过OTA更新,如果LIB需要升级,只能走方式三全片升级。
方式三:有线升级(BOOT全片升级)
适用场景:LIB需要升级,或者无线升级失败后的兜底方案。
方式三走的是芯片内置BOOT,冷启动时PB22接地进入BOOT程序,通过USB(PB10/PB11)或UART(PA8/PA9)连接,用ISP工具进行升级。这种方式不依赖APP或IAP程序,属于全片擦写,适合产线烧录或现场救砖。
三种方式对比与选型建议
| 维度 | 方式一 | 方式二 | 方式三 |
|---|---|---|---|
| 升级通道 | 无线 | 无线 | 有线(USB/UART) |
| Flash策略 | 双区备份 | 单区直写 | 全片擦写 |
| APP升级 | 支持 | 支持 | 支持 |
| LIB升级 | 支持 | 不支持 | 支持 |
| 升级期间APP可用 | 是(后台式) | 否(非后台式) | 否 |
| 适用场景 | Flash充裕 | Flash紧凑 | 产线/救砖/LIB升级 |
实际项目选择时,如果产品Flash是512KB级别且功能复杂,方式一的双区备份能提供最好的升级体验和容错性;如果成本敏感、Flash只有128KB~256KB,方式二的固定库模式能在有限空间内实现无线升级,但要在项目初期就确认LIB不需要后续更新;方式三则作为兜底手段始终保留,冷启动PB22接地的硬件设计要在PCB上留出来。
实际开发过程中,建议先用方式三确保ISP工具能正常连接和烧录,再调方式二的IAP跳转和无线接收流程,最后如果需要双区备份再上方式一。这样分层验证,出问题时能快速定位是BOOT、IAP还是APP层的故障。
二、根据升级方式选型
理解了OTA的底层逻辑,选芯片时就要看Flash容量够不够双区?IAP空间怎么规划?是否需要固定库模式?
| 芯片系列 | 内核主频 | Flash | SRAM | BLE | 升级方式 |
|---|---|---|---|---|---|
| CH587 | 120MHz | 1MB | 256KB | BLE 5.4 | 支持 IAP 和 OTA |
| CH585 | 78MHz | 512KB | 128KB | BLE 5.4 | 支持 IAP 和 OTA |
| CH592 | 20MHz | 512KB | 26KB | BLE 5.4 | 支持 IAP 和 OTA |
三颗芯片还各带 32KB 独立 DataFlash,专门存数据,作用接近一块不掉电的小 EEPROM。做 OTA 分区时,这块一般单列为数据区,不占用户程序空间。
沁恒的 SDK 提供了一整套 OTA 工具链。APP、IAP、LIB 的 hex 文件可以用 WCH_AssemblingFileTool 合并,再经 ISP 工具烧录。官方安卓和 iOS 端的 OTA App 都支持基于 hex 和 bin 文件升级。
实操里有两件事容易踩。带库升级和不带库升级,流程不一样。带库的,直接用 OTA App 扫描连接设备就行。不带库的,得先用蓝牙调试助手发指令让设备进 OTA 模式,再用 OTA App 去连。Flash 分区规划要在项目初期定下来,别等做到一半再改。选了后台式,APP 区实际可用空间是 Flash 总量减去暂存区、IAP、BootLoader 和 LIB。以 448KB CodeFlash 为例,双区方案下用户程序真正能用的可能只有 200KB 出头。功能复杂的话,选 CH587 会比 CH585、CH592 从容不少。
小结
OTA 的实现方式直接决定了 Flash 预算和升级可靠性。后台式双区体验好,但吃 Flash。非后台式单区省空间,但容错差。固定库模式是提速的利器,值得在协议栈已经成熟的芯片上优先考虑。不同产品适配不同的 Flash 容量和功能需求。选型时先看 Flash 够不够撑起你想要的 OTA 模式,再看内核和外设是否匹配项目,这样能少走不少弯路。