第3章:升级通道与传输协议

好,咱们直接进入正题。OTA升级,说白了就是让设备自己学会「上网更新」。但设备不是人,它得靠协议跟服务器说话。这一章我重点聊聊HTTP/HTTPS、MQTT、CoAP这三个协议在OTA里的实际用法,还有断点续传和传输安全这些绕不开的坑。

3.1 HTTP/HTTPS:最通用的OTA通道

HTTP协议在OTA里用得最多,原因很简单——成熟、稳定、工具链齐全。我做过的大多数物联网项目,初期原型都是用HTTP搭的。

但HTTP有个致命问题:它是明文传输。你想想看,固件包在网络上裸奔,谁都能抓包拿到。所以生产环境必须上HTTPS。我个人习惯是,哪怕只是内部测试,也尽量用HTTPS,省得后面忘了改。

核心要点:HTTPS的握手开销在资源受限设备上不可忽视。我遇到过一款基于ESP8266的产品,每次HTTPS握手要消耗近2KB内存,差点把堆栈撑爆。

实际项目中,我建议这样选:

  • 资源充足(>256KB RAM):直接用HTTPS,省心
  • 资源紧张:考虑HTTP+签名校验,或者用下面要讲的CoAP

3.2 MQTT:适合双向通信的升级通道

MQTT本来是为物联网消息推送设计的,但很多人用它做OTA。为什么?因为它有「发布/订阅」模型,服务器可以主动推升级通知。

我在一个智能路灯项目里用过MQTT做OTA。当时有上千个节点,如果用HTTP轮询,服务器压力太大。换成MQTT后,服务器一条消息就能触发所有设备升级,效率高得多。

实战技巧:MQTT的QoS等级要选对。OTA场景下,我建议用QoS 1(至少一次),配合应用层的重传机制。QoS 2(恰好一次)开销太大,在弱网环境下容易卡死。

MQTT做OTA的典型流程:

  1. 设备订阅升级主题(如 ota/device_id/cmd
  2. 服务器发布升级指令,包含固件URL或直接传固件分片
  3. 设备下载固件,校验,写入
  4. 设备上报升级结果到状态主题

3.3 CoAP:为资源受限设备而生

CoAP这个协议,说白了就是HTTP的「瘦身版」。它基于UDP,头部只有4字节,特别适合内存只有几十KB的MCU。

我记得有一次帮客户优化一款温湿度传感器,原来用HTTP做OTA,每次升级要花3分钟,而且经常超时。换成CoAP后,升级时间缩短到40秒,成功率从82%提升到97%。

注意:CoAP基于UDP,天然不支持大包传输。固件包超过1KB就必须分片。我建议CoAP只用于传输升级元数据(如版本号、固件哈希),实际固件下载还是走HTTP。

三种协议对比,我整理了个表:

特性 HTTP/HTTPS MQTT CoAP
传输层 TCP TCP UDP
头部开销 ~800字节 ~2字节 ~4字节
适合场景 大固件、网关设备 批量推送、双向通信 超低功耗、受限设备
安全性 HTTPS(强) TLS(可选) DTLS(可选)

3.4 断点续传机制

断点续传,说白了就是「从哪里跌倒,从哪里爬起来」。设备升级到一半断电了、断网了,总不能从头再来吧?

我做过一个户外设备,升级一次要传50MB固件。有一次测试,设备在99%的时候断网了,重新下载又花了半小时。后来加了断点续传,同样的场景只用了30秒。

实现断点续传,核心就三步:

  1. 记录进度:把已下载的字节数写到Flash的特定区域
  2. 请求续传:HTTP用 Range 头,如 Range: bytes=102400-
  3. 校验完整性:续传完成后,对整个固件做哈希校验

代码示例:HTTP断点续传请求

GET /firmware/v2.3.bin HTTP/1.1
Host: ota.example.com
Range: bytes=524288-   // 从第524288字节开始下载
User-Agent: IoTDevice/1.0

嗯,这里要注意:断点续传的进度记录一定要用原子操作。我曾经遇到过设备在写进度时掉电,结果进度数据损坏,导致固件写错位置,直接变砖。后来我改用双备份机制,写之前先擦除备份区,写成功后标记有效。

3.5 传输层安全

传输安全不是「要不要」的问题,而是「怎么做」的问题。我见过太多设备因为没做传输加密,固件被篡改后植入恶意代码。

传输层安全分三个层次:

  • 基础层:TLS/DTLS加密通道,防止窃听和篡改
  • 增强层:固件签名+证书校验,防止伪造服务器
  • 极限层:硬件安全模块(HSM/SE),密钥不出芯片

避坑指南:我曾经在项目里只做了TLS,没做证书固定(Certificate Pinning)。结果测试时发现,只要中间人伪造一个CA签发的证书,就能轻松劫持升级流量。从那以后,我所有项目都强制做证书固定。

对于资源受限设备,DTLS是更好的选择。它基于UDP,握手开销比TLS小很多。我建议这样配置:

  • 使用PSK(预共享密钥)模式,避免证书处理
  • 会话复用,减少握手次数
  • 握手超时设为5秒,避免死等

最后说一句:传输安全是OTA的底线。你想想看,如果升级通道都不安全,那后面的校验、回滚做得再好也没用。我个人习惯是,安全投入至少占OTA开发时间的30%。

警告:不要为了省资源而省略传输加密。我见过一个团队为了省2KB内存,用明文HTTP传固件,结果产品上市第三天就被黑客远程控制了。省下的成本,远不够赔的。

好了,这一章就到这里。下一章我们聊聊固件包的差分算法和压缩策略,那才是真正考验嵌入式工程师功底的地方。