Android Automotive HAL 框架对比
1. 整体架构层次
应用层
↓
Framework (CarService, CarManager)
↓
HIDL/AIDL
↓
hardware/interfaces/automotive/ ← 接口定义
↓
hardware/libhardware/include/hardware/ ← 传统 HAL
↓
供应商实现
↓
Linux Kernel
2. hardware/interfaces/automotive/
位置和用途
bash
# 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:跨进程通信
示例代码结构
c++
// 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/
位置和用途
bash
# 传统 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 在应用进程内运行
示例代码结构
c
// hardware.h
typedef struct hw_module_t {
uint32_t tag;
uint16_t module_api_version;
const char* id;
const char* name;
const char* author;
struct hw_module_methods_t* methods;
} hw_module_t;
// 音频 HAL
struct audio_hw_device {
struct hw_device_t common;
int (*set_voice_volume)(struct audio_hw_device* dev, float volume);
int (*set_master_volume)(struct audio_hw_device* dev, float volume);
// ... 更多音频操作
};
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
// Java 层调用
IVehicle vehicle = IVehicle.getService();
vehicle.get(VehicleProperty.INFO_VIN, (status, value) -> {
Log.d("VIN: " + value.stringValue);
});
// 服务端实现 (C++)
class VehicleHal : public IVehicle {
Return<void> get(const VehiclePropValue& prop, get_cb _hidl_cb) {
// 从车辆总线读取数据
int32_t value = readCanBus(prop.prop);
_hidl_cb(StatusCode::OK, {prop, value});
return Void();
}
};
xml
<!-- 权限配置 -->
<hal format="hidl">
<name>android.hardware.automotive.vehicle</name>
<transport>hwbinder</transport>
<version>2.0</version>
<interface>
<name>IVehicle</name>
<instance>default</instance>
</interface>
</hal>
传统 HAL 示例
c
// 定义传统 HAL
struct vehicle_module_t {
struct hw_module_t common;
int (*get_vin)(struct vehicle_device_t* dev, char* vin, size_t len);
int (*get_speed)(struct vehicle_device_t* dev, float* speed);
};
// 加载和使用
int load_vehicle_hal() {
const hw_module_t* module;
int err = hw_get_module(VEHICLE_HARDWARE_MODULE_ID, &module);
vehicle_device_t* dev;
err = module->methods->open(module, "vehicle", (hw_device_t**)&dev);
char vin[32];
dev->get_vin(dev, vin, sizeof(vin));
return 0;
}
6. 迁移示例:从传统到新架构
c
// 传统 HAL (旧)
struct legacy_vehicle_device {
struct hw_device_t common;
int (*get_property)(int prop, 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(const VehiclePropValue& prop, get_cb _hidl_cb) {
VehiclePropValue result = prop;
// 兼容旧接口
if (mLegacyHal != nullptr) {
int legacyValue;
mLegacyHal->get_property(prop.prop, &legacyValue);
result.value.int32Values[0] = legacyValue;
}
_hidl_cb(StatusCode::OK, result);
return Void();
}
private:
legacy_vehicle_device* mLegacyHal = nullptr;
};
7. 在汽车场景的具体应用
车辆属性服务对比
java
// 新架构:通过 Vehicle HAL 2.0
public class CarPropertyManager {
private IVehicle mVehicle;
public int getSpeed() {
VehiclePropValue request = new VehiclePropValue();
request.prop = VehicleProperty.PERF_VEHICLE_SPEED;
mVehicle.get(request, (status, value) -> {
if (status == StatusCode.OK) {
return value.value.floatValues[0];
}
});
}
}
// 传统方式:通过 libhardware
public class LegacyCarManager {
static {
System.loadLibrary("vehicle_hal");
}
public native int getSpeed(); // 通过 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.h
10. 总结
| 方面 | hardware/interfaces/automotive/ | hardware/libhardware/include/hardware |
|---|---|---|
| 设计理念 | 现代、安全、可扩展 | 传统、简单、直接 |
| 适用场景 | 汽车信息娱乐系统、复杂功能 | 简单硬件抽象、嵌入式系统 |
| 发展趋势 | 主推方向,持续更新 | 维护模式,新项目不推荐 |
| 学习曲线 | 较陡,需要了解 Binder/HIDL | 较平缓,C 语言为主 |
| 社区支持 | Google 官方支持,文档丰富 | 社区维护,逐渐淘汰 |
建议 :新项目优先使用 hardware/interfaces/automotive/ 架构,特别是 Android Automotive OS 相关开发。传统 HAL 主要用于维护旧代码或特殊性能需求场景。