Skip to content

LV001-OTA全景与设计目标 ​

一、 OTA 是什么 ​

1. OTA 的定义 ​

OTA(Over-The-Air,空中下载)升级,是指设备通过无线或有线网络远程获取新固件并完成自我更新,全程无需返厂、无需连接烧录器、无需人工拆机干预。它解决的核心问题是:设备卖出去之后,固件 Bug 修复、功能迭代、安全补丁如何触达成千上万的在网设备。

一次完整的 OTA 升级可以概括为一行流水线:

text
检查更新 → 下载升级包 → 校验 → 写入存储 → 切换启动 → 确认生效 / 失败回滚

2. OTA 与 IAP、ICP 的辨析 ​

嵌入式领域有三个容易混淆的烧录/升级术语,它们的区别在于"谁来提供新固件、走什么通道":

术语全称通道固件来源典型场景
ICPIn-Circuit ProgrammingSWD / JTAG 调试口烧录器产线烧录、开发调试
IAPIn-Application Programming任意通信口(UART / USB / CAN…)上位机、调试助手bootloader 在线烧录
OTAOver-The-Air网络(Wi-Fi / 4G / 以太网 / LoRa…)远程服务器量产设备远程升级

三者的关系可以这样理解:

  • ICP 是"外科手术",需要接触硬件调试口,设备必须拿到手边
  • IAP 是一种能力:应用程序在运行中自己擦写 Flash。OTA 的写入动作本质上就是 IAP
  • OTA 是一种业务:在 IAP 能力之上,叠加了版本管理、远程分发、校验、回滚等一整套机制

一句话:IAP 是让芯片能自己写自己,OTA 是让设备能从云端拿新固件再自己写自己。本专题讨论的正是后者这套完整业务。

3. OTA 的适用对象 ​

OTA 不是 Linux 设备的专利,从几 KB Flash 的单片机到车载域控制器都可以做 OTA,只是方案复杂度差异巨大:

二、 OTA 系统的角色与架构 ​

一套 OTA 系统由三个角色构成:服务器端负责生产与分发升级包,传输通道负责可靠送达,设备端负责接收、校验、安装与自我恢复。

OTA 升级系统角色架构

1. 服务器端 ​

服务器端是整个 OTA 体系的"大脑",职责包括:

  • 版本管理:维护固件仓库,记录每个版本适用的设备型号、硬件批次、区域
  • 升级策略:决定"谁该升、什么时候升"——灰度发布、分组推送、强制升级
  • 差分包生成:基于新旧版本镜像用 bsdiff 等算法预先生成差分包,减少设备下载流量

服务器端不一定是云端平台,小型项目里一台 HTTP 文件服务器加一个版本描述 JSON 就足够了。服务器端的详细设计见 LV031-发布与量产运维。

2. 传输通道 ​

传输通道的唯一要求是可靠地把字节流送达设备,常见的有:

  • HTTPS:最通用,自带 TLS 加密与证书体系,Linux 设备首选
  • MQTT:适合 IoT 平台,借发布/订阅通道推送升级通知,固件本身一般仍走 HTTP 拉取
  • 私有协议:MCU 外挂通信模组(ESP8266、4G 模组)时,常见"MCU 用 UART 逐块向模组要数据"的私有分块协议

除了这三类网络通道,OTA 还大量使用近场通道——UART(YMODEM)、USB DFU、CAN、BLE 等,多用于开发调试、产线与救砖,详见 LV013-升级通道协议。

通道层不保证的内容(包是否完整、是否被篡改、是否适配本机)由设备端自己校验,这是"不信任通道"的基本安全原则,详见 LV019-升级安全机制。

3. 设备端 ​

设备端内部又分为三层,职责严格分离:

  • App(业务应用):正常运行时负责查询更新、下载升级包、写入非活动槽、置升级标志。升级的主要工作其实发生在旧 App 还活着的时候
  • OTA 代理:App 内部(或独立任务/进程)负责下载、分块校验、写 Flash 的逻辑模块
  • Bootloader:设备上电的第一段代码,升级后负责校验新固件、决定启动哪个槽、失败时回滚。它是升级安全的最后防线,因此自身必须简单、稳定,通常不参与 OTA 更新

