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"],
}
编译与部署
- 将
virtual_sensors.cpp和Android.bp放入device/<vendor>/<board>/sensors/目录 - 在AOSP根目录执行:
source build/envsetup.sh && lunch <target> - 编译模块:
mmm device/<vendor>/<board>/sensors/ - 将生成的
sensors.virtual.so推送到设备:adb push sensors.virtual.so /vendor/lib/hw/ - 重启系统服务:
adb shell stop && adb shell start
验证方法
- 确认HAL模块被系统识别:
adb shell dumpsys sensorservice,应能看到名为"Virtual Accelerometer"的传感器,type为android.sensor.accelerometer - 读取实时数据:
adb shell dumpsys sensorservice --sensor 0(或使用sensorstest工具),观察三轴数值随时间变化 - 通过条件:传感器列表中正确显示虚拟加速度计;连续读取时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
常见问题
- 传感器列表为空:检查
sensors.virtual.so是否推送到正确路径(/vendor/lib/hw/),且文件名与ro.hardware属性匹配 - 数据不变化:确认
poll()中step变量为静态持续递增,未被重置 - 编译错误:确认头文件路径包含
hardware/sensors.h,且链接了libhardware