Andriod Sensor HAL实现

转自

http://blog.csdn.net/FE421504975/article/details/8248569

Andriod Sensor HAL实现

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层接口

GoogleSensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,AndroidSensorHAL接口定义在:

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结构体中

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值