【注意】

Bootloader 不参与自身升级是通用原则:一旦 Bootloader 被刷坏,设备失去一切自救能力,只能拆机用调试口恢复。

三、 OTA 通用升级流程 ​

无论 MCU 还是 Linux 平台,OTA 的流程骨架是一致的,差异只在每一步的实现手段。

OTA 通用升级流程

1. 发现新版本 ​

三种触发模式:

  • 手动触发:用户主动点"检查更新"。服务器压力最小,但版本收敛最慢,适合有屏幕、有人操作的设备
  • 设备轮询:设备定期向服务器请求版本描述文件(JSON / 私有格式),与本地版本比对。实现简单,服务器无状态,是绝大多数方案的选择
  • 服务器推送:服务器通过 MQTT 等长连接主动通知设备升级。实时性好,适合需要统一调度的大规模设备群

发现新版本之后还有两个独立选择:要不要弹提示等用户确认、什么时候执行。它们与触发模式一起构成"升级在用户侧怎么发生"这个运营维度,三种选择的组合与取舍见 LV004-升级方案维度与选型 第四节。

版本比对不能只看版本号大小,还要匹配设备型号、硬件版本、区域、灰度白名单,防止把 A 型号的固件推给 B 型号。

2. 下载升级包 ​

下载阶段的核心诉求是抗网络抖动:

  • 断点续传:记录已下载偏移,网络中断后从断点继续,而不是从头再来
  • 分块校验:边下载边按块校验(如每 4 KB 一个 CRC),尽早发现数据错误,避免整个包下完才发现损坏
  • 写入位置:下载的固件必须写到非活动槽 / 暂存区,绝不能直接覆盖正在运行的系统

3. 校验升级包 ​

下载完成后、置位升级标志之前,必须完成两道校验:

  • 完整性校验:对整个镜像计算 SHA-256(或 CRC32),与包内元数据中的预期值比对
  • 真实性校验:用设备内置的厂商公钥对升级包签名做验签,确认包确实来自厂商而非攻击者

任何一道不通过,丢弃升级包并上报失败原因,设备继续运行旧固件,本次升级对用户无感。

4. 请求切换 ​

校验通过后,App 把"请下次从 B 槽启动"这个意图写入 Flash 中的启动参数区(boot control),然后主动重启。从这一刻起,决策权移交给 Bootloader。参数区的字段设计与读写时序是 OTA 可靠性的核心,详见 LV016-选槽与回滚机制。

5. Bootloader 引导与确认 ​

重启后 Bootloader 读取参数区,发现有待试用的新固件:

(1)再次校验新槽镜像(不信任 App 之前的结论,独立复查)

(2)校验通过则引导新固件,并记录"已尝试启动次数"

(3)新固件启动后进行自检(关键外设、通信链路、看门狗喂养正常)

(4)自检通过 → 新固件自己写参数区"确认转正"(mark good),升级完成

(5)自检失败或反复重启超过次数上限 → Bootloader 切回旧槽,回滚到旧固件

这个"试用—确认—超限回退"的机制保证了:哪怕新固件有严重 Bug 导致系统无法正常工作,设备也能自己退回旧版本,不会变砖。

四、 OTA 的核心设计目标 ​

设计任何一套 OTA 方案时,所有取舍都围绕下面四个目标展开,后文每一篇的机制分析也都会回到这四条上。

1. 原子性 ​

升级的任意时刻掉电,设备都必须处于一个确定的状态:要么还是完整的旧系统,要么是完整的新系统,绝不能是"刷了一半"的中间态。原子性靠"先写非活动区、校验通过后再原子地翻标志位"来保证。

2. 可回滚 ​

新固件自身有缺陷(能启动但功能异常、或反复崩溃)时,设备必须能自动退回旧版本。回滚的前提是旧固件的副本在升级全程不被破坏——这正是 A/B 双槽方案相比单槽复制方案的本质优势。

3. 安全性 ​

升级通道是攻击者刷入恶意固件的天然入口,必须设防:

  • 来源可信:数字签名 + 设备端公钥验签
  • 传输可信:TLS 加密,防中间人篡改
  • 版本可信:防回滚机制,禁止降级到已知有漏洞的旧版本

