汽车

Android 车载 HAL 图标

借助各种总线拓扑,很多汽车子系统都可以实现互连以及与车载信息娱乐 (IVI) 系统的连接。不同的制造商提供的确切总线类型和协议之间有很大差异(甚至同一品牌的不同车型之间也是如此),例如控制器区域网络 (CAN) 总线、局域互联网络 (LIN) 总线、面向媒体的系统传输 (MOST) 总线以及汽车级以太网和 TCP/IP 网络(如 BroadR-Reach)。

Android Automotive 的硬件抽象层 (HAL) 可为 Android 框架提供一致的接口,无论物理传输层如何。此车载 HAL 是开发 Android Automotive 实现的接口。

系统集成商可以将特定于功能的平台 HAL 接口(如 HVAC)与特定于技术的网络接口(如 CAN 总线)连接,以实现车载 HAL 模块。典型的实现可能包括运行专有实时操作系统 (RTOS) 的专用微控制器单元 (MCU),以用于 CAN 总线访问或类似操作,该微控制器单元可通过串行链路连接到运行 Android Automotive 的 CPU。除了专用的 MCU,还可以将总线访问作为虚拟 CPU 来实现。只要实现符合车载 HAL 的接口要求,每个合作伙伴都可以选择适合硬件的架构。

架构

车载 HAL 是汽车与车辆网络服务之间的接口定义:

Android 车载 HAL 架构

图 1. 车载 HAL 与 Android Automotive 架构

  • Car API:包含 CarHvacManager、CarSensorManager 和 CarCameraManager 等 API。如需详细了解所有受支持的 API,请参阅 /platform/packages/services/Car/car-lib
  • CarService:位于 /platform/packages/services/Car/
  • VehicleNetworkService:通过内置安全机制控制车载 HAL。仅限访问系统组件(第三方应用等非系统组件需使用 Car API)。原始设备制造商 (OEM) 可以通过 vns_policy.xmlvendor_vns_policy.xml 控制访问权限。位于 /platform/packages/services/Car/vehicle_network_service/;有关访问车辆网络的库,请参阅 /platform/packages/services/Car/libvehiclenetwork/
  • 车载 HAL:定义 OEM 可以实现的属性且包含属性元数据的接口(例如,属性是否为 int,允许使用哪些更改模式)。位于 hardware/libhardware/include/hardware/vehicle.h。有关基本参考实现,请参阅 hardware/libhardware/modules/vehicle/

车辆属性

车载 HAL 接口基于访问(读取、写入、订阅)属性,这是特定函数的抽象表示。属性可以是只读、只写(用于将信息传递到车载 HAL 级别),或者读取和写入。对大多数属性的支持都是可选的。

每个属性都由 int32 键唯一标识,且具有预定义的类型 (value_type):

  • INT32(和数组)、INT64BOOLEANFLOAT(和数组)、字符串、字节。
  • 区域类型除了值之外还有区域。

区域类型

车载 HAL 定义了 3 种区域类型:

  • vehicle_zone:基于排的区域。
  • vehicle_seat:基于座位的区域。
  • vehicle_window:基于窗户的区域。

每个区域属性都应使用预定义的区域类型。如有必要,您可以为每个属性使用自定义区域类型(有关详情,请参阅处理自定义属性)。

配置属性

使用 vehicle_prop_config_t 为每个属性提供配置信息。具体信息包括:

  • access(r、w、rw)
  • change_mode(表示监视属性的方式:变化模式还是连续模式)
  • min_value(int32、float、int64)、max_value(int32、float、int64)
  • min_sample_ratemax_sample_rate
  • permission_model
  • prop(属性 ID、int)
  • value_type
  • zone_flags(将受支持的区域表示为位标记)

此外,某些属性具有表示功能的具体配置标记。

HAL 接口

车载 HAL 使用以下接口:

  • vehicle_prop_config_t const *(*list_properties)(..., int* num_properties)。列出车载 HAL 所支持的所有属性的配置。车辆网络服务仅使用受支持的属性。
  • (*get)(..., vehicle_prop_value_t *data)。读取属性的当前值。对于区域属性,每个区域都可能具有不同的值。
  • (*set)(..., const vehicle_prop_value_t *data)。为属性写入一个值。写入结果按每个属性进行定义。
  • (*subscribe)(..., int32_t prop, float sample_rate, int32_t zones)
    • 开始监视属性值的变化。对于区域属性,订阅适用于请求的区域。Zones = 0 用于请求所有受支持的区域。
    • 车载 HAL 应该在属性值发生变化(即变化类型)或出现常量间隔(即连续类型)时调用单独的回调。
  • (*release_memory_from_get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data)。释放从 get 调用分配的内存。

车载 HAL 使用以下回调接口:

  • (*vehicle_event_callback_fn)(const vehicle_prop_value_t *event_data)。通知车辆属性值的变化。应只针对已订阅属性执行。
  • (*vehicle_error_callback_fn)(int32_t error_code, int32_t property, int32_t operation). 返回全局车载 HAL 级别错误或每个属性的错误。全局错误会导致 HAL 重新启动,这可能导致包括应用在内的其他组件重新启动。

处理区域属性

区域属性相当于多个属性的集合,其中每个子属性都可由指定的区域值访问。

  • 区域属性的 get 调用始终包含请求中的区域,因此,只应返回所请求区域的当前值。
  • 区域属性的 set 调用始终包含请求中的区域,因此,只应更改所请求的区域。
  • subscribe 调用包括所有已订阅区域的标记。不应报告来自未订阅区域的事件。

Get 调用

