第二章:OTA系统架构设计
好,咱们进入正题。上一章聊了OTA升级的基本概念,这一章咱们来拆解一下整个系统的骨架——架构设计。说白了,就是搞清楚“谁负责什么,怎么连起来”。
我个人习惯把OTA系统分成三块:云端、终端、还有连接它们的通信链路。这三块缺一不可,就像人吃饭,得有菜、有锅、还得有火候。咱们一个一个来看。
2.1 云端架构:大脑和仓库
云端是OTA的大脑,也是固件包的仓库。它不光是存个文件那么简单,还得管版本、管策略、管安全。
核心模块我一般这么划分:
- 固件管理模块:负责固件包的存储、版本号管理、增量包生成。嗯,这里要注意,增量包生成算法(比如bsdiff)很吃服务器性能,我建议提前做好压力测试。
- 设备管理模块:记录每把锁的当前版本、设备ID、升级历史。说白了就是台账,谁该升级、谁升到一半断了,都得记清楚。
- 升级策略引擎:决定什么时候推、推给谁、灰度比例多少。我在项目中遇到过,一次全量推送把服务器打崩了,后来老老实实加了灰度策略。
- 安全认证模块:签名验证、设备身份校验。这个后面会细讲,但记住一句话:没有签名的OTA就是裸奔。
云端架构的避坑指南:
我曾经犯过一个错——把固件包直接放在公网可读的存储桶里。结果被人扫到了下载链接,固件被扒了个精光。后来强制加了临时签名URL,有效期只有5分钟。你想想看,这要是被竞争对手拿到,后果不堪设想。
2.2 终端架构:锁上的那点事
终端就是单车锁本身。它的资源很有限——MCU主频可能就几十兆赫,Flash和RAM都是按KB算的。所以终端架构必须精简。
我一般把终端软件分成三层:
| 层级 | 职责 | 典型模块 |
|---|---|---|
| 应用层 | 业务逻辑 | 开锁逻辑、蓝牙通信、OTA触发 |
| 中间层 | 协议解析、存储管理 | OTA协议栈、Flash分区管理、校验模块 |
| 底层 | 硬件驱动、Bootloader | Flash驱动、通信驱动、安全启动 |
这里重点说说Bootloader。它是OTA升级的“守门员”。终端上电后,先跑Bootloader,它检查有没有新固件要更新。如果有,就擦写Flash;如果没有,就跳转到应用区。
我建议Bootloader做得越简单越好。为什么?因为Bootloader一旦写复杂了,出bug的概率就大,而Bootloader出bug,锁就变砖了。我曾经见过一个项目,Bootloader里塞了蓝牙协议栈,结果升级到一半蓝牙断连,锁直接死在那了。
我的个人经验:
终端Flash分区我习惯分三块:Bootloader区、App A区、App B区。A区跑当前固件,B区存下载好的新固件。升级时先写B区,校验通过后再把启动标志切到B区。这样就算升级断电,最多回滚到A区,不会变砖。
2.3 通信链路设计:怎么把固件送过去
通信链路是连接云和端的桥梁。单车锁的通信方式,主流就两种:蓝牙和蜂窝(2G/4G/NB-IoT)。
蓝牙方案:
- 成本低,功耗低,但需要手机做中继。
- 流程:云端→手机App→蓝牙→锁。
- 我建议用MTU协商,一次传20字节太慢了,能提到512字节最好。
蜂窝方案:
- 直接连网,不需要手机,但贵,功耗高。
- 流程:云端→基站→锁。
- 注意流量费!一个固件包如果10MB,一万把锁升级一次就是100GB流量,钱哗哗的。
我个人更倾向于混合方案:日常用蓝牙,紧急升级或批量升级时走蜂窝。但不管哪种方案,通信链路都得考虑断点续传和重传机制。你想想看,锁在户外,信号时好时坏,传一半断了是常态。没有断点续传,每次都得从头传,那用户体验就太差了。
警告:
通信链路一定要做双向认证。我曾经见过一个案例,攻击者伪造了基站,向锁推送了恶意固件。原因就是锁只验证了固件签名,但没有验证通信对端的身份。后来我们在链路层加了TLS双向认证,才堵住这个漏洞。
2.4 架构设计的核心原则
说了这么多,总结几条我踩坑踩出来的原则:
- 模块解耦:云端、终端、链路各自独立演进。别让一方的改动影响另一方。
- 安全前置:架构设计阶段就要考虑安全,别等上线了再打补丁。
- 容错设计:终端要能回滚,链路要能重传,云端要有熔断机制。
- 可观测性:每个环节都要有日志和监控。不然出了问题,你都不知道是云端没推、链路断了、还是终端没收到。
嗯,这一章的内容就到这里。架构设计是OTA系统的骨架,骨架歪了,后面再怎么填肉都别扭。下一章咱们聊聊具体的升级协议设计,包括数据包格式、校验算法这些细节。到时候我会拿一个实际项目里的协议栈出来拆解,保证干货满满。