1. 體系結構
2. 數據結構
3. 四大函數
本文以重力感應器裝置G-sensor爲例探索Android的各層次結構。
1. 體系結構
Android的體系結構可分爲4個層次。
- 第一層次 底層驅動層,包括標準Linux,Android核心驅動,Android相關設備驅動,G-sensor的設備驅動程序即存在於此
- 第二層次 Android標準C/C++庫,包括硬件抽象層,Android各底層庫,本地庫,JNI
- 第三層次 Android Java Framwork框架層
- 第四層次 Java應用程序
本文重點關注硬件抽象層,JNI以及Framework。
1.1 硬件抽象層
硬件抽象層通過例如open(), read(), write(), ioctl(), poll()等函數調用的方式,與底層設備驅動程序進行交互,而這些函數調用是底層設備驅動程序事先準備好的。
用於交互的關鍵是文件描述符fd,fd通過open()打開G-sensor設備節點而得到,即 fd = open ("/dev/bma220", O_RDONLY);而/dev/bma220這個設備節點是在底層設備驅動中註冊完成的。
其他的函數調用如read(), write()等都通過該文件描述符fd對G-sensor設備進行操作。
1.2 JNI (Java Native Interface)
JNI層可以認爲是整個體系結構中的配角,概括地講,它就完成了一項任務,既實現從C++語言到Java語言的轉換。JNI層爲Java Framework層提供一系列接口,而這些接口函數的具體實現中,利用例如module->methods->open(), sSensorDevice->data_open(), sSensorDevice->poll()等回調函數與硬件抽象層進行交互。而這些open(), poll()回調函數在硬件抽象層中具體實現。
1.3 Java Framework
Framework層提供各種類和類的對象,可作爲系統的守護進程運行,也可供上層應用程序的使用。
例如類SensorManager,它作爲系統的守護進程在初始化的時候開始運行,其子類SensorThread中的子類SensorThreadRunnable通過sensors_data_poll()實現了對G-sensor數據的輪訓訪問,而sensors_data_poll()通過JNI層轉換到硬件抽象層去具體實現poll()。
2 數據結構
一般境況下,硬件抽象層對硬件的描述都分爲control和data兩大類。
2.1 sensors_control_context_t
struct sensors_control_context_t {
struct sensors_control_device_t device;
int fd;
};
struct sensors_control_device_t {
struct
hw_device_t common;
int (*open_data_source)(struct sensors_control_device_t *dev);
int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled);
int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);
int (*wake)(struct sensors_control_device_t *dev);
};
2.2 sensors_data_context_t
struct sensors_data_context_t {
struct sensors_data_device_t device;
int fd;
};
struct sensors_data_device_t {
struct hw_device_t common;
int (*data_open)(struct sensors_data_device_t *dev, int fd);
int (*data_close)(struct sensors_data_device_t *dev);
int (*poll)(struct sensors_data_device_t *dev,
sensors_data_t* data);
}
struct hw_device_t {
uint32_t tag; uint32_t version;
struct hw_module_t* module;
int (*close)(struct hw_device_t* device);
};
struct hw_module_t {
uint32_t tag; uint16_t version_major; uint16_t version_minor;
const char *id; const char *name; const char *author;
struct hw_module_methods_t* methods;
};
struct hw_module_methods_t {
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
};
下文將通過對(*open), (*open_data_source), (*data_open)和(*poll)的代碼分析,探索Android的各層次架構。
3 四大函數
3.1 module->methods->open()
1) Framework
SensorService作爲系統守護進程運行,其類的構造函數實現_sensors_control_init()。
2) JNI
爲_sensors_control_init()提供接口android_init(),並執行回調函數module->methods->open();
3) 硬件抽象層
具體實現(*open),該函數爲所有G-sensor回調函數的指針賦值。
3.2 sSensorDevice->open_data_source()
1) Framework
SensorService作爲系統守護進程運行,其類的一個公有成員ParcelFileDescriptor通過實現_sensors_control_open()得到設備的文件描述符。
2) JNI
爲_sensors_control_open()提供接口android_open(),並執行回調函數sSensorDevice->open_data_source();
3) 硬件抽象層
具體實現(*open_data_source),該函數通過打開G-sensor的設備節點得到文件描述符fd = open ("/dev/bma220", O_RDONLY);
4) 設備驅動層
通過misc_register()對G-sensor設備進行註冊,建立設備節點。
3.3 sSensorDevice->data_open()
1) Framework
SensorManager作爲系統守護進程運行,其子類SensorThreadRunnable的行爲函數run()實現sensors_data_open()。
2) JNI
爲sensors_data_open()提供接口sensors_data_open(),並執行回調函數sSensorDevice->data_open();
3) 硬件抽象層
具體實現(*data_open),該函數的功能就是將已經得到的文件描述符fd複製一份到sensors_data_context結構體中的dev->fd,以便爲處理數據的回調函數如(*poll)使用。
3.4 sSensorDevice->poll()
1) Framework
SensorManager作爲系統守護進程運行,其子類SensorThreadRunnable的行爲函數run()實現sensors_data_poll(values, status, timestamp),其目的是通過此函數得到從底層傳上來的有關G-sensor的數據values, status和timestamp,再通過此類的一個行爲函數listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);爲上層應用程序提供了得到G-sensor設備數據的接口函數。
2) JNI
爲sensors_data_poll()提供接口sensors_data_poll(),並執行回調函數sSensorDevice->poll(sSensorDevice, &data);其中,得到的data就是從底層傳上來的G-sensor數據,然後通過下圖的方式將data中對應的數據分別賦給values, status和timestamp。
3) 硬件抽象層
具體實現(*poll),該函數通過ioctl()實現與底層驅動程序的交互。
ioctl(dev->fd, BMA220_GET_ORIENTATION, &orient_value);
其中,dev->fd即剛纔由(*data_open)得到的文件描述符,BMA220_GET_ORIENTATION爲ioctl的一個命令,具體實現由底層驅動程序完成,orient_value即得到的G-sensor數據,它通過下圖的方式將相對應的數據賦給了data結構體中的values, status和time,從而最終實現了從底層到上層的數據通信。
4) 設備驅動層
與硬件抽象層交互的read(), write(), ioctl()函數由設備驅動實現。以ioctl()的一條命令BMA220_GET_ORIENTATION爲例,
通過bma220_get_orientation(data)得到G-sensor的數據data,然後將其從內核空間上傳到用戶空間的arg.