3. 传感器数据上报基础", "title"

任务目标

在Android传感器HAL层中,poll函数是传感器数据从内核空间上报至Framework的核心通道。本案例将实现一个最小可用的poll函数,模拟产生一组加速度计数据并完成上报,最终通过HAL层日志验证数据通路已打通。

前置环境

  • Android源码树(AOSP)已编译通过,目标平台为sdk_gphone_x86_64或实际开发板
  • 已创建传感器HAL模块(sensors.xxx.so),包含基本的sensors_module_t和sensors_poll_device_1_t结构体定义
  • 本案例聚焦poll函数实现,默认open_sensors、activate等接口已按标准模板接入

核心实现

在HAL实现文件(如sensors_hal.cpp)中,完成poll函数的模拟数据上报逻辑。关键点:构造sensors_event_t数据包,填充加速度计的三轴数据、时间戳和传感器句柄,并通过return返回值告知Framework本次上报的事件数量。

```cpp // sensors_hal.cpp — poll函数最小实现 #include #include #include #define ACCEL_HANDLE 0x01 #define ACCEL_RANGE (2.0f * 9.81f) // ±2g #define ACCEL_RESOLUTION (ACCEL_RANGE / 32768.0f) static int64_t get_timestamp() { struct timespec ts; clock_gettime(CLOCK_BOOTTIME, &ts); return (int64_t)ts.tv_sec * 1000000000LL + ts.tv_nsec; } /* 模拟一组加速度计数据(单位:m/s²) */ static void fill_accel_event(sensors_event_t* ev) { memset(ev, 0, sizeof(sensors_event_t)); ev->version = sizeof(sensors_event_t); ev->sensor = ACCEL_HANDLE; ev->type = SENSOR_TYPE_ACCELEROMETER; ev->timestamp = get_timestamp(); // 模拟静止状态:重力在Z轴约9.81,X/Y接近0 ev->acceleration.x = 0.05f; ev->acceleration.y = -0.02f; ev->acceleration.z = 9.78f; ev->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; } /* poll函数:每次调用上报1个模拟事件 */ static int poll_sensors(struct sensors_poll_device_1* dev, sensors_event_t* data, int max_num) { if (max_num < 1) { ALOGE("poll: max_num=%d too small", max_num); return -EINVAL; } fill_accel_event(&data[0]); ALOGI("poll: simulated accel event -> x=%.2f y=%.2f z=%.2f ts=%lld", data[0].acceleration.x, data[0].acceleration.y, data[0].acceleration.z, (long long)data[0].timestamp); return 1; // 返回本次上报的事件数量 } /* 将poll_sensors注册到sensors_poll_device_1_ops */ static int open_sensors(const struct hw_module_t* module, const char* name, struct hw_device_t** device) { // ... 标准open逻辑,此处省略模块初始化 ... struct sensors_poll_device_1_t* poll_dev = ...; poll_dev->poll = poll_sensors; // ... 其余ops赋值 ... *device = &poll_dev->common; return 0; } ```

编译与部署

  1. 将上述代码合并到你的HAL实现文件中,确保poll_sensors已正确赋值给poll_dev->poll
  2. 编译HAL模块:mmm hardware/libhardware/modules/sensors(或你的模块路径)
  3. 将生成的sensors.xxx.so推送到设备:adb push sensors.xxx.so /vendor/lib64/hw/(或对应架构目录)
  4. 重启系统服务:adb shell stop && adb shell start

验证方法

通过logcat观察HAL层日志,确认数据上报路径已打通:

adb logcat -s Sensors | grep "poll"

通过条件:连续多次调用poll后,日志中出现类似以下内容,且数值在预期范围内(X≈0,Y≈0,Z≈9.8):

I/Sensors : poll: simulated accel event -> x=0.05 y=-0.02 z=9.78 ts=1234567890123

同时,Framework层可通过dumpsys sensorservice查看是否有传感器连接(若Framework已正确加载HAL,会显示accel传感器状态)。

常见问题

  • poll未被调用:检查activate是否已使能传感器,Framework默认不会主动poll未激活的传感器
  • 数据未上报:确认sensors_event_t的version字段设置为sizeof(sensors_event_t),且sensor句柄与activate时使用的句柄一致
  • 时间戳异常:使用CLOCK_BOOTTIME而非CLOCK_REALTIME,避免系统时间调整导致数据异常
传感器数据上报通路(poll函数验证) Framework SensorService (Java层) HAL层 sensors_poll_device_1 poll() 函数 模拟数据源 x=0.05, y=-0.02 z=9.78 m/s² 读取数据 生成事件 返回 sensors_event_t 数组 验证观测点 ① logcat 过滤 Sensors 标签,观察 poll 日志输出 ② 日志格式:poll: simulated accel event -> x=0.05 y=-0.02 z=9.78 ts=... ③ 通过条件:Z轴数值≈9.8 m/s²(重力加速度),X/Y≈0,时间戳单调递增 ④ 可选:dumpsys sensorservice 确认 accel 传感器已连接