一、OTA概述与车载系统架构
大家好,我是你们这门课的主讲。今天咱们聊聊OTA,以及它背后的车载系统架构。
OTA,全称Over-The-Air,说白了就是空中升级。你想想看,手机系统能在线更新,汽车现在也一样。不用跑4S店,不用插线,车自己就能把系统给升级了。我最早接触车载OTA是在2018年,那时候很多车厂还在用U盘刷机的方式。说实话,那体验真不怎么样——车主得把车开到店里,技师拿个U盘插上去,等半小时...
嗯,现在不一样了。OTA已经成为智能汽车的标配功能。但要做好OTA,你得先理解车载系统的分层架构。
1.1 车载系统分层架构
车载Android系统,和手机Android系统有相似之处,但也有很大不同。我习惯把整个系统分成四层来看:
- 应用层:用户直接接触的部分。比如中控屏上的导航、音乐、设置等App。
- 框架层:Android Framework,提供各种API和服务。比如包管理服务、窗口管理服务等。
- 硬件抽象层:HAL层,把硬件差异给屏蔽掉。比如摄像头、音频、GPS等硬件接口。
- 内核层:Linux Kernel,负责驱动硬件、管理内存和进程。
这四层的关系,我画了张图,你一看就明白:
每一层都有它自己的职责。应用层只管业务逻辑,框架层提供能力支撑,HAL层屏蔽硬件差异,内核层管好底层资源。OTA升级主要影响的是系统分区,也就是框架层和内核层的内容。
1.2 A/B分区与无缝升级原理
说到OTA,就不得不提A/B分区。这是个什么概念呢?
我举个例子你就懂了。你手机升级系统的时候,是不是要重启,然后等它转圈圈?那个过程其实是在把新系统写到系统分区里。如果写一半断电了,手机就变砖了。
A/B分区的思路很简单:准备两套系统分区,一套叫A槽(slot A),一套叫B槽(slot B)。
核心思想:当前运行的系统和正在升级的系统互不干扰。升级时把新系统写到另一个槽里,写完后切换启动槽位。
具体流程是这样的:
- 下载升级包:车机从云端下载OTA升级包,存到缓存分区。
- 写入备用槽:假设当前运行在A槽,系统就把新镜像写到B槽。
- 设置启动标记:写入完成后,设置boot_control的标记,告诉Bootloader下次从B槽启动。
- 重启切换:用户下次启动车辆,Bootloader检查标记,从B槽启动。
- 回滚机制:如果B槽启动失败,Bootloader自动回滚到A槽。
我曾在某个项目里遇到过一个问题:升级包写到一半,车辆突然断电了。你猜怎么着?因为用的是A/B分区方案,车辆重新上电后,Bootloader发现B槽的校验不通过,自动切回了A槽。用户完全没感觉到升级失败,只是发现系统版本没变而已。
我的建议:做A/B分区设计时,一定要把boot_control HAL实现好。这个HAL负责管理槽位状态,包括当前槽位、是否成功启动、回滚计数等。很多坑都出在这里。
A/B分区的布局,我画个图给你看:
你看,A槽和B槽各自有一套完整的系统分区。用户数据分区是共享的,不管从哪个槽启动,用户的数据都在。
注意:千万不要在升级过程中修改userdata分区的内容。我曾经见过一个团队,在升级脚本里加了清空缓存的命令,结果把用户数据给清了。车主一上车,导航收藏夹全没了...那投诉量,啧啧。
关于无缝升级,还有个关键点:升级过程是在后台完成的。用户正常开车,系统在后台下载、校验、写入。等一切就绪,只需要一次重启就能切换到新系统。整个过程用户几乎无感知。
不过这里有个细节:升级包的大小。如果升级包太大,下载时间会很长,而且占用存储空间。我建议把升级包控制在2GB以内。怎么做?用增量升级。只打包有变化的部分,而不是整个系统镜像。
举个例子:系统A版本升级到B版本,可能只改了10个文件。增量包就只包含这10个文件的差异数据。大小可能只有200MB,而不是2GB。这样下载快,写入也快。
关键点总结:
- A/B分区是实现无缝升级的基础
- 升级时写入备用槽,不影响当前运行
- Bootloader负责槽位切换和回滚
- 增量升级可以大幅减小升级包体积
- 用户数据分区必须保持稳定
好了,这一章的内容就到这里。OTA的概念和A/B分区的原理,是后面所有章节的基础。你把这些搞懂了,后面讲具体实现的时候,就会轻松很多。
公众号:蓝海资料掘金营,微信deep3321