打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Andriod Sensor HAL实现(sensor.h和4.2的一样)
1 Android sensor构建
Android4.1 系统内置对传感器的支持达13种,他们分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。Android实现传感器系统包括以下几个部分:
n        java层
n        JNI层
n        HAL层
n        驱动层
各部分之间架构图如下:
2 Sensor HAL层接口
Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:
hardware/libhardware/include/hardware/sensors.h
n        对传感器类型的定义:
#define SENSOR_TYPE_ACCELEROMETER       1  //加速度传感器
#define SENSOR_TYPE_MAGNETIC_FIELD       2  //磁力传感器
#define SENSOR_TYPE_ORIENTATION           3  //方向
#define SENSOR_TYPE_GYROSCOPE            4  //陀螺仪
#define SENSOR_TYPE_LIGHT 5 //环境光照传感器
#define SENSOR_TYPE_PRESSURE              6  //压力传感器
#define SENSOR_TYPE_TEMPERATURE          7  //温度传感器
#define SENSOR_TYPE_PROXIMITY             8   //距离传感器
#define SENSOR_TYPE_GRAVITY             9
#define SENSOR_TYPE_LINEAR_ACCELERATION 10   //线性加速度
#define SENSOR_TYPE_ROTATION_VECTOR     11
#define SENSOR_TYPE_RELATIVE_HUMIDITY   12    //湿度传感器
#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
n        传感器模块的定义结构体如下:
struct sensors_module_t {
struct hw_module_t common;
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
};
该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表。
n        对任意一个sensor设备都会有一个sensor_t结构体,其定义如下:
struct sensor_t {
const char*     name;       //传感器名字
const char*     vendor;
int             version;     //版本
int             handle;     //传感器的handle句柄
int             type;       //传感器类型
float           maxRange;   //最大范围
float           resolution;    //解析度
float           power;       //消耗能源
int32_t         minDelay;    //事件间隔最小时间
void*           reserved[8];   //保留字段,必须为0
};
n        每个传感器的数据由sensors_event_t结构体表示,定义如下:
typedef struct sensors_event_t {
int32_t version;
int32_t sensor;            //标识符
int32_t type;             //传感器类型
int32_t reserved0;
int64_t timestamp;        //时间戳
union {
float           data[16];
sensors_vec_t   acceleration;   //加速度
sensors_vec_t   magnetic;      //磁矢量
sensors_vec_t   orientation;     //方向
sensors_vec_t   gyro;          //陀螺仪
float           temperature;     //温度
float           distance;        //距离
float           light;           //光照
float           pressure;         //压力
float           relative_humidity;  //相对湿度
};
uint32_t        reserved1[4];
} sensors_event_t;
其中,sensor为传感器的标志符,而不同的传感器则采用union方式来表示,sensors_vec_t结构体用来表示不同传感器的数据,
n        sensors_vec_t定义如下:
typedef struct {
union {
float v[3];
struct {
float x;
float y;
float z;
};
struct {
float azimuth;
float pitch;
float roll;
};
};
int8_t status;
uint8_t reserved[3];
} sensors_vec_t;
n        Sensor设备结构体sensors_poll_device_t,对标准硬件设备hw_device_t结构体的扩展,主要完成读取底层数据,并将数据存储在struct sensors_poll_device_t结构体中,poll函数用来获取底层数据,调用时将被阻塞定义如下:
struct sensors_poll_device_t {
struct hw_device_t common;
//Activate/deactivate one sensor
int (*activate)(struct sensors_poll_device_t *dev,
int handle, int enabled);
//Set the delay between sensor events in nanoseconds for a given sensor.
int (*setDelay)(struct sensors_poll_device_t *dev,
int handle, int64_t ns);
//获取数据
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
n        控制设备打开/关闭结构体定义如下:
static inline int sensors_open(const struct hw_module_t* module,
struct sensors_poll_device_t** device) {
return module->methods->open(module,
SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
}
static inline int sensors_close(struct sensors_poll_device_t* device) {
return device->common.close(&device->common);
}
3 Sensor HAL实现(以bma250为例子)
3.1打开设备流程图
SensorDevice属于JNI层,与HAL进行通信的接口, 在JNI层调用了HAL层的open_sensors()方法打开设备模块,再调用poll__activate()对设备使能,然后调用poll__poll读取数据。
3.2 实现代码分析
在bma250传感器中,只有加速度传感器,所以在sensor.cpp中,首先需要定义传感器数组sSensorList,其实就是初始化struct sensor_t结构体,只有加速传感器,初始化如下:
static const struct sensor_t sSensorList[] = {
{     "BMA250 3-axis Accelerometer",
"Bosch",
1, 0,
SENSOR_TYPE_ACCELEROMETER,
4.0f*9.81f,
(4.0f*9.81f)/1024.0f,
0.2f,
0,
{ }
},
};
n        定义open_sensors函数,来打开Sensor模块,代码如下:
static struct hw_module_methods_t sensors_module_methods = {
open : open_sensors
};
static int open_sensors(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
int status = -EINVAL;
sensors_poll_context_t *dev = new sensors_poll_context_t();
memset(&dev->device, 0, sizeof(sensors_poll_device_t));
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version  = 0;
dev->device.common.module   = const_cast<hw_module_t*>(module);
dev->device.common.close    = poll__close;
dev->device.activate        = poll__activate;
dev->device.setDelay        = poll__setDelay;
dev->device.poll            = poll__poll;
if(sensor_get_class_path(dev) < 0) {
ALOGD("g sensor get class path error \n");
return -1;
}
dev->fd = open_input_device();
*device = &dev->device.common;
status = 0;
return status;
}
在这个方法中,首先需要为hw_device_t分配内存空间,并对其初始化,设置重要方法的实现,然后调用open_input_device打开设备节点,返回文件描述符。
n        poll__activate()对设备使能
static int poll__activate(struct sensors_poll_device_t *device,
int handle, int enabled) {
sensors_poll_context_t *dev = (sensors_poll_context_t *)device;
char buffer[20];
int bytes = sprintf(buffer, "%d\n", enabled);
set_sysfs_input_attr(dev->class_path,"enable",buffer,bytes);
return 0;
}
static int set_sysfs_input_attr(char *class_path,
const char *attr, char *value, int len)
{
char path[256];
int fd;
if (class_path == NULL || *class_path == '\0'
|| attr == NULL || value == NULL || len < 1) {
return -EINVAL;
}
snprintf(path, sizeof(path), "%s/%s", class_path, attr);
path[sizeof(path) - 1] = '\0';
fd = open(path, O_RDWR);
if (fd < 0) {
return -errno;
}
if (write(fd, value, len) < 0) {
close(fd);
return -errno;
}
close(fd);
return 0;
}
代码很简单,通过系统调用open方法打开设备,然后调用write()方法写指令使能。
n        poll__poll(),读取数据
static int poll__poll(struct sensors_poll_device_t *device,
sensors_event_t* data, int count) {
struct input_event event;
int ret;
sensors_poll_context_t *dev = (sensors_poll_context_t *)device;
if (dev->fd < 0)
return 0;
while (1) {
ret = read(dev->fd, &event, sizeof(event));
if (event.type == EV_ABS) {
switch (event.code) {
#ifdef GSENSOR_XY_REVERT
case ABS_Y:
data->acceleration.x =
event.value * CONVERT_X;
break;
case ABS_X:
data->acceleration.y =
event.value * CONVERT_Y;
break;
#else
case ABS_X:
data->acceleration.x =
event.value * CONVERT_X;
break;
case ABS_Y:
data->acceleration.y =
event.value * CONVERT_Y;
break;
#endif
case ABS_Z:
data->acceleration.z =
event.value * CONVERT_Z;
break;
}
} else if (event.type == EV_SYN) {
data->timestamp =
(int64_t)((int64_t)event.time.tv_sec*1000000000
+ (int64_t)event.time.tv_usec*1000);
data->sensor = 0;
data->type = SENSOR_TYPE_ACCELEROMETER;
data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
return 1;
}
}
return 0;
}
通过read读取设备数据,并存储在sensors_event_t结构体中
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android4.0 G-Sensor工作流程
android上层应用apk到G
Android 传感器 HAL 头文件 sensors.h 详细注释
Android Sensor
camera HAL 学习
Android平台读写i2c设备开发笔记一
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服