在初始化期间,由于尚未收到匹配的车辆网络消息,属性的值可能不可用。在这种情况下,get 调用应该返回 -EAGAIN。某些属性(如 HVAC)具有独立的电源开/关属性。这种属性的 get 的调用(关机时)应返回特殊值 (VEHICLE_INT_OUT_OF_RANGE_OFF/VEHICLE_FLOAT_OUT_OF_RANGE_OFF),而不是返回错误。

此外,某些属性(如 HVAC 温度)可以用某个值来表示其处于最大功率模式,而不是特定的温度值。在这种情况下,请使用特殊值表示这种状态。

  • VEHICLE_INT_OUT_OF_RANGE_MAX/MIN
  • VEHICLE_FLOAT_OUT_OF_RANGE_MAX/MIN

示例:获取 HVAC 温度

车载 HAL get HVAC 的示例

图 2. 获取 HVAC 温度(CS = CarService、VNS = VehicleNetworkService、VHAL = 车载 HAL)

Set 调用

set 调用属于异步操作,涉及进行所请求更改之后的事件通知。在典型的操作中,set 调用会导致在车辆网络中发出更改请求。拥有该属性的电子控制单元 (ECU) 执行更改后,更新后的值通过车辆网络返回,而车载 HAL 会将更新后的值作为事件发送给车辆网络服务 (VNS)。

某些 set 调用可能要求准备好初始数据,而这些数据在初始化期间可能尚不可用。在这种情况下,set 调用应该返回 -EAGAIN。某些具有独立的电源开/关的属性应在属性关闭且无法设置时返回 -ESHUTDOWN

set 生效之前,get 不一定会返回所设置的值。例外情况是更改模式为 VEHICLE_PROP_CHANGE_MODE_ON_SET. 的属性。此属性仅在被 Android 之外的外部组件(如 VEHICLE_PROPERTY_UNIX_TIME 等时钟属性)设置时才通知更改。

示例:设置 HVAC 温度

车载 HAL set HVAC 的示例

图 3. 设置 HVAC 温度(CD = CarService、VNS = VehicleNetworkService、VHAL = 车载 HAL)

处理自定义属性

为了满足合作伙伴的特定需求,车载 HAL 允许使用针对系统应用的自定义属性。在使用自定义属性时,请遵循以下指南:

  • 键值应该在 [VEHICLE_PROPERTY_CUSTOM_START, VEHICLE_PROPERTY_CUSTOM_END] 范围内。其他范围会预留以供将来的扩展功能使用;使用这种范围可能会导致将来的 Android 版本中出现冲突。
  • 仅使用定义的 value_type。BYTES 类型允许传递原始数据,因此,在大多数情况下是足够的。通过自定义属性频繁发送大数据可能会减缓整个车辆网络的访问速度,因此,在添加大量需要 HAL 处理的数据时要小心谨慎。
  • 将访问策略添加到 vendor_vns_policy.xml(否则所有访问都将被拒)。
  • 通过 VendorExtensionManager(适用于 Java 组件)或 Vehicle Network Service API(适用于本机)访问。请勿修改其他汽车 API,因为这样做可能会在将来导致兼容性问题。

处理 HVAC 属性

您可以使用车载 HAL 控制 HVAC,具体方法是设置与 HVAC 相关的属性。大多数 HVAC 属性都是区域属性,但也有一些非区域(全局)属性。定义的示例属性包括:

  • VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET(按每个区域设置温度)。
  • VEHICLE_PROPERTY_HVAC_RECIRC_ON(按每个区域控制再循环)。

有关 HVAC 属性的完整列表,请在 vehicle.h 中搜索 VEHICLE_PROPERTY_HVAC_*

处理传感器属性

车载 HAL 传感器属性表示真实的传感器数据或策略信息,如驾驶状态。某些传感器信息(如驾驶状态和日间/夜间模式)不限制任何应用的访问,因为这些数据是构建安全车载应用所必需的。其他传感器信息(如车辆速度)更为敏感,需要用户可以管理的特定权限。

支持的传感器属性包括:

  • DRIVING_STATUS(应该支持):表示在当前驾驶状态下允许的操作。此信息用于在驾驶过程中屏蔽不安全的应用。
  • NIGHT_MODE(应该支持):确定日间/夜间显示模式。
  • GEAR_SELECTION/CURRENT_GEAR:驾驶员选择的挡位与实际挡位。
  • VEHICLE_SPEED:车速。受权限保护。
  • ODOMETER:当前里程表读数。受权限保护。
  • FUEL_LEVEL:当前油位 (%)。
  • FUEL_LEVEL_LOW:油位是否较低(布尔值)。

安全性

车载 HAL 支持 3 个级别的数据访问安全性:

  • 仅限系统(由 vns_policy.xml 控制)
  • 允许拥有权限的应用访问(通过汽车服务)
  • 无需任何权限即可访问(通过汽车服务)

仅允许部分系统组件直接访问车辆属性,而车辆网络服务是把关程序。大多数应用需通过汽车服务的额外把关(例如,只有系统应用可以控制 HVAC,因为这需要仅授予系统应用的系统权限)。

验证

AOSP 包含以下用于开发过程的测试资源:

  • hardware/libhardware/tests/vehicle/vehicle-hal-tool.c:加载车载 HAL 并执行简单操作的命令行原生工具,有助于在开发的早期阶段让系统正常运行。
  • packages/services/Car/tests/carservice_test/:包含使用模拟车载 HAL 属性进行的汽车服务测试。每个属性的预期行为都会在测试中实现,这是了解预期行为的绝佳起点。
  • hardware/libhardware/modules/vehicle/:基本参考实现。