3. 实现虚拟传感器HAL

任务目标

在Android HAL层实现一个虚拟传感器模块,向上层提供标准传感器HAL接口,能够读取模拟的加速度计数据,并让数据随时间自然变化,以验证HAL框架的数据通路。

环境与前置依赖

  • Android源码树(AOSP),已初始化hardware/libhardware模块
  • 目标平台:模拟器或开发板,内核已加载goldfish/sensors相关驱动(本案例不依赖具体硬件)
  • 编译工具:Android.bp / Android.mk 构建环境

实现方案

本案例实现一个最小但完整的传感器HAL模块:定义sensors_module_t和sensors_poll_device_t,注册一个虚拟加速度计(type: SENSOR_TYPE_ACCELEROMETER)。数据生成采用正弦波模拟三轴加速度变化,每次poll调用时推进时间戳并更新数值,从而模拟真实传感器持续输出的行为。

关键完整代码

// virtual_sensors.cpp
#include <hardware/hardware.h>
#include <hardware/sensors.h>
#include <math.h>
#include <string.h>
#include <cutils/log.h>

#define VIRTUAL_SENSOR_ID_ACCEL 0

static const struct sensor_t sSensorList[] = {
    {
        .name = "Virtual Accelerometer",
        .vendor = "AOSP",
        .version = 1,
        .handle = VIRTUAL_SENSOR_ID_ACCEL,
        .type = SENSOR_TYPE_ACCELEROMETER,
        .maxRange = 19.6f,
        .resolution = 0.01f,
        .power = 0.5f,
        .minDelay = 10000,   // 10ms
        .fifoReservedEventCount = 0,
        .fifoMaxEventCount = 0,
        .stringType = SENSOR_STRING_TYPE_ACCELEROMETER,
        .requiredPermission = "",
        .maxDelay = 200000,  // 200ms
        .flags = SENSOR_FLAG_CONTINUOUS_MODE,
        .reserved = {}
    }
};

static int virtual_sensors_get_sensors_list(struct sensors_module_t* module,
                                            struct sensor_t const** list) {
    (void)module;
    *list = sSensorList;
    return 1;  // 返回传感器数量
}

static int virtual_sensors_set_operation_mode(struct sensors_poll_device_t* dev,
                                              int mode) {
    (void)dev; (void)mode;
    return 0;  // 本虚拟设备无需特殊模式处理
}

static int virtual_sensors_activate(struct sensors_poll_device_t* dev,
                                    int handle, int enabled) {
    (void)dev; (void)handle; (void)enabled;
    return 0;  // 虚拟设备始终可读,激活操作直接成功
}

static int virtual_sensors_set_delay(struct sensors_poll_device_t* dev,
                                     int handle, int64_t ns) {
    (void)dev; (void)handle; (void)ns;
    return 0;  // 采样率调整在本实现中不改变数据生成逻辑
}

static int virtual_sensors_poll(struct sensors_poll_device_t* dev,
                                sensors_event_t* data, int count) {
    (void)dev;
    static int64_t step = 0;
    static int64_t base_time = 0;

    if (base_time == 0) {
        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        base_time = ts.tv_sec * 1000000000LL + ts.tv_nsec;
    }

    int num_events = 0;
    if (count > 0) {
        // 生成一个加速度计事件
        sensors_event_t& ev = data[0];
        memset(&ev, 0, sizeof(ev));
        ev.version = sizeof(sensors_event_t);
        ev.sensor = VIRTUAL_SENSOR_ID_ACCEL;
        ev.type = SENSOR_TYPE_ACCELEROMETER;
        ev.timestamp = base_time + step * 10000000LL;  // 每步10ms

        // 模拟三轴正弦变化,周期约2秒
        double t = step * 0.01;  // 秒
        ev.acceleration.x = 9.8f * sin(t * 2.0 * M_PI / 2.0);
        ev.acceleration.y = 9.8f * cos(t * 2.0 * M_PI / 2.0);
        ev.acceleration.z = 9.8f + 2.0f * sin(t * 2.0 * M_PI / 1.0);
        ev.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;

        num_events = 1;
        step++;
    }
    return num_events;
}

