第2章:OTA系统架构设计:云端架构、车端架构、通信协议选择(MQTT/HTTP)、差分升级原理
好,我们直接进入正题。上一章聊了OTA为什么重要,这一章我们来拆解它的骨架——系统架构。
很多人一上来就纠结协议选型,或者直接写代码。我个人习惯是,先画一张大图。把云端、车端、管道这三块理清楚,后面才不会翻车。
2.1 云端架构:不只是个文件服务器
云端是OTA的大脑。它要管的事情很多:版本管理、车辆分组、策略下发、升级包生成、日志收集。说白了,它是个业务系统,不是简单的文件存储。
我建议把云端拆成几个核心模块:
- 版本管理模块:维护每个ECU的固件版本基线。你想想看,一辆车几十个ECU,每个ECU又有不同硬件版本,版本矩阵有多复杂?
- 车辆管理模块:按车型、区域、VIN范围做升级策略。比如「先给测试车队推,没问题再全量」。
- 升级包生成模块:负责做差分计算,生成增量包。这个后面细讲。
- 任务调度模块:控制升级节奏,避免全网同时下载把服务器打爆。
- 日志与监控模块:收集升级成功/失败数据,方便排查问题。
核心要点:云端架构要支持灰度发布和回滚。我在项目中遇到过,全量推送后才发现某个车型的CAN信号定义不一致,差点导致大批量刷死。从那以后,我坚持所有升级必须走灰度。
2.2 车端架构:谁来做升级的「管家」?
车端架构的关键是选一个OTA Master。它负责跟云端通信、下载包、校验、分发到各个ECU。
常见的方案有两种:
- 方案A:网关做Master。网关本身有网络连接能力,也连着CAN/FlexRay,天然适合做OTA调度。但网关的算力和存储通常有限,大包下载可能吃力。
- 方案B:座舱域控制器做Master。座舱域一般有高性能SoC,大存储,Wi-Fi/4G都方便。但要注意,它跟底盘域的安全隔离要做好。
我个人更倾向方案B。为什么?因为座舱域升级失败最多是黑屏,不会影响刹车转向。安全边界更清晰。
车端架构里还有几个关键角色:
- 下载代理:负责断点续传、校验完整性。我曾经见过一个项目,下载到99%断了,结果没做续传,整包重下,用户体验极差。
- 升级代理:负责刷写具体ECU。它要处理刷写时序、电源管理、看门狗喂狗。
- 回滚代理:刷失败了怎么办?得有备份分区或者AB系统切换机制。
避坑指南:我曾经在车端架构里忘了考虑「升级过程中车辆休眠」的问题。结果刷到一半,车进入低功耗模式,CAN通信断了,ECU变砖。后来我们加了一个「升级不休眠」的电源管理策略。
2.3 通信协议选择:MQTT vs HTTP
这是大家问得最多的问题。我直接说结论:控制信令用MQTT,文件下载用HTTP。
为什么?
| 特性 | MQTT | HTTP |
|---|---|---|
| 连接方式 | 长连接,双向推送 | 短连接,请求-响应 |
| 实时性 | 高,毫秒级推送 | 低,需要轮询 |
| 流量开销 | 低,头部极小 | 高,头部大 |
| 断点续传 | 不支持 | 支持(Range头) |
| 适用场景 | 升级指令、状态上报 | 固件包下载 |
你想想看,云端要通知一万辆车「开始升级」,如果用HTTP轮询,每辆车每隔几秒发一个请求,服务器压力多大?MQTT一条消息推下去,所有订阅的车瞬间收到。
但下载固件包就不一样了。固件包动辄几百MB,HTTP的断点续传、多线程下载、CDN加速都是现成的。MQTT不适合传大文件。
我的建议:MQTT的QoS等级选1(至少一次)。QoS0可能丢消息,QoS2太慢。我在项目中用QoS1配合去重逻辑,效果很好。
2.4 差分升级原理:只传变化的部分
差分升级是OTA的核心技术之一。说白了,就是只传输新旧固件之间的差异部分,而不是整个固件包。
举个例子:旧固件100MB,新固件102MB。如果全量下载,每次都要传102MB。但差分后,可能只有5MB的差异。对于车机流量来说,这省的不是一星半点。
差分算法有很多种,常见的有:
- bsdiff:基于二进制差分,压缩率高,但计算量大。适合座舱域这种高性能平台。
- hdiffpatch:针对嵌入式优化,内存占用小。适合MCU类ECU。
- Google的Courgette:Chrome用的算法,对可执行文件优化特别好。
差分升级的流程是这样的:
- 云端拿到新旧两个固件,运行差分算法,生成patch文件。
- 车端下载patch文件。
- 车端用旧固件 + patch文件,通过反向差分算法,还原出新固件。
- 校验新固件的完整性(MD5/SHA256)。
- 刷写新固件到目标分区。
注意:差分升级有个前提——车端必须保留旧固件。如果旧固件被删了或者损坏了,差分就玩不转了。所以,我建议车端保留至少两个版本的固件副本。
还有一个坑:差分算法对固件编译的确定性有要求。如果每次编译出来的二进制都不一样(比如时间戳、随机数),差分率会很低。我在项目中就遇到过,同一个代码两次编译,差异率高达30%。后来我们强制开启了编译的确定性模式。
2.5 小结
这一章我们聊了:
- 云端架构要管版本、车辆、任务、日志,核心是灰度发布。
- 车端架构选座舱域做Master更安全,别忘了电源管理。
- 通信协议:MQTT管信令,HTTP管下载,各司其职。
- 差分升级省流量,但要注意编译确定性和旧固件保留。
下一章,我们会深入OTA的安全设计。嗯,那才是真正让人头疼的地方。