17、系统更新(OTA):A/B 分区更新策略,Seamless Update 在车机上的适配
聊到车机OTA,很多人的第一反应就是“手机怎么升级,车机就怎么升级呗”。
嗯,这话对了一半。手机升级失败了最多变砖,你拿去售后刷一下就好。
但车机要是升级到一半断电了,或者系统起不来了,那可是要出大事的——车可能直接趴窝,甚至影响安全。
所以,Android Automotive OS 在OTA这块,做了一个非常关键的设计:A/B 分区无缝更新。
说白了,就是让你在不知不觉中完成系统升级,而且就算升级失败,车也能正常开。
17.1 什么是 A/B 分区?
传统Android系统只有一个 system 分区,升级时直接覆盖写入。
一旦写入过程中断电或出错,系统就挂了。
A/B 分区的思路很简单:准备两套分区,一套叫 slot A,一套叫 slot B。
我打个比方:
你正在用 slot A 开车,系统在后台偷偷往 slot B 里写新版本。
写完了,下次重启时自动切到 slot B。
如果 slot B 起不来,系统还能自动回退到 slot A。
这就是所谓的“无缝更新”(Seamless Update)。
用户几乎感知不到升级过程,唯一的变化就是——重启了一次。
- system_a
- system_b
- vendor_a
- vendor_b
- product_a
- product_b
- boot_a
- boot_b
- ... 其他分区同理
每个 slot 都是一套完整的系统镜像。
当前使用的 slot 叫“active slot”,另一个叫“inactive slot”。
17.2 更新流程:到底怎么“无缝”?
整个流程分三步走:
- 下载阶段:系统在后台下载 OTA 包,写入 inactive slot。
- 切换阶段:下载完成后,标记 inactive slot 为“可启动”。
- 重启阶段:用户重启后,bootloader 读取标记,启动新 slot。
这里有个细节:
下载和写入是同时进行的,不是先下载完再写。
OTA 包是流式处理的,边下载边解压边写入。
这样做的好处是——不需要预留两倍的空间。
我在项目中遇到过一个问题:
某个车机存储空间只有 32GB,A/B 两套系统加上用户数据,空间非常紧张。
后来我们启用了“压缩写入”和“增量 OTA”,才把空间压下来。
嗯,这里要注意,车机的存储成本比手机敏感得多。
17.3 Seamless Update 在车机上的特殊适配
手机上的无缝更新,基本就是上面那套流程。
但车机不一样,有几个关键点需要单独处理。
17.3.1 电源管理
车机升级最怕什么?
怕升级到一半,用户熄火走人了。
手机可以靠电池撑着,车机不行——车一断电,系统直接掉电。
所以,车机 OTA 必须做“电源守护”:
- 升级过程中,如果检测到车辆进入“熄火”状态,系统会尝试保持供电一段时间。
- 如果电量不足,必须暂停升级,并标记“升级未完成”。
- 下次车辆上电时,继续从断点处写入。
我曾经调试过一个 case:
某款车在升级时,用户突然拔了钥匙,结果 slot B 写了一半。
下次启动时,bootloader 检测到 slot B 不完整,自动回退到 slot A。
用户完全没感觉,但升级失败了。
后来我们加了一个“升级进度持久化”的逻辑,才解决这个问题。
17.3.2 用户交互
手机升级时,用户能看到进度条,还能选择“立即重启”或“稍后重启”。
车机不行——驾驶员不能分心看进度条。
所以,车机的 OTA 交互设计原则是:尽量无感。
- 下载阶段:后台静默进行,不打扰用户。
- 切换阶段:只在车辆熄火且处于安全状态时,才提示“系统将重启”。
- 重启阶段:重启过程要快,最好在 30 秒内完成。
我个人的习惯是:
在车机设置里放一个“系统更新”入口,用户可以查看当前版本和更新状态。
但不要主动弹窗,更不要强制升级。
17.3.3 分区大小与存储布局
车机的硬件配置差异很大。
有的车机存储 64GB,有的只有 16GB。
A/B 分区意味着每个分区都要 double,存储压力翻倍。
解决方案有几个:
- 动态分区:不固定分区大小,按需分配。
- 虚拟 A/B:只对关键分区做 A/B,非关键分区用 overlay 方式。
- 增量 OTA:只传输差异部分,而不是完整镜像。
我建议:
如果你的车机存储小于 32GB,一定要上虚拟 A/B。
否则,用户装几个 App 就没空间了,升级都升不了。
17.4 核心流程图:A/B 分区更新状态机
下面这张图,是我自己画的一个简化版状态机。
它展示了从“当前 slot A 运行”到“切换到 slot B 成功”的完整过程。
17.5 避坑指南:我踩过的几个坑
做车机 OTA 这几年,我踩过不少坑。
挑几个典型的说说,希望能帮你少走弯路。
有一次,我们给某款车配了 16GB 存储,结果 A/B 分区各占 6GB,用户数据只剩 4GB。
用户装几个导航地图就满了,OTA 包都下载不下来。
后来我们改成虚拟 A/B,才把用户数据空间释放出来。
车机在升级时,如果进入休眠模式,写入速度会骤降,甚至导致写入超时。
我当时的解决方案是:在升级期间,强制保持 CPU 唤醒,并关闭屏幕以省电。
有一次升级后,新系统起不来。
查了半天,发现是 bootloader 版本太旧,不认识新分区的格式。
从那以后,我每次做 OTA 都会检查 bootloader 的兼容性。
17.6 总结
A/B 分区更新策略,是 Android Automotive OS 保证系统可靠性的核心设计。
它让车机升级变得安全、无感,甚至可以在用户不知情的情况下完成。
但车机的特殊性——电源不稳定、存储有限、安全要求高——让这套策略在落地时多了不少挑战。
我个人觉得,做车机 OTA 最重要的不是技术有多炫,而是“稳”。
宁可升级慢一点,也别让车趴窝。
如果你刚开始做车机 OTA,建议先从“虚拟 A/B”入手。
它比完整 A/B 更省空间,而且 Google 在 Android 12 之后已经把它作为默认方案了。
公众号:蓝海资料掘金营,微信 deep3321