【Android】Sensor框架HAL層解讀


Android sensor構建

  Android4.1 系統內置對傳感器的支持達13種,他們分別是:加速度傳感器(accelerometer)、磁力傳感器(magnetic field)、方向傳感器(orientation)、陀螺儀(gyroscope)、環境光照傳感器(light)、壓力傳感器(pressure)、溫度傳感器(temperature)和距離傳感器(proximity)等。

  Android實現傳感器系統包括以下幾個部分:

  1. java
  2. JNI 
  3. HAL層
  4. 驅動層

  各部分之間架構圖如下:

  

 

 


Sensor HAL層接口

  GoogleSensor提供了統一的HAL接口,不同的硬件廠商需要根據該接口來實現並完成具體的硬件抽象層。

  AndroidSensorHAL接口定義在:hardware/libhardware/include/hardware/sensors.h

  對傳感器類型的定義:

#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
View Code

  傳感器模塊的定義結構體如下:

struct sensors_module_t {
    struct hw_module_t common;
    int (*get_sensors_list)(struct sensors_module_t* module,
            struct sensor_t const** list);
};
View Code

  該接口的定義實際上是對標准的硬件模塊hw_module_t的一個擴展,增加了一個get_sensors_list函數,用於獲取傳感器的列表。

  對任意一個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
};
View Code

  每個傳感器的數據由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;
View Code

  其中,sensor為傳感器的標志符,而不同的傳感器則采用union方式來表示。

  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;
View Code

  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);
};
View Code

  控制設備打開/關閉結構體定義如下:

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);
}
View Code

 

 


Sensor HAL實現

打開設備時序圖

  

  SensorDevice屬於JNI層,與HAL進行通信的接口;

  JNI層調用了HAL層的open_sensors()方法打開設備模塊,再調用poll__activate()對設備使能,然后調用poll__poll讀取數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM