2. 车载系统架构总览

Android Automotive OS(AAOS)并不是把手机 Android 直接搬到车机上,而是在原生 Android 框架之上,为车辆场景重新组织了一套纵向分层体系。理解这套分层,是后续开发 CarService、Vehicle HAL、车辆属性服务以及系统应用的前提。AAOS 的典型结构自下而上可划分为:硬件与内核层、HAL 层、原生服务层(Native Services)、CarService 层、应用框架层(Framework)、系统应用层(System Apps)。每一层都有明确的职责边界和跨层通信契约,任何越层调用都会带来耦合与稳定性风险。

AAOS 分层架构与关键职责 自下而上:硬件 → HAL → 原生服务 → CarService → 应用框架 → 系统应用 系统应用层 System Apps Settings / Launcher / HVAC / Media / 车辆设置 / 仪表投屏 用户可见 应用框架层 Framework Car API / CarPropertyManager / CarUxRestrictions / CarAppService SDK 契约 CarService 层(核心枢纽) CarPropertyService · CarPowerManagementService · CarUxRestrictionsService CarAudioService · CarOccupantZoneService · CarDrivingStateService 策略与仲裁 原生服务层 Native Services AudioFlinger · SurfaceFlinger · VehicleService · SensorService · PowerManager 系统能力 HAL 层 Hardware Abstraction Layer Vehicle HAL(VHAL)· Audio HAL · Camera HAL · GNSS HAL · Power HAL AIDL / HIDL 接口,属性 ID 与区域 Zone 定义 硬件抽象 硬件与内核层 Kernel / Hardware Linux Kernel · CAN / LIN / Ethernet · MCU · SoC · 传感器与执行器 物理世界 能力向上暴露 / 请求向下传递 应用开发者关注 系统服务开发者关注

一、核心原理:分层是为了隔离变化

AAOS 分层的本质是把“硬件差异”和“业务策略”分别关进不同的笼子。最底层的硬件与内核层负责驱动 CAN、LIN、以太网、MCU 等物理总线;HAL 层把不同车型、不同供应商的硬件差异抽象成统一接口;原生服务层提供音频、显示、传感器等系统级能力;CarService 层承载车辆专属的业务策略与仲裁逻辑;应用框架层把 CarService 的能力包装成稳定的 SDK;系统应用层则是最终用户直接交互的界面。

关键约束是:上层只能通过下层暴露的接口访问能力,不能跨层直连。例如应用不能直接读 VHAL,必须经过 CarPropertyManager;CarService 也不能绕过原生服务直接操作 AudioFlinger 的私有结构。

分层通信契约:应用 → Car API → CarService(Binder)→ VehicleService(Binder)→ VHAL(AIDL/HIDL)→ 内核驱动 → 硬件。

二、各层关键职责与典型对象

层级 关键职责 典型对象 / 接口
系统应用层 面向用户的 UI 与交互,调用 Car API 完成车辆控制与信息展示 Settings、Launcher、HVAC、Media、仪表投屏
应用框架层 提供稳定 SDK,做权限校验、UX 限制、跨进程封装 CarPropertyManager、CarUxRestrictions、CarAppService
CarService 层 车辆业务策略、状态仲裁、多用户与多区域管理 CarPropertyService、CarPowerManagementService、CarAudioService
原生服务层 提供音频、显示、传感器、电源等系统级基础能力 AudioFlinger、SurfaceFlinger、VehicleService、SensorService
HAL 层 抽象硬件差异,定义属性 ID、区域与访问权限 Vehicle HAL、Audio HAL、Camera HAL、GNSS HAL
硬件与内核层 驱动物理总线与外设,提供内核态能力 Linux Kernel、CAN、LIN、Ethernet、MCU、SoC

三、方法流程:一次车辆属性读取的完整链路

以“读取车速并显示在仪表”为例,完整链路如下:

  1. 系统应用调用 CarPropertyManager.getProperty(),传入属性 ID 与区域。
  2. 框架层校验调用方权限与当前 UX 限制状态。
  3. 请求通过 Binder 进入 CarService 的 CarPropertyService。
  4. CarPropertyService 向 VehicleService 订阅或查询对应属性。
  5. VehicleService 通过 AIDL/HIDL 调用 VHAL 的 get() 或等待 onPropertyEvent() 回调。
  6. VHAL 从 CAN 总线或 MCU 读取原始信号,转换为属性值并回传。
  7. 结果沿原路返回,最终由应用渲染到仪表界面。
// 应用侧读取车速属性(示意)
CarPropertyManager mgr = car.getCarManager(CarPropertyManager.class);
CarPropertyValue<Float> speed = mgr.getProperty(
        VehiclePropertyIds.PERF_VEHICLE_SPEED,
        VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
float kmh = speed.getValue();

四、案例场景:HVAC 温度调节

用户在 HVAC 应用中把主驾温度从 22℃ 调到 24℃。应用调用 Car API 写入 HVAC_TEMPERATURE_SET 属性;CarService 的 CarPropertyService 校验区域与权限后,将写请求下发到 VehicleService;VHAL 把目标温度转换为空调控制单元可识别的信号,通过 CAN 发送给空调 ECU;ECU 执行后回传实际温度,VHAL 触发属性变更事件,CarService 再通知所有订阅者,HVAC 应用刷新 UI。整个过程体现了“应用只表达意图,策略在 CarService,硬件差异在 HAL”的分工。

调试建议:排查车辆属性问题时,优先确认属性 ID、区域 Zone、访问权限(读/写)三者是否匹配,再检查 VHAL 是否真正上报了事件。

五、误区与复盘

  • 误区一:应用直接调用 VHAL。 这会导致权限失控与版本兼容问题,必须经过 CarService 与框架层。
  • 误区二:把 CarService 当成 HAL 使用。 CarService 负责策略与仲裁,不负责硬件寄存器操作。
  • 误区三:忽略区域 Zone。 多区域车型中,同一属性在不同 Zone 下取值不同,漏传 Zone 会读到错误数据。
  • 误区四:在框架层写业务策略。 策略应集中在 CarService,框架层只做封装与校验,否则升级维护困难。
复盘要点:分层架构的价值在于“变化隔离”。硬件变化止于 HAL,业务策略变化止于 CarService,SDK 变化止于框架层。任何跨层直连都会破坏这种隔离,增加整车软件迭代成本。

掌握这套分层与职责边界后,后续无论是开发 CarService 子服务、扩展 VHAL 属性,还是编写车辆系统应用,都能快速定位代码应落在哪一层、通过什么接口通信,从而避免架构性返工。