和菜鳥一起學android4.0.3源碼之傳感器的簡單移植

對於加速度傳感器,我們只需要知道他的三軸的數據,而android上層也是只需要一個數據結構中的數據而已。

 

1、關於linux驅動層

驅動主要是註冊了input設備,通過i2c接口讀取傳感器寄存器中的三軸數據,並上報這三個數據。

 

 

2、關於android硬件抽象層

在hardware\libhardware\include\hardware下有一個sensors.h的頭文件,主要填寫這裏的一個數據結構就可以了。

結構如下:

[html] view plaincopy
  1. typedef struct {  
  2.     union {  
  3.         float v[3];  
  4.         struct {  
  5.             float x;  
  6.             float y;  
  7.             float z;  
  8.         };  
  9.         struct {  
  10.             float azimuth;  
  11.             float pitch;、  
  12.    
  13.             float roll;  
  14.         };  
  15.     };  
  16.     int8_t status;  
  17.     uint8_t reserved[3];  
  18. } sensors_vec_t;  
  19.    
  20. /**  
  21.  * Union ofthe various types of sensor data  
  22.  * that can be returned.  
  23.  */  
  24. typedef structsensors_event_t {  
  25.     /* must be sizeof(struct sensors_event_t)*/  
  26.     int32_t version;  
  27.    
  28.     /* sensor identifier */  
  29.     int32_t sensor;  
  30.    
  31.     /* sensor type */  
  32.     int32_t type;  
  33.    
  34.     /* reserved */  
  35.     int32_t reserved0;  
  36.    
  37.     /* time is in nanosecond */  
  38.     int64_t timestamp;  
  39.    
  40.     union {  
  41.         float           data[16];  
  42.    
  43.         /* acceleration values are in meter persecond per second (m/s^2) */  
  44.        sensors_vec_t   acceleration;  
  45.    
  46.         /* magnetic vector values are inmicro-Tesla (uT) */  
  47.         sensors_vec_t   magnetic;  
  48.    
  49.         /* orientation values are in degrees */  
  50.         sensors_vec_t   orientation;  
  51.    
  52.         /* gyroscope values are in rad/s */  
  53.         sensors_vec_t   gyro;  
  54.    
  55.         /* temperature is in degrees centigrade(Celsius) */  
  56.         float           temperature;  
  57.    
  58.         /* distance in centimeters */  
  59.         float           distance;  
  60.    
  61.         /* light in SI lux units */  
  62.         float           light;  
  63.    
  64.         /* pressure in hectopascal (hPa) */  
  65.         float           pressure;  
  66.    
  67.         /* relative humidity in percent */  
  68.         float           relative_humidity;  
  69.     };  
  70.     uint32_t        reserved1[4];  
  71. }sensors_event_t;  

而android中源碼也有爲了這個抽象層專門搞了一個sensor的類,用來處理上報上來的數據,並提供給jni,給android上層。

具體代碼在device\samsung\tuna\libsensors這個文件夾下。

具體移植如下:

 

[html] view plaincopy
  1. static structsensor_t sSensorList[LOCAL_SENSORS + MPLSensor::numSensors] = {  
  2.       { "GP2A Light sensor",  
  3.           "Sharp",  
  4.           1, SENSORS_LIGHT_HANDLE,  
  5.           SENSOR_TYPE_LIGHT, 3000.0f, 1.0f,0.75f, 0, { } },  
  6.       { "GP2A Proximity sensor",  
  7.           "Sharp",  
  8.           1, SENSORS_PROXIMITY_HANDLE,  
  9.           SENSOR_TYPE_PROXIMITY, 5.0f, 5.0f,0.75f, 0, { } },  
  10.       { "BMP180 Pressure sensor",  
  11.           "Bosch",  
  12.           1, SENSORS_PRESSURE_HANDLE,  
  13.           SENSOR_TYPE_PRESSURE, 1100.0f, 0.01f,0.67f, 20000, { } },  
  14. };  

這裏要修改爲自己的設備。

[html] view plaincopy
  1.    
  2. private:  
  3.     enum {  
  4.         mpl               = 0,  //all mpl entries must be consecutive and inthis order  
  5.         mpl_accel,  
  6.         mpl_timer,  
  7.         light,  
  8.         proximity,  
  9.         pressure,  
  10.         numSensorDrivers,       // wake pipe goes here  
  11.         mpl_power,              //special handle for MPL pminteraction  
  12.         numFds,  
  13.     };  

這裏選擇自己的設備對應的編號

[html] view plaincopy
  1.    
  2. inthandleToDriver(int handle) const {  
  3.         switch (handle) {  
  4.             case ID_RV:  
  5.             case ID_LA:  
  6.             case ID_GR:  
  7.             case ID_GY:  
  8.             case ID_A:  
  9.             case ID_M:  
  10.             case ID_O:  
  11.                 return mpl;  
  12.             case ID_L:  
  13.                 return light;  
  14.             case ID_P:  
  15.                 return proximity;  
  16.             case ID_PR:  
  17.                 return pressure;  
  18.         }  
  19.         return -EINVAL;  
  20.     }  

這裏根據不同的id對應上面填寫的編號就行。比如我這裏是三軸加速度,所以、只要

Case ID_A:

       Return accel;

 

[html] view plaincopy
  1. sensors_poll_context_t::sensors_poll_context_t()  
  2. {  
  3.     FUNC_LOG;  
  4.     MPLSensor* p_mplsen = new MPLSensor();  
  5.     setCallbackObject(p_mplsen); //setup thecallback object for handing mpl callbacks  
  6.     numSensors =  
  7.         LOCAL_SENSORS +  
  8.        p_mplsen->populateSensorList(sSensorList + LOCAL_SENSORS,  
  9.                                     sizeof(sSensorList[0]) * (ARRAY_SIZE(sSensorList) - LOCAL_SENSORS));  
  10.    
  11.     mSensors[mpl] = p_mplsen;  
  12.     mPollFds[mpl].fd =mSensors[mpl]->getFd();  
  13.     mPollFds[mpl].events = POLLIN;  
  14.     mPollFds[mpl].revents = 0;  
  15. ……  
  16. }  

這裏的構造函數裏,填寫三軸加速度的就行。

 

然後根據自己的傳感器來新建一個類。創建兩個文件,AccelSensor.cpp, AccelSensor.h

具體函數根據libsensor中的就行。

 

移植好後,mm編譯後會得到一個sensor.*.so,其中*可以根據你的Android.mk來得到。有了這個然後再跑android系統。就可以使用了。

 

3、關於測試

可以下載一個加速度傳感器測試儀來測試,也可以根據重力加速度可以使屏幕旋轉來測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章