前言
前面的文章中,描述了 Android Automotive 的框架中应用、Framework 层服务等知识,本篇文章将会继续按照 Android Automotive 框架介绍 Vehicle Hal 层服务的内容。
上一篇:AndroidAutomotive模块介绍(三)CarService服务
正文
1、VehicleHal 介绍
本篇文档将对 Andorid Automotive 框架中 VehicleHal 层展开介绍。VehicleHal 即为车辆硬件抽象层的定义。可以理解为 Android Automotive OS 中的硬件抽象层接口,包括车辆属性和方法;各厂商制造商会根据定义的 Hal 接口,实现定制化的模块服务。
VehicleHal 是链接 Android Automotive Car Services 与制造商实现车辆控制服务进程的桥梁,通过标准化接口对上层提供服务,对于服务的实现依赖厂商的定制化,可以忽略汽车制造商的具体实现,也就是说 CarService 调用 VehicleHal 定义的标准接口,厂商实现这些接口。
2、VehicleHal 模块功能
2.1 rc 文件
VehicleHal 的代码路径为:android/hardware/interfaces/automotive/vehicle/2.0/default。路径下有 android.hardware.automotive.vehicle@2.0-service.rc 文件,在开机阶段通过此 rc 文件,将 VehicleHal 进程启动,下面来看下 android.hardware.automotive.vehicle@2.0-service.rc 文件的定义
service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service
class hal
user vehicle_network
group system inet
2.2 编译
对于 VehicleHal 的编译,可以对以下两个 Android.bp 文件介绍。
- Hidl 接口编译
- VehicleHal 服务编译
VehicleHal 定义的 Hal 接口编译介绍,Android.bp 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0,目录结构如下:
ubuntu:android/hardware/interfaces/automotive/vehicle/2.0$ ls -l
total 132
-rw-r--r-- 1 users 375 Nov 9 2022 Android.bp
drwxrwxr-x 5 users 4096 Mar 22 13:55 default
-rw-r--r-- 1 users 2336 Nov 9 2022 IVehicleCallback.hal
-rw-r--r-- 1 users 3665 Nov 9 2022 IVehicle.hal
-rw-r--r-- 1 users 115184 Nov 9 2022 types.hal
下面是 Android.bp 文件的定义:
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "android.hardware.automotive.vehicle@2.0",
root: "android.hardware",
vndk: {
enabled: true,
},
srcs: [
"types.hal",
"IVehicle.hal",
"IVehicleCallback.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
gen_java: true,
}
编译文件中定义了 android.hardware.automotive.vehicle@2.0 HIDL 接口编译,包含三个文件 types.hal、IVehicle.hal、IVehicleCallback.hal 文件。
VehicleHal 服务编译介绍,Android.bp 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0/default,目录结构如下:
ubuntu16:android/hardware/interfaces/automotive/vehicle/2.0/default$ ls -l
total 28
-rw-r--r-- 1 users 4705 Nov 9 2022 Android.bp
-rw-r--r-- 1 users 155 Nov 9 2022 android.hardware.automotive.vehicle@2.0-service.rc
drwxrwxr-x 4 users 4096 Jun 7 2022 common
drwxrwxr-x 3 users 4096 Jun 7 2022 impl
drwxrwxr-x 2 users 4096 Nov 9 2022 tests
-rw-r--r-- 1 users 1953 Nov 9 2022 VehicleService.cpp
Android.bp 文件定义如下:
// Vehicle reference implementation lib
cc_library {
name: "android.hardware.automotive.vehicle@2.0-manager-lib",
vendor: true,
defaults: ["vhal_v2_0_defaults"],
srcs: [
"common/src/Obd2SensorStore.cpp",
"common/src/SubscriptionManager.cpp",
"common/src/VehicleHalManager.cpp",
"common/src/VehicleObjectPool.cpp",
"common/src/VehiclePropertyStore.cpp",
"common/src/VehicleUtils.cpp",
"common/src/VmsUtils.cpp",
],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["common/include"],
}
// Vehicle default VehicleHAL implementation
cc_library_static {
name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
vendor: true,
cflags: ["-Wno-unused-parameter", "-Wno-sign-compare"],
defaults: ["vhal_v2_0_defaults"],
srcs: [
"impl/vhal_v2_0/CommConn.cpp",
"impl/vhal_v2_0/EmulatedVehicleHal.cpp",
"impl/vhal_v2_0/VehicleEmulator.cpp",
"impl/vhal_v2_0/PipeComm.cpp",
"impl/vhal_v2_0/SocketComm.cpp",
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["impl"],
whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
shared_libs: [
"libbase",
"libprotobuf-cpp-lite",
],
static_libs: [
"libjsoncpp",
"libqemu_pipe",
"android.hardware.automotive.vehicle@2.0-libproto-native",
],
}
cc_binary {
name: "android.hardware.automotive.vehicle@2.0-service",
defaults: ["vhal_v2_0_defaults"],
init_rc: ["android.hardware.automotive.vehicle@2.0-service.rc"],
vendor: true,
relative_install_path: "hw",
srcs: ["VehicleService.cpp"],
shared_libs: [
"libbase",
"libprotobuf-cpp-lite",
],
static_libs: [
"android.hardware.automotive.vehicle@2.0-manager-lib",
"android.hardware.automotive.vehicle@2.0-default-impl-lib",
"android.hardware.automotive.vehicle@2.0-libproto-native",
"libjsoncpp",
"libqemu_pipe",
],
}
从 Android.bp 的定义中,VehicleHal 的服务名为 android.hardware.automotive.vehicle@2.0-service,启动 rc 文件是 android.hardware.automotive.vehicle@2.0-service.rc,入口文件是 VehicleService.cpp,依赖自定义相关模块主要有 android.hardware.automotive.vehicle@2.0-manager-lib、android.hardware.automotive.vehicle@2.0-default-impl-lib、android.hardware.automotive.vehicle@2.0-libproto-native。
android.hardware.automotive.vehicle@2.0-manager-lib 模块是 common 目录下的文件所编译的内容,主要是 VehicleHal 所以来的模块。
android.hardware.automotive.vehicle@2.0-default-impl-lib 模块是 impl 目录下的文件所编译的内容,主要是 VehicleHal 的功能实现模块。
android.hardware.automotive.vehicle@2.0-libproto-native 模块是 impl/vhal_v2_0/proto 目录下的文件所编译的内容,目录下的文件为 VehicleHalProto.proto 文件,是一种序列化存储数据的方式。
2.3 HIDL 接口
Android Automotive 框架中 Hal 层接口文件有三个,IVehicle.hal、IVehicleCallback.hal 和 types.hal 文件。IVehicle.hal 文件中定义了 Vehicle Hal 对外提供的接口;IVehicleCallback.hal 文件中定义了 VehicleHal 的回调接口;types.hal 文件定义了 Vehicle Hal 的属性定义。
Hidl 文件路径为:android/hardware/interfaces/automotive/vehicle/2.0。
2.3.1 IVehicle.hal
IVehicle.hal 文件中定义了 Vehicle Hal 对外提供的接口,上层 CarService 通过 IVehicle.hal 中定义的接口与 Vehicle Hal 通信。
package android.hardware.automotive.vehicle@2.0;
import IVehicleCallback;
interface IVehicle {
/**
* Returns a list of all property configurations supported by this vehicle
* HAL.
* 返回此车辆HAL支持的所有属性配置的列表
*/
getAllPropConfigs() generates (vec<VehiclePropConfig> propConfigs);
/**
* Returns a list of property configurations for given properties.
*
* If requested VehicleProperty wasn't found it must return
* StatusCode::INVALID_ARG, otherwise a list of vehicle property
* configurations with StatusCode::OK
* 返回给定属性的属性配置列表。
* 如果请求的车辆属性没有找到,它必须返回StatusCode::INVALID_ARG,否则返回一个车辆属性配置列表,StatusCode::OK
*/
getPropConfigs(vec<int32_t> props)
generates (StatusCode status, vec<VehiclePropConfig> propConfigs);
/**
* Get a vehicle property value.
*
* For VehiclePropertyChangeMode::STATIC properties, this method must always
* return the same value always.
* For VehiclePropertyChangeMode::ON_CHANGE properties, it must return the
* latest available value.
*
* Some properties like RADIO_PRESET requires to pass additional data in
* GET request in VehiclePropValue object.
*
* If there is no data available yet, which can happen during initial stage,
* this call must return immediately with an error code of
* StatusCode::TRY_AGAIN.
* 获取车辆属性值。
* 对于 VehiclePropertyChangeMode::STATIC 的属性值,此方法会返回同一个值,不会改变。
* 对于 VehiclePropertyChangeMode::ON_CHANGE 的属性值,此方法会返回最新值。
*/
get(VehiclePropValue requestedPropValue)
generates (StatusCode status, VehiclePropValue propValue);
/**
* Set a vehicle property value.
*
* Timestamp of data must be ignored for set operation.
*
* Setting some properties require having initial state available. If initial
* data is not available yet this call must return StatusCode::TRY_AGAIN.
* For a property with separate power control this call must return
* StatusCode::NOT_AVAILABLE error if property is not powered on.
* 设置车辆属性值。
* 特殊场景:
* 设置一些属性值需要其初始状态可用,如果初始状态不可用,需要返回 StatusCode::TRY_AGAIN。
* 设置单独电源控制的属性,如果属性未上电,需要返回 StatusCode::TRY_AGAIN。
*/
set(VehiclePropValue propValue) generates (StatusCode status);
/**
* Subscribes to property events.
*
* Clients must be able to subscribe to multiple properties at a time
* depending on data provided in options argument.
*
* @param listener This client must be called on appropriate event.
* @param options List of options to subscribe. SubscribeOption contains
* information such as property Id, area Id, sample rate, etc.
* 订阅属性
* 客户端可以一次订阅多个属性,这取决于 options 定义的参数。
* 参数 SubscribeOptions 包含 属性id、区域id、采样率 等信息。
*/
subscribe(IVehicleCallback callback, vec<SubscribeOptions> options)
generates (StatusCode status);
/**
* Unsubscribes from property events.
*
* If this client wasn't subscribed to the given property, this method
* must return StatusCode::INVALID_ARG.
* 取消订阅属性
* 如果客户端在此前没有对此属性进行订阅,则返回 StatusCode::INVALID_ARG。
*/
unsubscribe(IVehicleCallback callback, int32_t propId)
generates (StatusCode status);
/**
* Print out debugging state for the vehicle hal.
*
* The text must be in ASCII encoding only.
*
* Performance requirements:
*
* The HAL must return from this call in less than 10ms. This call must avoid
* deadlocks, as it may be called at any point of operation. Any synchronization
* primitives used (such as mutex locks or semaphores) must be acquired
* with a timeout.
*
* 打印车辆的调试状态。
*/
debugDump() generates (string s);
};
2.3.2 IVehicleCallback.hal
IVehicleCallback.hal 文件定义了 VehicleHal 的回调对象,上层 CarService 通过注册此回调对象以监听属性是否改变。VehicleHal 通过回调对象返回状态给到客户端。
package android.hardware.automotive.vehicle@2.0;
interface IVehicleCallback {
/**
* Event callback happens whenever a variable that the API user has
* subscribed to needs to be reported. This may be based purely on
* threshold and frequency (a regular subscription, see subscribe call's
* arguments) or when the IVehicle#set method was called and the actual
* change needs to be reported.
*
* These callbacks are chunked.
*
* @param values that has been updated.
* 当需要报告客户端订阅的变量时,就会调用此回调函数。
* 这可能基于常规按频率上报或者客户端调用 IVehicle#set 函数时调用。
*/
oneway onPropertyEvent(vec<VehiclePropValue> propValues);
/**
* This method gets called if the client was subscribed to a property using
* SubscribeFlags::EVENTS_FROM_ANDROID flag and IVehicle#set(...) method was called.
*
* These events must be delivered to subscriber immediately without any
* batching.
*
* @param value Value that was set by a client.
* 如果客户端使用 SubscribeFlags::EVENTS_FROM_ANDROID 标志订阅属性,并且调用 IVehicle#set 函数,则回调此方法。
*/
oneway onPropertySet(VehiclePropValue propValue);
/**
* Set property value is usually asynchronous operation. Thus even if
* client received StatusCode::OK from the IVehicle::set(...) this
* doesn't guarantee that the value was successfully propagated to the
* vehicle network. If such rare event occurs this method must be called.
*
* @param errorCode - any value from StatusCode enum.
* @param property - a property where error has happened.
* @param areaId - bitmask that specifies in which areas the problem has
* occurred, must be 0 for global properties
* 设置属性通常是异步操作,客户端调用 IVehicle#set 函数到接收到 StatusCode::OK 的返回值,也不能保证此属性成功传播到车辆网络,如果发生这种低概率的事件,则回调此方法。
* @ errorCode:StatusCode 枚举中的任何值。
* @ property:发生错误的属性。
* @ areaId:指定问题发生在哪个区域的位掩码,对于全局属性必须为 0。
*/
oneway onPropertySetError(StatusCode errorCode,
int32_t propId,
int32_t areaId);
};
2.3.3 types.hal
types.hal 中定义了 VehicleHal 的属性、结构等数据。
2.3.3.1 车辆属性 VehiclePropertyType
下面列举 types.hal 中定义的 VehiclePropertyType 属性:
package android.hardware.automotive.vehicle@2.0;
/**
* Enumerates supported data type for VehicleProperty.
* 枚举 VehicleProperty 支持的数据类型。
* Used to create property ID in VehicleProperty enum.
* 用于在 VehicleProperty enum 中创建属性 ID。
*/
enum VehiclePropertyType : int32_t { // VehicleProperty 的类型是 string、bool、还是 int32 等等
STRING = 0x00100000,
BOOLEAN = 0x00200000,
INT32 = 0x00400000,
INT32_VEC = 0x00410000,
INT64 = 0x00500000,
INT64_VEC = 0x00510000,
FLOAT = 0x00600000,
FLOAT_VEC = 0x00610000,
BYTES = 0x00700000,
/**
* Any combination of scalar or vector types. The exact format must be
* provided in the description of the property.
*/
MIXED = 0x00e00000, // 这两个主要就是 VehicleProperty 用来进行或运算的。
MASK = 0x00ff0000
};
2.3.3.2 车辆区域属性 VehicleArea
下面是 types.hal 中定义的车辆区域属性:
/**
* Vehicle Areas
* Used to construct property IDs in the VehicleProperty enum.
* 用于在VehicleProperty enum中构造属性id。
*
* Some properties may be associated with particular vehicle areas. For
* example, VehicleProperty:DOOR_LOCK property must be associated with
* particular door, thus this property must be marked with
* VehicleArea:DOOR flag.
* 某些属性可能与特定车辆区域相关。例如,VehicleProperty:DOOR_LOCK 属性必须与特定的门相关联,因此该属性必须标记为 VehicleArea: door 标志。
*
* Other properties may not be associated with particular vehicle area,
* these kind of properties must have VehicleArea:GLOBAL flag.
* 其他属性可能不与特定的车辆区域相关联,这些属性必须具有VehicleArea:GLOBAL标志。
*
* [Definition] Area: An area represents a unique element of an AreaType.
* For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
*
* [Definition] AreaID: An AreaID is a combination of one or more areas,
* and is represented using a bitmask of Area enums. Different AreaTypes may
* not be mixed in a single AreaID. For instance, a window area cannot be
* combined with a seat area in an AreaID.
*
* Rules for mapping a zoned property to AreaIDs:
* - A property must be mapped to an array of AreaIDs that are impacted when
* the property value changes.
* - Each element in the array must represent an AreaID, in which, the
* property value can only be changed together in all the areas within
* an AreaID and never independently. That is, when the property value
* changes in one of the areas in an AreaID in the array, then it must
* automatically change in all other areas in the AreaID.
* - The property value must be independently controllable in any two
* different AreaIDs in the array.
* - An area must only appear once in the array of AreaIDs. That is, an
* area must only be part of a single AreaID in the array.
*
* [Definition] Global Property: A property that applies to the entire car
* and is not associated with a specific area. For example, FUEL_LEVEL,
* HVAC_STEERING_WHEEL_HEAT.
*
* Rules for mapping a global property to AreaIDs:
* - A global property must not be mapped to AreaIDs.
*/
enum VehicleArea : int32_t {
GLOBAL = 0x01000000, // 全局区域
/** WINDOW maps to enum VehicleAreaWindow */
WINDOW = 0x03000000, // 窗户区域
/** MIRROR maps to enum VehicleAreaMirror */
MIRROR = 0x04000000, // 反光镜区域
/** SEAT maps to enum VehicleAreaSeat */
SEAT = 0x05000000, // 座椅区域
/** DOOR maps to enum VehicleAreaDoor */
DOOR = 0x06000000, // 车门区域
/** WHEEL maps to enum VehicleAreaWheel */
WHEEL = 0x07000000, // 车轮区域
YFVehicleAreaTire = 0x08000000,
MASK = 0x0f000000,
};
2.3.3.3 车辆属性分组类型 VehiclePropertyGroup
下面是 types.hal 中定义的车辆属性分组类型:
/**
* Enumerates property groups.
* 车辆属性分组枚举
*
* Used to create property ID in VehicleProperty enum.
* 用于在VehicleProperty enum中创建属性ID。
*/
enum VehiclePropertyGroup : int32_t { // AndroidO 之后的 treble,用于区分 android 原生的 property 和厂商的 property。
/**
* Properties declared in AOSP must use this flag.
* AOSP 原生的属性标志
*/
SYSTEM = 0x10000000,
/**
* Properties declared by vendors must use this flag.
* 厂商自定义的属性标志
*/
VENDOR = 0x20000000,
MASK = 0xf0000000,
};
2.3.3.4 车辆属性 VehicleProperty
下面是 types.hal 中定义的车辆属性
/**
* Declares all vehicle properties. VehicleProperty has a bitwise structure.
* Each property must have:
* - a unique id from range 0x0100 - 0xffff
* - associated data type using VehiclePropertyType
* - propert