3. 属性配置与注册:属性配置文件、权限、变更模式与访问模式
在 Vehicle HAL 中,属性(Property)是车辆信号与上层服务之间的核心数据单元。每个属性在被系统使用之前,必须通过 属性配置文件 完成定义与注册。本章节将深入解析 VehiclePropertyConfig 的结构、属性权限模型、变更模式以及访问模式,帮助开发者构建安全、高效的车辆信号订阅体系。
3.1 属性配置文件(VehiclePropertyConfig)
VehiclePropertyConfig 是描述一个车辆属性元数据的核心结构体。它定义了属性的唯一标识、数据类型、访问权限、变更行为以及支持的车辆区域。该配置通常在 HAL 实现层的 onCreate() 方法中通过列表形式注册。
| 配置字段 | 类型 | 说明 |
|---|---|---|
prop |
int32_t | 属性唯一 ID,由 VehicleProperty 枚举定义 |
access |
VehiclePropertyAccess | 访问模式:读、写、读写 |
changeMode |
VehiclePropertyChangeMode | 变更模式:静态、连续变化、按需变化 |
minSampleRate |
float | 最低采样率(Hz),用于连续变化属性 |
maxSampleRate |
float | 最高采样率(Hz),用于连续变化属性 |
areaConfigs |
vector<VehicleAreaConfig> | 区域配置列表,定义属性在哪些车辆区域生效 |
configArray |
vector<int32_t> | 厂商自定义配置数组,用于扩展属性行为 |
configString |
string | 厂商自定义配置字符串 |
关键设计原则: 每个属性必须且只能注册一次。重复注册相同
prop ID 会导致 HAL 服务启动失败。区域配置 areaConfigs 必须与属性支持的区域类型(如全局、车窗、车门等)严格匹配。
3.2 属性权限模型
属性权限通过 VehiclePropertyAccess 枚举定义,决定了上层应用或服务能够对属性执行的操作。权限模型是车辆安全策略的第一道防线。
- READ(读):允许订阅者读取属性的当前值。适用于传感器数据、状态指示等只读信号。
- WRITE(写):允许订阅者向属性写入新值。适用于控制类信号,如车窗升降、门锁控制。
- READ_WRITE(读写):同时允许读取和写入。适用于可读可控制的属性,如空调温度设定。
安全警告: 对于涉及行车安全的属性(如车速、制动状态),应严格限制为 READ 模式。任何写操作都可能引入安全风险。对于控制类属性,建议在 HAL 层实现额外的权限校验逻辑。
3.3 变更模式(Change Mode)
变更模式定义了属性值发生变化时的通知策略。正确选择变更模式直接影响系统性能和信号订阅的实时性。
| 变更模式 | 枚举值 | 行为描述 | 典型应用 |
|---|---|---|---|
| STATIC | 0x00 | 属性值在车辆生命周期内不会改变,仅在初始化时设置一次 | 车辆 VIN、硬件版本号、固件版本 |
| ON_CHANGE | 0x01 | 属性值发生变化时主动通知订阅者,不变化时不发送 | 车门状态、车窗位置、灯光开关 |
| CONTINUOUS | 0x02 | 属性值以固定采样率持续上报,即使值未变化也可能周期性发送 | 车速、发动机转速、电池电压 |
性能优化建议: 对于 CONTINUOUS 模式,务必合理设置
minSampleRate 和 maxSampleRate。过高的采样率会占用大量系统带宽,而过低的采样率可能导致关键信号丢失。通常车速信号建议 10-50 Hz,温度信号 1-5 Hz。
3.4 访问模式(Access Mode)与订阅关系
访问模式决定了订阅者与属性之间的交互方式。在 Vehicle HAL 中,访问模式与变更模式共同决定了属性在订阅系统中的行为特征。
3.5 属性注册代码示例
以下代码展示了如何在 HAL 实现中创建并注册一个车速属性(VEHICLE_SPEED)和一个车门状态属性(DOOR_POSITION)。
// VehicleHalServer.cpp 中的 onCreate() 方法
Return<void> onCreate() override {
// 创建属性配置列表
std::vector<VehiclePropertyConfig> configs;
// 1. 车速属性:连续变化,只读,全局区域
VehiclePropertyConfig speedConfig;
speedConfig.prop = (int32_t)VehicleProperty::VEHICLE_SPEED;
speedConfig.access = VehiclePropertyAccess::READ;
speedConfig.changeMode = VehiclePropertyChangeMode::CONTINUOUS;
speedConfig.minSampleRate = 10.0f; // 最低 10 Hz
speedConfig.maxSampleRate = 50.0f; // 最高 50 Hz
// 全局区域配置
VehicleAreaConfig areaConfig;
areaConfig.areaId = 0; // 全局区域 ID
areaConfig.minInt32Value = 0;
areaConfig.maxInt32Value = 300; // 车速范围 0-300 km/h
speedConfig.areaConfigs = {areaConfig};
configs.push_back(speedConfig);
// 2. 车门状态属性:按需变化,读写,按车门区域
VehiclePropertyConfig doorConfig;
doorConfig.prop = (int32_t)VehicleProperty::DOOR_POSITION;
doorConfig.access = VehiclePropertyAccess::READ_WRITE;
doorConfig.changeMode = VehiclePropertyChangeMode::ON_CHANGE;
// 四个车门区域配置
for (int32_t doorId = 1; doorId <= 4; ++doorId) {
VehicleAreaConfig areaCfg;
areaCfg.areaId = doorId;
areaCfg.minInt32Value = 0; // 关闭
areaCfg.maxInt32Value = 100; // 完全打开
doorConfig.areaConfigs.push_back(areaCfg);
}
configs.push_back(doorConfig);
// 注册到 HAL 服务
auto status = mHalServer->registerProperties(configs);
if (status != StatusCode::OK) {
ALOGE("属性注册失败: %d", (int32_t)status);
}
return Void();
}
最佳实践: 属性注册应在
onCreate() 中尽早完成,确保在 HAL 服务对外提供信号之前所有元数据已就绪。对于 CONTINUOUS 模式,建议在车辆网络信号稳定后再开始上报,避免启动阶段产生无效数据。
3.6 属性配置与订阅的映射关系
属性配置直接影响订阅者的行为。下表总结了不同配置组合下订阅者的典型表现:
| 访问模式 | 变更模式 | 订阅者读取行为 | 订阅者写入行为 | 通知触发条件 |
|---|---|---|---|---|
| READ | STATIC | 可读取固定值 | 不允许 | 无(值不变) |
| READ | ON_CHANGE | 可读取当前值 | 不允许 | 值发生变化时 |
| READ | CONTINUOUS | 可读取当前值 | 不允许 | 按采样率周期性触发 |
| READ_WRITE | ON_CHANGE | 可读取当前值 | 允许写入新值 | 值发生变化时(包括写入后) |
| READ_WRITE | CONTINUOUS | 可读取当前值 | 允许写入新值 | 按采样率周期性触发 |
常见错误: 将 WRITE 模式与 STATIC 变更模式组合是无效的,因为静态属性不允许写入。同样,WRITE 模式与 CONTINUOUS 组合虽然语法上允许,但实际场景中极少使用,因为连续上报通常用于传感器数据,而传感器数据通常是只读的。