zoukankan      html  css  js  c++  java
  • Andriod Sensor HAL 分析

    1 Androidsensor构建

                 Android4.1系统内置对传感器的支持达13种,他们分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。


    Android传感各部分之间架构图如下:




    2 SensorHAL层接口

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

    hardware/libhardware/include/hardware/sensors.h

          对传感器类型的定义:

    #defineSENSOR_TYPE_ACCELEROMETER      1 //加速度传感器

    #defineSENSOR_TYPE_MAGNETIC_FIELD      2 //磁力传感器

    #defineSENSOR_TYPE_ORIENTATION          3 //方向

    #defineSENSOR_TYPE_GYROSCOPE           4 //陀螺仪

    #defineSENSOR_TYPE_LIGHT                 5 //环境光照传感器

    #defineSENSOR_TYPE_PRESSURE             6 //压力传感器

    #defineSENSOR_TYPE_TEMPERATURE         7 //温度传感器

    #defineSENSOR_TYPE_PROXIMITY            8  //距离传感器

    #defineSENSOR_TYPE_GRAVITY            9

    #defineSENSOR_TYPE_LINEAR_ACCELERATION10  //线性加速度

    #defineSENSOR_TYPE_ROTATION_VECTOR    11

    #defineSENSOR_TYPE_RELATIVE_HUMIDITY  12   //湿度传感器

    #defineSENSOR_TYPE_AMBIENT_TEMPERATURE 13

            传感器模块的定义结构体如下:

    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函数,用于获取传感器的列表。

          对任意一个sensor设备都会有一个sensor_t结构体,其定义如下:

    struct sensor_t {

       constchar*    name;      //传感器名字

       constchar*    vendor;

       int            version;    //版本

       int            handle;    //传感器的handle句柄

       int            type;      //传感器类型

       float          maxRange;  //最大范围

       float          resolution;   //解析度

       float          power;      //消耗能源

       int32_t        minDelay;   //事件间隔最小时间

       void*          reserved[8];  //保留字段,必须为0

    };

         每个传感器的数据由sensors_event_t结构体表示,定义如下:

    typedef structsensors_event_t {

       int32_t version;

       int32_tsensor;           //标识符

       int32_ttype;            //传感器类型

       int32_t reserved0;

       int64_ttimestamp;       //时间戳

       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结构体用来表示不同传感器的数据, 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;

             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 givensensor.

       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);

    };


           控制设备打开/关闭结构体定义如下:

    static inline intsensors_open(const struct hw_module_t* module,

           struct sensors_poll_device_t** device) {

       returnmodule->methods->open(module,

               SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);

    }

    static inline intsensors_close(struct sensors_poll_device_t* device) {

       returndevice->common.close(&device->common);

    }


    3 SensorHAL实现(以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[] = {

     

           {    "BMA2503-axis Accelerometer",

                   "Bosch",

                   1, 0,

                   SENSOR_TYPE_ACCELEROMETER,

                 4.0f*9.81f,

                 (4.0f*9.81f)/1024.0f,

                 0.2f,

                 0,

                 { }

          },

    };

             定义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 = newsensors_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 ");

                 return -1;

          }

          dev->fd =open_input_device();

          *device =&dev->device.common;

          status = 0;

          return status;

    }

    在这个方法中,首先需要为hw_device_t分配内存空间,并对其初始化,设置重要方法的实现,然后调用open_input_device打开设备节点,返回文件描述符。

            poll__activate()对设备使能

    static intpoll__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 ", enabled);

          set_sysfs_input_attr(dev->class_path,"enable",buffer,bytes);

          return 0;

    }

    static intset_sysfs_input_attr(char *class_path,

                               const char *attr, char *value, int len)

    {

          char path[256];

          int fd;

          if (class_path == NULL || *class_path == ''

             || attr ==NULL || value == NULL || len < 1) {

                 return -EINVAL;

          }

          snprintf(path, sizeof(path), "%s/%s", class_path, attr);

          path[sizeof(path) - 1] = '';

          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()方法写指令使能。


             poll__poll(),读取数据

    static int poll__poll(structsensors_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 =

     













  • 相关阅读:
    Struts2多文件上传
    Struts2单文件上传
    java验证码
    spring-day01
    Spring MVC篇一、搭建Spring MVC框架
    连接oracle数据库
    spring 核心技术
    Spring的特点
    spring连接数据库
    oracle学习第六天
  • 原文地址:https://www.cnblogs.com/liulaolaiu/p/11744621.html
Copyright © 2011-2022 走看看