Android Sensor 架構深刻剖析【轉】

本文轉載自:數組

一、Android sensor架構架構

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

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

各部分之間架構圖以下:
blog

二、Sensor HAL層接口接口

Google爲Sensor提供了統一的HAL接口,不一樣的硬件廠商須要根據該接口來實現並完成具體的硬件抽象層,Android中Sensor的HAL接口定義在:hardware/libhardware/include/hardware/sensors.h內存

對傳感器類型的定義:get

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

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

對任意一個sensor設備都會有一個sensor_t結構體,其定義以下:

每一個傳感器的數據由sensors_event_t結構體表示,定義以下:

其中,sensor爲傳感器的標誌符,而不一樣的傳感器則採用union方式來表示,sensors_vec_t結構體用來表示不一樣傳感器的數據,sensors_vec_t定義以下:

Sensor設備結構體sensors_poll_device_t,對標準硬件設備 hw_device_t結構體的擴展,主要完成讀取底層數據,並將數據存儲在struct sensors_poll_device_t結構體中,poll函數用來獲取底層數據,調用時將被阻塞定義以下:

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

三、Sensor HAL實現(以LM75溫度傳感器爲例子)

(1)打開設備流程圖

(2)實現代碼分析

在代碼中含有兩個傳感器ADC電位器和LM75溫度傳感器,因此在sensor.c中,首先須要定義傳感器數組device_sensor_list[],其實就是初始化struct sensor_t結構體,初始化以下:

定義open_sensors函數,來打開Sensor模塊,代碼以下:

在這個方法中,首先須要爲hw_device_t分配內存空間,並對其初始化,設置重要方法的實現。

control_open_data_source()打開傳感器並使能設備:

調用sensor__data_poll方法讀取數據:

/*輪詢讀取數據*/        static int sensors__data_poll(struct sensors_data_context_t *dev, sensors_data_t * values)        {            int n;            int mag;            float temp;            char buf[10];            while (1) {            if(count % 3 == 2) // 讀取ADC值            {                if( read(dev->event_fd[0], &mag, sizeof(mag)) < 0)                {                   LOGE("read adc error");                }else{                 dev->sensors[ID_MAGNETIC_FIELD].magnetic.v[0] =(float)mag;                 LOGE("read adc %f\n",(float)mag);                *values = dev->sensors[ID_MAGNETIC_FIELD];                values->sensor = ID_MAGNETIC_FIELD;                count++;                }                usleep(500000);                return ID_MAGNETIC_FIELD;                }                else if(count%3 == 1) //讀取溫度傳感器值                 {                memset(buf, 0 ,sizeof(buf));                if((n = read(dev->event_fd[1], buf, 10)) < 0)                {                    LOGE("read temp error");                    }else{                    buf[n - 1] = '\0';                    temp =(float) (atoi(buf) / 1000);                    dev->sensors[ID_TEMPERATURE].temperature = temp;                    LOGE("read temp %f\n",temp);                    *values = dev->sensors[ID_TEMPERATURE];                    values->sensor = ID_TEMPERATURE;                    count++;                }                    close(dev->event_fd[1]);                    dev->event_fd[1]= open("/sys/bus/i2c/devices/0-0048/temp1_input", O_RDONLY);                    usleep(500000);                    return ID_TEMPERATURE;               }               else if(count%3 == 0) //讀取方向傳感器模擬值                 {                    LOGI("read orientation\n");                    /* fill up data of orientation */                    dev->sensors[ID_ORIENTATION].orientation.azimuth = x + 5;                    dev->sensors[ID_ORIENTATION].orientation.pitch = y + 5;                    dev->sensors[ID_ORIENTATION].orientation.roll = z + 5;                    *values = dev->sensors[ID_ORIENTATION];                    values->sensor = ID_ORIENTATION;                    count++;                    x += 0.0001; y += 0.0001; z += 0.0001;                    usleep (500000);                    return ID_ORIENTATION;              }            }        }

相關文章
相關標籤/搜索