2026/4/3 20:04:05
网站建设
项目流程
寿光市建设局网站,wordpress左上角logo,做游戏视频网站,上海网页设计培训网上一篇文章我们梳理了高通SEE架构的原理与核心组件#xff0c;了解到SEE作为传感器“中枢”#xff0c;向上对接客户端、向下管理硬件的核心逻辑。本文将聚焦代码实战与硬件协同两大维度#xff1a;一方面解析Sensor HAL层的关键代码结构与编译配置#xff0c;带您看懂高通…上一篇文章我们梳理了高通SEE架构的原理与核心组件了解到SEE作为传感器“中枢”向上对接客户端、向下管理硬件的核心逻辑。本文将聚焦代码实战与硬件协同两大维度一方面解析Sensor HAL层的关键代码结构与编译配置带您看懂高通SEE的软件实现另一方面深入ADSP应用专用处理器与SEE的通信机制揭秘传感器数据在“应用层-硬件层”之间的流转路径。一、SensorHAL层SEE与Android的桥梁在Android中SEE通过SensorHAL层对接上层SensorService屏蔽硬件差异将SEE接口封装为Android标准HIDL接口。1. 关键目录结构高通SEE的Sensor HAL代码主要存放在vendor/qcom/proprietary/sensors-see/ 目录下高通 proprietary 代码仓该目录包含HAL实现、驱动适配、测试工具等核心模块关键子目录功能如下vendor/qcom/proprietary/sensors-see/ ├── sensors-hal/ # HAL核心实现 ├── hal-2.0-hidl-impl/ # HIDL 2.0接口 ├── sensordaemon/ # 传感器守护进程 ├── QSensorTest/ # 测试工具 ├── reverserpc/ # 跨进程通信 └── nanopb/ # Protocol Buffers编解码以sensors-hal/目录为例其下的sensors/子目录是传感器驱动的“聚集地”sensors_list.txt文件会列出当前设备支持的所有传感器例如sensors_list.txt 示例accelerometer:qti,accel,SUID_ACC_001 gyroscope:qti,gyro,SUID_GYRO_001 temperature:qti,temp,SUID_TEMP_001 proximity:qti,prox,SUID_PROX_001每行对应一个传感器格式为“传感器类型:厂商:驱动名:SUID”HAL层会根据该列表加载对应的驱动模块。2. 核心文件解析ISensors.halAndroid标准HIDL接口定义Sensors.cppHIDL接口实现转发调用至SEEsns_sensor.hSEE传感器核心结构体定义1ISensors.halHIDL接口定义该文件是Android系统定义的传感器HAL标准接口位于hardware/interfaces/sensors/1.0/ISensors.hal定义了上层调用HAL的核心方法例如// ISensors.hal 核心方法 interface ISensors { // 获取传感器列表 getSensorsList() generates (vecSensorInfo sensors); // 开启/关闭传感器 activate(int32_t sensorHandle, bool enabled) generates (Status status); // 设置采样率与批处理参数 batch(int32_t sensorHandle, int64_t samplingPeriodNs, int64_t maxReportLatencyNs) generates (Status status); // 读取传感器数据 poll(vecEvent* events, vecFence* fences) generates (Status status); // 刷新传感器缓冲区 flush(int32_t sensorHandle) generates (Status status); };高通SEE的HAL层sensors-hal/需实现这些方法并将其映射到SEE的内部接口如set_client_request()、collect_data()。2Sensors.cppHAL接口实现hardware/interfaces/sensors/1.0/default/Sensors.cpp是HIDL接口的具体实现文件编译后生成android.hardware.sensors1.0-impl.so库。该文件的核心逻辑是“将Android HIDL调用转发到SEE”例如activate()方法的实现// Sensors.cpp 中 activate() 方法示例 ReturnStatus Sensors::activate(int32_t sensorHandle, bool enabled) { // 1. 根据sensorHandle获取SEE中的传感器SUID std::string sensorSuid getSuidByHandle(sensorHandle); if (sensorSuid.empty()) { return Status::BAD_VALUE; } // 2. 构造SEE的请求参数开启/关闭传感器 sns_sensor_request request; request.sensor_suid sensorSuid; request.enable enabled; // 3. 调用SEE的内部接口发送请求 status_t ret see_send_request(request); if (ret ! NO_ERROR) { return Status::INTERNAL_ERROR; } return Status::OK; }其中see_send_request()是HAL层与SEE核心服务通信的关键函数通过ReverseRPC或QMI协议将请求发送到SEE的服务管理器。3sns_sensor.hSEE传感器核心结构体在SEE的内部实现中所有传感器都通过sns_sensor结构体描述该文件位于slpi_proc/ssc/inc/sns_sensor.hSLPI是高通传感器低功耗岛处理器定义了传感器的核心接口与状态// sns_sensor.h 核心结构体 typedef struct sns_sensor { // 传感器回调函数如事件通知 sns_sensor_cb const *cb; // 传感器API如创建实例、获取SUID sns_sensor_api const *api; // 传感器状态如是否激活、当前采样率 sns_sensor_state const *state; // 传感器实例列表 struct sns_sensor_instance **instances; // 实例数量 uint32_t num_instances; } sns_sensor; // 传感器核心API typedef struct sns_sensor_api { // 创建传感器实例 sns_sensor_instance* (*create_instance)(struct sns_sensor *sensor); // 移除传感器实例 void (*remove_instance)(struct sns_sensor *sensor, sns_sensor_instance *instance); // 获取传感器SUID sns_suid const* (*get_sensor_uuid)(struct sns_sensor *sensor); // 处理客户端请求 void (*set_client_request)(struct sns_sensor *sensor, sns_sensor_instance *instance, sns_request const *request); } sns_sensor_api;该结构体是SEE“传感器实例化机制”的核心——每个传感器可创建多个实例实例根据客户端请求的配置如不同采样率独立运行实现“一传感器多场景适配”。3. 编译配置高通SEE的Sensor HAL层通过Android.mk与Android.bpSoong编译系统实现编译关键配置文件如下Android.mk/Android.bp模块编译规则android.hardware.sensors1.0-service.rc服务启动配置1sensors-hal/Android.mk该文件定义sensors-hal模块的编译规则指定源文件、依赖库与输出目标# Android.mk 示例 LOCAL_PATH : $(call my-dir) include $(CLEAR_VARS) # 模块名 LOCAL_MODULE : sensors-see-hal # 源文件核心实现 LOCAL_SRC_FILES : framework/sns_hal.cpp \ sensors/sns_temp_sensor.cpp \ sensors/sns_accel_sensor.cpp # 依赖库SEE核心库、nanopb协议库 LOCAL_SHARED_LIBRARIES : libsee-core \ libnanopb \ liblog # 头文件路径 LOCAL_C_INCLUDES : $(LOCAL_PATH)/inc \ $(TOP)/vendor/qcom/proprietary/sensors-see/nanopb/inc # 编译输出为共享库 include $(BUILD_SHARED_LIBRARY)编译后会生成libsee-hal.so供Sensor HAL服务加载。2Android.hardware.sensors1.0-service.rc这是Sensor HAL服务的启动配置文件位于hardware/interfaces/sensors/1.0/default/定义了服务的启动时机与权限# 服务名称与可执行文件路径 service vendor.sensors-hal-1-0 /vendor/bin/hw/android.hardware.sensors1.0-service # 声明HIDL接口对接上层SensorService interface android.hardware.sensors1.0::ISensors default # 服务类型hal类随系统boot阶段启动 class hal # 权限配置访问传感器硬件的权限 user system group system input系统启动时会在boot阶段执行class_start hal启动该服务进而加载libsee-hal.so与SEE核心模块。二、ADSP与SEE通信QMI协议详解1. ADSP的角色低功耗处理传感器数据的功耗仅为AP的1/10高实时性微秒级调度延迟硬件隔离数据在ADSP内处理提升安全性2. QMI通信流程APHAL层 --QMI请求-- ADSPSEE模块 ↑ ↓ 配置传感器 处理请求 ↑ ↓ APHAL层 --QMI响应-- ADSPSEE模块核心流程以“设置采样率”为例2.1.AP侧HAL层发送请求HAL层调用batch(sensor_type, period)方法如设置温度传感器采样率为1Hz通过qsh_qmi()函数QMI接口封装构造QMI消息消息内容包含传感器SUID、请求类型设置采样率、参数period1000ms调用send_sync_sensor_request(suid)将QMI消息通过RPC通道发送到ADSP。2.2.ADSP侧SEE模块处理请求ADSP的QMI服务端接收消息解析出传感器SUID与参数调用SEE的set_client_request()接口将采样率参数下发至传感器驱动驱动更新硬件配置后通过QMI发送“配置成功”的响应消息。2.3.AP侧接收响应HAL层通过qsh_qmi()接收响应消息确认配置完成向上层SensorService返回Status::OK完成一次通信。3. QMI消息格式Protocol BuffersQMI消息基于协议缓冲区Protocol Buffers 定义SEE架构中所有传感器相关的QMI消息都通过.proto文件标准化例如sns_std.proto定义框架级消息如请求/响应头、错误码sns_accel.proto定义加速度计的消息如采样率配置、数据上报格式sns_temp.proto定义温度传感器的消息如阈值配置、温度数据格式。以sns_std.proto中的请求消息为例// sns_std.proto 示例 message sns_std_request { // 请求类型如设置采样率0x01开启传感器0x02 uint32 request_type 1; // 传感器SUID sns_suid suid 2; // 请求参数键值对如period:1000 repeated sns_std_param params 3; // 请求ID用于匹配响应 uint32 request_id 4; }这种标准化格式确保了AP与ADSP之间的消息兼容性即使硬件迭代只需更新.proto文件即可适配。三、实战温度传感器数据采集C示例1. 初始化与激活传感器sns_hal_context*hal_ctxsns_hal_init();sensor_info_t*temp_sensorfind_sensor_by_type(temperature);sns_hal_activate(hal_ctx,temp_sensor-id,true);sns_hal_batch(hal_ctx,temp_sensor-id,batch_param);2. 激活传感器并设置采样率通过QMI接口发送配置请求激活传感器并设置采样率// 5. 激活温度传感器status_t activate_retsns_hal_activate(hal_ctx,temp_sensor-id,true);if(activate_ret!STATUS_OK){printf(激活传感器失败错误码%d\n,activate_ret);return-1;}// 6. 设置采样率为1Hzperiod1000msbatch_param_t batch_param{.sampling_period1000000000,// 1秒单位ns.max_report_latency0// 无延迟上报};status_t batch_retsns_hal_batch(hal_ctx,temp_sensor-id,batch_param);if(batch_ret!STATUS_OK){printf(设置采样率失败错误码%d\n,batch_ret);return-1;}printf(传感器激活成功采样率1Hz\n);3. 采集并打印温度数据sensor_event_t event;for(inti0;i10;i){status_t retsns_hal_poll(hal_ctx,temp_sensor-id,event,2000);if(retSTATUS_OK){floattemperatureevent.data[0];printf(温度: %.1f℃\n,temperature);}sleep(1);}// 8. 释放资源sns_hal_deactivate(hal_ctx,temp_sensor-id);sns_hal_deinit(hal_ctx);release_qsh_interface(qmi_iface);return0;4. 运行结果示例找到温度传感器SUIDSUID_TEMP_001 获取QMI接口成功 传感器激活成功采样率1Hz 第1次采集温度22.5℃时间戳1690000000000 第2次采集温度22.6℃时间戳1690001000000 第3次采集温度22.5℃时间戳1690002000000 ...