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;
}
```
编译与部署
- 将上述代码合并到你的HAL实现文件中,确保
poll_sensors已正确赋值给poll_dev->poll
- 编译HAL模块:
mmm hardware/libhardware/modules/sensors(或你的模块路径)
- 将生成的
sensors.xxx.so推送到设备:adb push sensors.xxx.so /vendor/lib64/hw/(或对应架构目录)
- 重启系统服务:
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,避免系统时间调整导致数据异常