Android Automotive HAL 框架对比
1.整体架构层次
应用层 ↓ Framework (CarService, CarManager) ↓ HIDL/AIDL ↓ hardware/interfaces/automotive/ ← 接口定义 ↓ hardware/libhardware/include/hardware/ ← 传统 HAL ↓ 供应商实现 ↓ Linux Kernel2.hardware/interfaces/automotive/
位置和用途
# Android 代码树位置hardware/interfaces/automotive/ ├── vehicle/ │ ├──2.0/# HIDL 接口定义│ │ ├── IVehicle.h │ │ ├── types.h │ │ └── IVehicleCallback.h │ └──1.0/ ├── can/ │ └──1.0/# CAN 总线接口├── audiocontrol/ │ └──1.0/# 音频控制接口└── sv/ └──1.0/# 共享内存接口主要特点
- 基于 HIDL/AIDL:Android 8.0+ 的新 HAL 架构
- 进程隔离:HAL 运行在独立进程
- 版本化接口:支持接口版本升级
- Binder IPC:跨进程通信
示例代码结构
// IVehicle.h (HIDL 接口) package android.hardware.automotive.vehicle@2.0; interface IVehicle { // 获取车辆属性 get(PropValue prop, get_cb _hidl_cb); // 设置车辆属性 set(PropValue prop); // 订阅事件 subscribe(IVehicleCallback callback, SubscribeOptions options); };3.hardware/libhardware/include/hardware/
位置和用途
# 传统 HAL 位置hardware/libhardware/include/hardware/ ├── hardware.h# HAL 核心头文件├── sensors.h# 传感器 HAL├── gps.h# GPS HAL├── camera.h# 相机 HAL├── audio.h# 音频 HAL└── hw_module_t.h# 模块定义主要特点
- 传统 HAL 架构:Android 8.0 之前的标准
- 动态库形式:.so 库直接加载
- C 语言接口:兼容性好
- 进程内调用:HAL 在应用进程内运行
示例代码结构
// hardware.htypedefstructhw_module_t{uint32_ttag;uint16_tmodule_api_version;constchar*id;constchar*name;constchar*author;structhw_module_methods_t*methods;}hw_module_t;// 音频 HALstructaudio_hw_device{structhw_device_tcommon;int(*set_voice_volume)(structaudio_hw_device*dev,floatvolume);int(*set_master_volume)(structaudio_hw_device*dev,floatvolume);// ... 更多音频操作};4.详细对比表
| 特性 | hardware/interfaces/automotive/ | hardware/libhardware/include/hardware/ |
|---|---|---|
| 接口语言 | HIDL (.hal) / AIDL | C 语言 |
| 通信方式 | Binder IPC | 直接函数调用 |
| 进程模型 | 独立进程 | 进程内库 |
| 版本管理 | 内置版本控制 | 手动版本管理 |
| 安全性 | SELinux 策略隔离 | 依赖进程边界 |
| 兼容性 | 向前兼容 | 二进制兼容 |
| 构建系统 | Android.bp | Android.mk |
| 调试难度 | 较高(跨进程) | 较低 |
5.实际使用示例对比
新架构示例 (Vehicle HAL 2.0)
// Java 层调用IVehiclevehicle=IVehicle.getService();vehicle.get(VehicleProperty.INFO_VIN,(status,value)->{Log.d("VIN: "+value.stringValue);});// 服务端实现 (C++)classVehicleHal:publicIVehicle{Return<void>get(constVehiclePropValue&prop,get_cb _hidl_cb){// 从车辆总线读取数据int32_t value=readCanBus(prop.prop);_hidl_cb(StatusCode::OK,{prop,value});returnVoid();}};<!-- 权限配置 --><halformat="hidl"><name>android.hardware.automotive.vehicle</name><transport>hwbinder</transport><version>2.0</version><interface><name>IVehicle</name><instance>default</instance></interface></hal>传统 HAL 示例
// 定义传统 HALstructvehicle_module_t{structhw_module_tcommon;int(*get_vin)(structvehicle_device_t*dev,char*vin,size_tlen);int(*get_speed)(structvehicle_device_t*dev,float*speed);};// 加载和使用intload_vehicle_hal(){consthw_module_t*module;interr=hw_get_module(VEHICLE_HARDWARE_MODULE_ID,&module);vehicle_device_t*dev;err=module->methods->open(module,"vehicle",(hw_device_t**)&dev);charvin[32];dev->get_vin(dev,vin,sizeof(vin));return0;}6.迁移示例:从传统到新架构
// 传统 HAL (旧)structlegacy_vehicle_device{structhw_device_tcommon;int(*get_property)(intprop,void*value);};// 新架构 HAL (新)#include<android/hardware/automotive/vehicle/2.0/IVehicle.h>using namespace android::hardware::automotive::vehicle::V2_0;class ModernVehicleHal:public IVehicle{public:Return<void>get(constVehiclePropValue&prop,get_cb _hidl_cb){VehiclePropValue result=prop;// 兼容旧接口if(mLegacyHal!=nullptr){intlegacyValue;mLegacyHal->get_property(prop.prop,&legacyValue);result.value.int32Values[0]=legacyValue;}_hidl_cb(StatusCode::OK,result);returnVoid();}private:legacy_vehicle_device*mLegacyHal=nullptr;};7.在汽车场景的具体应用
车辆属性服务对比
// 新架构:通过 Vehicle HAL 2.0publicclassCarPropertyManager{privateIVehiclemVehicle;publicintgetSpeed(){VehiclePropValuerequest=newVehiclePropValue();request.prop=VehicleProperty.PERF_VEHICLE_SPEED;mVehicle.get(request,(status,value)->{if(status==StatusCode.OK){returnvalue.value.floatValues[0];}});}}// 传统方式:通过 libhardwarepublicclassLegacyCarManager{static{System.loadLibrary("vehicle_hal");}publicnativeintgetSpeed();// 通过 JNI 调用 C HAL}8.开发建议和选择
何时使用 hardware/interfaces/automotive/
✅推荐使用新架构的情况:
- 新项目开发
- 需要更好的安全性隔离
- 需要接口版本控制
- 多供应商集成
- Android Automotive OS 开发
- 需要与 Framework Service 深度集成
何时使用传统 HAL
✅可能使用传统 HAL 的情况:
- 维护旧有代码
- 性能要求极高的场景
- 简单的硬件抽象
- 资源受限的设备
- 没有 IPC 开销需求
9.实际项目结构示例
# 现代汽车 HAL 项目结构 packages/services/Car/ ├── service/ │ └── CarService.java ├── vehicle/ │ └── 2.0/ │ ├── default/ │ │ └── Vehicle.cpp │ ├── vts/ │ │ └── VtsHalAutomotiveVehicleTest.cpp │ └── Android.bp └── Android.mk # 传统 HAL 项目结构 hardware/ ├── libhardware/ │ ├── include/hardware/ │ │ └── vehicle.h │ └── modules/vehicle/ │ ├── vehicle.c │ └── Android.mk └── interfaces/automotive/vehicle/1.0/ └── IVehicle.h10.总结
| 方面 | hardware/interfaces/automotive/ | hardware/libhardware/include/hardware |
|---|---|---|
| 设计理念 | 现代、安全、可扩展 | 传统、简单、直接 |
| 适用场景 | 汽车信息娱乐系统、复杂功能 | 简单硬件抽象、嵌入式系统 |
| 发展趋势 | 主推方向,持续更新 | 维护模式,新项目不推荐 |
| 学习曲线 | 较陡,需要了解 Binder/HIDL | 较平缓,C 语言为主 |
| 社区支持 | Google 官方支持,文档丰富 | 社区维护,逐渐淘汰 |
建议:新项目优先使用hardware/interfaces/automotive/架构,特别是 Android Automotive OS 相关开发。传统 HAL 主要用于维护旧代码或特殊性能需求场景。