4. 资源可控 ​

OTA 不能影响设备正常业务:下载在后台限速进行,写 Flash 避开业务高峰,重启切换尽量快。Linux 上 A/B 方案可以做到"用户无感升级",MCU 上则通常需要接受一次短暂重启。

五、 本专题的结构与阅读路径 ​

本专题 11 篇按"原理 → 机制 → 平台方案 → 工程实践"四层组织,编号顺序即阅读顺序。四层之间是抽象递减、落地递增的关系:原理层建立共同语言,机制层讲平台无关的做法,平台层落到具体芯片,实践层处理发布与运维。

OTA 专题的四层结构

1. 各篇职责与权威主题 ​

每个主题在全专题只有一个权威出处,其余篇章只给结论并跳转,不重复展开。下表第四列即该篇的权威主题——要找某个机制的完整设计与代码,直接查这一列。

层篇目回答的问题权威主题
原理LV001-OTA全景与设计目标OTA 是什么、系统由谁构成角色架构、通用流程骨架、四个设计目标
原理LV004-升级方案维度与选型有哪些做法、怎么选存储布局对比、XIP 与 RAM 运行、触发与安装时机、升级期间可用性根因、选型决策树
机制LV007-升级包格式与传输机制包长什么样、怎么可靠送达包头格式、断点续传、分块校验、Flash 擦写约束
机制LV010-差分算法对比与嵌入式移植差分怎么真正落地差分算法对比、嵌入式移植、压缩选型、差分与 A/B 组合、补丁生成策略
机制LV013-升级通道协议字节流走哪条线UART / USB DFU / CAN UDS / BLE / 网络模组的协议实现、通道分层原则
机制LV016-选槽与回滚机制装完怎么保证还能启动启动参数区、双副本掉电安全、选槽决策、回滚状态机、看门狗配合
机制LV019-升级安全机制怎么防止被刷入假固件签名验签、信任链、防回滚、包加密、密钥管理
平台LV022-MCU无BankSwap落地方案老 MCU 上怎么落地STM32F103 分区规划、四种方案、Bootloader 完整工程、App 改造清单、开源 Bootloader 复用
平台LV025-MCU有BankSwap落地方案硬件能帮掉什么忙Bank Swap 地址映射、STM32L4/L5 实现、各系列差异、i.MX RT
平台LV028-Linux平台OTA方案Linux 上怎么用现成机制U-Boot bootcount、eMMC / NAND 分区、SWUpdate / RAUC / Mender、dm-verity、FIT 签名
工程实践LV031-发布与量产运维怎么发布、怎么测、怎么运维版本描述文件、发布流水线、灰度分批、异常注入测试、量产 FAQ

2. 阅读路径 ​

(1)只想搞懂原理:LV001 → LV004。两篇读完即可参与方案讨论,不必深入机制层。

(2)在 MCU 上落地:LV001 → LV004 → LV007 → LV013 → LV016 → LV019 → LV022 或 LV025。最后一步取决于芯片是否支持硬件 Bank Swap:不支持走 LV022,支持走 LV025。差分与流量敏感时再补 LV010。

(3)在 Linux 上落地:LV001 → LV004 → LV016 → LV019 → LV028 → LV031。机制层可跳过 LV007 与 LV013——Linux 的传输由框架与 HTTP 栈接管,不需要自己设计包格式与通道协议。

(4)排查线上升级故障:先看 LV031 的 FAQ 表定位失败阶段,再到 LV016 的异常场景推演对照掉电点行为,最后按失败阶段回到对应机制篇(下载 / 校验 → LV007,写槽 → LV022 或 LV028,启动 → LV016,验签 → LV019)。

3. 本篇的定位 ​

本篇是原理层的入口,只做三件事:说清 OTA 与 IAP / ICP 的区别(第一节)、给出"服务器—通道—设备"的角色架构(第二节)、走一遍平台无关的流程骨架(第三节)。第四节提出的原子性、可回滚、安全性、资源可控四个目标,是后续每一篇做取舍时的共同判据——机制层的每套设计,最终都要回答"它满足了这四条中的哪几条、牺牲了什么"。


本文档由 markdowncli 技能辅助生成