车辆属性

车载 HAL 接口会定义原始设备制造商 (OEM) 可以实现的属性,并会包含属性元数据(例如,属性是否为 int 以及允许使用哪些更改模式)。车载 HAL 接口是以对属性(特定功能的抽象表示)的访问(读取、写入、订阅)为基础。

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 应该在属性值发生变化时(即 on-change 类型)或按一定间隔(即 continuous 类型)调用单独的回调。
  • (*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 重新启动,这可能导致包括应用在内的其他组件重新启动。

车辆属性

属性可以是只读、只写(用于将信息传递到车载 HAL 一级),也可以是能够读取和写入(对大多数属性而言支持读写是可选的)。每个属性都由 int32 键唯一标识,且具有预定义的类型 (value_type):

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

区域类型

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

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

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

配置属性

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

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

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

处理区域属性

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

  • 区域属性的 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 获取 HVAC 的示例

图 1. 获取 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 设置 HVAC 的示例

图 2. 设置 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 属性

您可以通过设置与 HVAC 相关的属性,来使用车载 HAL 控制 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
    油位是否较低(布尔值)。