属性管理基础:VehicleProperty 的定义与核心要素
在 Vehicle HAL 中,属性(Property)是车辆信号的最小可操作单元。每个属性由四个核心维度唯一确定:属性 ID、属性类型、属性区域和属性状态。理解这四个维度的定义与组合规则,是正确实现车辆信号订阅与数据分发的前提。
2.1 属性 ID(Property ID)
属性 ID 是一个 int32 类型的全局唯一标识符,用于在系统中定位一个具体的车辆信号。其编码规则遵循 Android 官方定义,按功能域进行分段:
| 域范围(十六进制) | 功能域 | 示例属性 |
|---|---|---|
0x0100 - 0x01FF |
信息娱乐 / 座舱 | HVAC_TEMPERATURE_SET |
0x0200 - 0x02FF |
动力总成 | ENGINE_SPEED |
0x0300 - 0x03FF |
底盘 / 安全 | VEHICLE_SPEED |
0x0400 - 0x04FF |
车身 / 灯光 | DOOR_POSITION |
0x0500 - 0x05FF |
电气 / 电池 | BATTERY_LEVEL |
0x0600 - 0x06FF |
ADAS / 自动驾驶 | LANE_DEPARTURE_WARNING |
设计原则:属性 ID 的分配必须遵循“一信号一 ID”原则,禁止复用或跨域混用。OEM 自定义属性建议使用
0x0E00 - 0x0FFF 的私有域范围。
2.2 属性类型(Property Type)
属性类型定义了该属性承载的数据格式。Vehicle HAL 使用 VehiclePropertyType 枚举来标记每个属性的数据类型,确保 HAL 层与应用层之间的数据序列化一致。
| 类型枚举值 | Java / C++ 对应类型 | 典型用途 |
|---|---|---|
INT32 |
int |
车速、转速、温度 |
INT64 |
long |
里程、时间戳 |
FLOAT |
float |
电压、百分比、角度 |
BOOLEAN |
boolean |
开关状态、门锁状态 |
STRING |
String |
VIN、固件版本 |
BYTES |
byte[] |
诊断数据、自定义载荷 |
INT32_VEC |
int[] |
多区域温度数组 |
FLOAT_VEC |
float[] |
GPS 坐标序列 |
关键约束:属性类型一旦定义,在整个系统生命周期内不可变更。变更类型会导致 HAL 层与 CarService 之间的数据解析错位,引发运行时崩溃。
2.3 属性区域(Property Area)
属性区域用于标识该属性在车辆中的物理或逻辑位置。对于同一信号(如“车窗位置”),不同车门(左前、右后)需要不同的区域值来区分。区域使用 VehicleArea 枚举定义:
- GLOBAL(全局):适用于整车唯一的信号,如 VIN、总里程。
- WINDOW(车窗):按车窗位置细分,如左前、右前、左后、右后。
- DOOR(车门):按车门位置细分,与车窗区域类似但独立。
- SEAT(座椅):按座椅位置细分,如驾驶员、副驾、后排左、后排右。
- MIRROR(后视镜):按外后视镜位置细分。
- HVAC(空调):按空调分区,如驾驶区、副驾区、后排区。
- WHEEL(车轮):按车轮位置细分,如左前轮、右后轮。
属性 ID 的高 4 位(bit 28-31)用于编码区域类型,低 28 位用于编码具体属性编号。例如:
// 属性 ID 编码示例
#define VEHICLE_AREA_GLOBAL 0x00000000
#define VEHICLE_AREA_WINDOW 0x10000000
#define VEHICLE_AREA_DOOR 0x20000000
#define VEHICLE_AREA_SEAT 0x30000000
// 左前车窗位置属性 ID = 区域(车窗) + 属性编号(0x0100)
#define WINDOW_POS_LEFT_FRONT (VEHICLE_AREA_WINDOW | 0x0100)
常见错误:将 GLOBAL 区域的属性错误地分配了非 GLOBAL 区域值,或者将多区域属性(如车窗)错误地配置为 GLOBAL,会导致订阅方无法正确区分不同物理位置的信号。
2.4 属性状态(Property Status)
属性状态描述当前属性值的可用性与质量。每次属性值上报时,必须附带一个 VehiclePropertyStatus 枚举值:
| 状态枚举 | 含义 | 触发场景 |
|---|---|---|
AVAILABLE |
数据有效且来自真实传感器 | 正常行驶中,传感器工作正常 |
UNAVAILABLE |
数据暂时不可用,但硬件正常 | 信号丢失、CAN 总线延迟 |
ERROR |
数据无效,传感器或通信故障 | 传感器损坏、总线离线 |
应用层和 CarService 必须根据状态决定是否信任该数据。例如,当车速属性状态为 ERROR 时,ADAS 系统应降级或告警,而非使用无效值。
2.5 四维组合关系图
下图展示了属性 ID、类型、区域、状态四个维度如何共同构成一个完整的 VehicleProperty 实例:
2.6 属性定义完整示例
以下代码展示了一个完整的 VehicleProperty 定义,包含上述四个维度的配置:
// 定义:左前车窗位置属性
// 属性 ID:WINDOW_POS_LEFT_FRONT (0x10000100)
// 属性类型:INT32(单位:毫米,0 = 完全关闭)
// 属性区域:WINDOW(左前)
// 属性状态:由 HAL 层动态上报
struct VehiclePropConfig {
int32_t prop_id = 0x10000100; // 属性 ID(含区域编码)
int32_t access = 0x01; // 可读可写
int32_t change_mode = 0x01; // 连续变化
int32_t min_sample_rate = 10; // 最小采样间隔 10ms
int32_t max_sample_rate = 100; // 最大采样间隔 100ms
};
struct VehiclePropValue {
int32_t prop_id = 0x10000100;
int32_t area_id = 0x01; // 左前区域
int32_t status = VehiclePropertyStatus::AVAILABLE;
struct {
int32_t value = 250; // 当前开度 250mm
} data;
};
实践要点:在 HAL 层实现中,属性 ID 和区域 ID 通常合并为一个 int32 字段存储,解析时通过位掩码分离。属性状态必须随每次数据上报一起更新,不可复用上一次的状态值。
2.7 属性生命周期状态机
属性状态在运行时遵循有限状态机转换规则,确保数据质量的可追溯性:
2.8 属性管理核心原则总结
| 维度 | 核心原则 | 常见反例 |
|---|---|---|
| 属性 ID | 全局唯一,按功能域分段 | 不同信号共用同一 ID |
| 属性类型 | 定义后不可变更,与应用层契约一致 | FLOAT 类型误配为 INT32 |
| 属性区域 | 多区域属性必须正确编码区域位 | 车窗信号使用 GLOBAL 区域 |
| 属性状态 | 每次上报必须附带最新状态 | 复用上次状态导致误判 |
学习路径提示:掌握属性四维定义后,下一阶段将学习如何通过 Vehicle HAL 的
get/set 接口操作这些属性,以及如何基于属性 ID 和区域实现精确的信号订阅。