车载 HAL 与 Android Automotive 架构
- Car API:内有包含
CarSensorManager
在内的 API。如需详细了解受支持的 API,请参阅/platform/packages/services/Car/car-lib
。 - CarService:位于
/platform/packages/services/Car/
。 - 车载 HAL:用于定义 OEM 可以实现的车辆属性的接口。包含属性元数据(例如,车辆属性是否为 int 以及允许使用哪些更改模式)。位于
hardware/libhardware/include/hardware/vehicle.h
。如需了解基本参考实现,请参阅hardware/libhardware/modules/vehicle/
。
Automotive | Android Open Source Project
汽车框架核心 | Android Open Source Project
汽车框架核心
传统 Android 堆栈和汽车堆栈之间的区别:
● 汽车专用应用使用汽车 API 来访问汽车服务实现的功能。
● 汽车服务通过 CarServiceHelperService 与系统服务器通信,以访问核心 Android 功能。
● CarServiceHelperService 的主要目的是启动汽车服务。但是,当没有指定 API 与系统服务器通信时,将使用 CSHS。
● 汽车服务还连接到汽车专用的本机服务,例如 CarWatchdog。这些服务在系统服务器和汽车服务初始化之前处理汽车专用的任务。
● 使用车辆 HAL 和汽车专用 HAL 抽象出汽车硬件
Car Service
● 汽车服务提供汽车特定功能和策略的实现。它允许应用程序与汽车硬件交互。
● 汽车服务 (com.android.car) 以用户 0 身份运行,可以为所有用户提供服务,无论用户切换如何。
● 另一个版本 (CarPerUserService) 为用户 10+ 运行
○ 这是因为蓝牙和 LocationManager 仅适用于当前用户。
○ 此服务仅供内部汽车服务使用,不直接提供任何汽车 API。
● 在客户端应用程序中创建 Car 对象时,它将包含一个 ICar Binder 对象,以便它可以与 Car Service 通信。
● ICarImpl 负责创建各种 CarXYZServices 并实现应用程序与之交互的 ICar.aidl 接口。
Car Managers
● 应用程序用来访问汽车服务功能的共享库。
● 公开汽车特定的 API 功能。
● 每个 CarXYZManager 都有一个关联的 CarXYZService对应项。
● CarXYZManagers 使用 AIDL 文件定义的 ICarXYZService 绑定接口与各个 CarXYZServices 进行通信。
● CarXYZServices 还与汽车服务内的 XYZHalServices 进行通信
使用Car APIs
1 | private void init() { |
监听CarService崩溃重新获取。
1 | private void init() { |
CarAPI
packages/services/Car/car-lib/ aidl接口,客户端IBinder对象在Car API中被封装在一个个XXXManager
类中,列举其中几个
- CarActivityManager:运行Task状态监听,设置
- CarDrivingStateManager:车辆运动状态监听
- CarAudioManager:声音相关
- CarMediaManager:多媒体播放源相关
- CarPropertyManager:车辆相关,空调车门车窗等数据设置获取和监听
CarService启动
启动CarServiceHelperService
1 | private static final String CAR_SERVICE_HELPER_SERVICE_CLASS = |
CarServiceHelperService中执行onStart
1 | //frameworks/opt/car/services/builtInServices/src/com/android/internal/car/CarServiceHelperService.java |
启动CarService
1 | //packages/services/Car/service-builtin/src/com/android/car/CarService.java |
ICarImpl创建
1 | ICarImpl(Context serviceContext, Context builtinContext, VehicleStub vehicle, |
CarService的服务已经启动,再看下CarPropertyService的具体流程。
CarPropertyService
客户端CarPropertyManager
以获取VIN为例分析下流程
1 | services/Car/car-lib/src/android/car/VehiclePropertyIds.java |
服务端代码
1 | //services/Car/service/src/com/android/car/CarPropertyService.java |
mHal是CarPropertyService创建的时候传递的参数
1 | public CarPropertyService(Context context, PropertyHalService hal) { |
获取VIN的流程已经执行到了HalClient#internalGet中的mVehicle.get代码,mVehicle是VehicleStub的对象
1 | //VehicleStub.java |
看下AidlVehicleStub的get方法
1 | private final IVehicle mAidlVehicle; |
IVehicle.aidl在下面的目录中,这块属于hal层的vehicle代码,CarService通过Binder跨进程通信
hardware/interfaces/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/1/android/hardware/automotive/vehicle/IVehicle.aidl
aidl确实方便,比hidl少了好多步骤。在继续分析下Vehicle hal层的代码
Vehicle hal
hardware/libhardware/modules/vehicle/
在VehicleProperty.aidl中INFO_VIN跟VehiclePropertyIds.java的也是对应上的
1 | //VehicleProperty |
HIDL | Android Open Source Project
AIDL 概览 | Android Open Source Project
服务启动
1 | service vendor.vehicle-hal-default /vendor/bin/hw/android.hardware.automotive.vehicle@V1-default-service |
服务声明
1 | <manifest version="1.0" type="device"> |
Android.bp
1 | cc_binary { |
VehicleService.cpp
1 |
|
采用双层架构。上层是 DefaultVehicleHal
,实现了 VHAL AIDL 接口,并提供适用于所有硬件设备的通用 VHAL 逻辑。下层是 FakeVehicleHardware
,实现了 IVehicleHardware
接口。此类可模拟与实际硬件或车载总线交互的 VHAL 逻辑,并且特定于设备。供应商也可以视需要调整这一架构,重复使用同一 DefaultVehicleHal
类(扩展该类以覆盖某个方法),并提供自己的 IVehicleHardware
实现。
DefaultVehicleHal的构造函数
1 | //hardware/interfaces/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp |
BnVehicle是IVehicle.aidl的服务端实现,CarService远程调用到这个地方
看下客户端调用的mAidlVehicle.getValues(mGetSetValuesCallback, requests);对应这个方法
1 | //hardware/interfaces/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp |
FakeVehicleHardware继承于IVehicleHardware,因此会调用FakeVehicleHardware的getValues
1 | StatusCode FakeVehicleHardware::getValues(std::shared_ptr<const GetValuesCallback> callback, |
把GetValue添加到RequestmPendingGetValueRequests
1 | template <class CallbackType, class RequestType> |
handleRequestsOnce方法
1 | void FakeVehicleHardware::PendingRequestHandler<FakeVehicleHardware::GetValuesCallback, |
mServerSidePropStore是VehiclePropertyStore。
FakeVehicleHardware模拟与实际硬件或车载总线交互的VHAL逻辑。它使用内存中的映射来存储属性值,并且不与实际的车载总线通信。
VehiclePropertyStore就是用来存储和管理车辆属性的配置。模拟器修改的配置也会通过这个保存,没有硬件相关的交互,就是存储数据,通知数据。
实际开发中FakeVehicleHardware需要修改调用驱动的接口,比如向CAN或者串口读写数据,或者使用socket通信,跟相关的ECU通信,可以接入SOME/IP或FDBus。
(一) 车载以太网通信之SOME/IP协议_someip协议-CSDN博客 这篇SOME/IP系列文章很推荐。
VHAL 接口 | Android Open Source Project 车辆属性相关参考官方文档。