static int virtual_sensors_close(struct hw_device_t* dev) {
    (void)dev;
    return 0;
}

static int virtual_sensors_open(const struct hw_module_t* module,
                                const char* name,
                                struct hw_device_t** device) {
    if (strcmp(name, SENSORS_HARDWARE_POLL) != 0) {
        return -EINVAL;
    }

    sensors_poll_device_t* poll_dev = new sensors_poll_device_t();
    memset(poll_dev, 0, sizeof(*poll_dev));
    poll_dev->common.tag = HARDWARE_DEVICE_TAG;
    poll_dev->common.version = SENSORS_DEVICE_API_VERSION_1_0;
    poll_dev->common.module = const_cast<hw_module_t*>(module);
    poll_dev->common.close = virtual_sensors_close;
    poll_dev->activate = virtual_sensors_activate;
    poll_dev->setDelay = virtual_sensors_set_delay;
    poll_dev->poll = virtual_sensors_poll;
    poll_dev->setOperationMode = virtual_sensors_set_operation_mode;

    *device = &poll_dev->common;
    return 0;
}

static struct hw_module_methods_t virtual_sensors_methods = {
    .open = virtual_sensors_open
};

struct sensors_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .version_major = 1,
        .version_minor = 0,
        .id = SENSORS_HARDWARE_MODULE_ID,
        .name = "Virtual Sensors HAL",
        .author = "AOSP",
        .methods = &virtual_sensors_methods,
        .dso = nullptr,
        .reserved = {0}
    },
    .get_sensors_list = virtual_sensors_get_sensors_list
};

构建配置

// Android.bp
cc_library_shared {
    name: "sensors.virtual",
    vendor: true,
    relative_install_path: "hw",
    srcs: ["virtual_sensors.cpp"],
    shared_libs: [
        "libhardware",
        "libcutils",
        "liblog",
    ],
    header_libs: ["libhardware_headers"],
    cflags: ["-Wall", "-Werror"],
}

编译与部署

  1. 将virtual_sensors.cpp和Android.bp放入device/<vendor>/<board>/sensors/目录
  2. 在AOSP根目录执行:source build/envsetup.sh && lunch <target>
  3. 编译模块:mmm device/<vendor>/<board>/sensors/
  4. 将生成的sensors.virtual.so推送到设备:adb push sensors.virtual.so /vendor/lib/hw/
  5. 重启系统服务:adb shell stop && adb shell start

验证方法

  1. 确认HAL模块被系统识别:adb shell dumpsys sensorservice,应能看到名为"Virtual Accelerometer"的传感器,type为android.sensor.accelerometer
  2. 读取实时数据:adb shell dumpsys sensorservice --sensor 0(或使用sensorstest工具),观察三轴数值随时间变化
  3. 通过条件:传感器列表中正确显示虚拟加速度计;连续读取时x/y/z值呈现周期性正弦变化,且时间戳单调递增

预期输出示例

// dumpsys sensorservice 部分输出(仅示意结构)
Sensor List:
0: Virtual Accelerometer | AOSP | version: 1
   type: android.sensor.accelerometer
   maxRange: 19.6  resolution: 0.01  power: 0.5mA
   minDelay: 10000us  maxDelay: 200000us
虚拟传感器HAL数据通路 SensorService (Java/Native) open() sensors_module_t get_sensors_list() open() sensors_poll_device_t poll() / activate() 数据生成核心 x: sin(t) y: cos(t) z: 9.8+sin(t) 每次 poll() 调用 → step++ → 时间戳 +10ms → 更新三轴数值 验证 dumpsys sensorservice 数据流方向:SensorService → HAL Module → Poll Device → 正弦数据生成 → 返回 events[]

常见问题

  • 传感器列表为空:检查sensors.virtual.so是否推送到正确路径(/vendor/lib/hw/),且文件名与ro.hardware属性匹配
  • 数据不变化:确认poll()中step变量为静态持续递增,未被重置
  • 编译错误:确认头文件路径包含hardware/sensors.h,且链接了libhardware