小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

紅狼博客 ? Android源碼分析:傳感器系統(tǒng)

 dwlinux_gs 2014-08-09

Sensors in Android

總述

如下圖,應(yīng)用程序開(kāi)發(fā)者使用幾個(gè)sensor的幾個(gè)API類進(jìn)行應(yīng)用程序的開(kāi)發(fā)。Java的部分的API使用C/C++來(lái)實(shí)現(xiàn),也就是調(diào)用到JNI層。左側(cè)運(yùn)行于應(yīng)用程序的進(jìn)程空間,右側(cè)運(yùn)行于system server進(jìn)程空間。雙方通過(guò)ISensorEventConnection/SensorChannel進(jìn)行通訊。SensorService負(fù)責(zé)與Sensors的硬件適配層HAL進(jìn)行通訊,后者與驅(qū)動(dòng)和硬件進(jìn)行交互。

Java API

Java層的API類有SensorManager,利用它才可以使用系統(tǒng)的各種感應(yīng)器(sensor)。sensor的采樣值、精確度、時(shí)間戳以及信息是自哪個(gè)感應(yīng)器等信息封裝在JavaSensorEvent中。JavaSensor代表一個(gè)感應(yīng)器,包含感應(yīng)器的各種信息,它的成員數(shù)據(jù)與本地Sensor類以及HAL層的sensor_t對(duì)應(yīng)(見(jiàn)后述章節(jié))。作為父類的SensorEventListener是一個(gè)監(jiān)聽(tīng)器接口,應(yīng)用開(kāi)發(fā)者編寫它的一個(gè)子類可以實(shí)現(xiàn)對(duì)SensorEvent的監(jiān)聽(tīng)并做出相應(yīng)反應(yīng)。

在獲取sensor service創(chuàng)建SensorManager時(shí),會(huì)創(chuàng)建一個(gè)線程去輪詢(poll,調(diào)用sensors_data_poll)去取sensor的數(shù)據(jù),然后以發(fā)送消息的形式將SensorEvent發(fā)送給ListenerDelegate中的Handler,由handler在新一輪的線程循環(huán)中調(diào)用對(duì)應(yīng)的sensorListener進(jìn)行處理。

 

JNInative

JNI層位于frameworks/base/core/jni/下面,主要就是一個(gè)文件android_hardware_SensorManager.cpp。它使用的類如Sensor、SensorChannel、SensorEventQueue、、ISensorEventConnectionISensorServer則放在libgui.so中,見(jiàn)目錄frameworks/base/libs/gui。

 

Java層在輪詢之前,必須調(diào)用sensors_create_queue創(chuàng)建(見(jiàn)SensorThreadRunnableopen函數(shù))一個(gè)本地的SensorEventQueue隊(duì)列,這個(gè)C++對(duì)象的指針被轉(zhuǎn)換為int型后保存為SensorManager的靜態(tài)成員變量sQueue。當(dāng)輪詢時(shí),將該隊(duì)列傳遞給JNI層的sensors_data_poll,用于從該隊(duì)列中讀取Event數(shù)據(jù)(具體數(shù)據(jù)類型是ASensorEvent)。

本地SensorEventQueue類主要借助于兩個(gè)類進(jìn)行工作。一是封裝了管道的SensorChannel類,event的讀取和寫入都是針對(duì)封裝的管道進(jìn)行的;二是libutils庫(kù)中的Looper類,Looper類實(shí)現(xiàn)了在調(diào)用者線程中對(duì)文件描述符的輪詢(內(nèi)部使用的epoll),甚至可以注冊(cè)回調(diào)函數(shù),當(dāng)有文件描述符對(duì)應(yīng)的文件有數(shù)據(jù)到達(dá)時(shí)使用回調(diào)函數(shù)進(jìn)行處理。這樣,隊(duì)列類SensorEventQueue使用Looper監(jiān)聽(tīng)著管道對(duì)應(yīng)的描述符,當(dāng)有數(shù)據(jù)達(dá)到時(shí),就可以讀取,沒(méi)有使用回調(diào)機(jī)制。整個(gè)過(guò)程是:在Java層的SensorManager的線程中不斷調(diào)用sensors_data_poll查詢數(shù)據(jù),這導(dǎo)致其JNI層的native實(shí)現(xiàn)在隊(duì)列上等待event事件(見(jiàn)隊(duì)列的成員函數(shù)waitForEvent,它使用poll進(jìn)行輪詢),也就是說(shuō),直到有管道中有數(shù)據(jù)可用才返回。當(dāng)沒(méi)有發(fā)生錯(cuò)誤返回時(shí),表示有數(shù)據(jù)可讀,然后對(duì)數(shù)據(jù)進(jìn)行讀取。一次讀取單位為一個(gè)event。

下面是JNI層中的sensors_data_poll代碼片段:

res = queue->read(&event, 1);
if (res == -EAGAIN) {
res = queue->waitForEvent();//
等待有數(shù)據(jù)可讀取
if (res != NO_ERROR)//
檢查是否發(fā)生錯(cuò)誤
return -1;
res = queue->read(&event, 1);//
沒(méi)錯(cuò)誤,進(jìn)行數(shù)據(jù)讀取
}

封裝管道的SensorChannel類的對(duì)象由ISensorEventConnection接口獲取。另外,對(duì)sensor的激活/去激活也是通過(guò)ISensorEventConnection調(diào)用到server側(cè)的SensorService完成的。

C++Sensor代表了一個(gè)sensor,它是HALsensor_t的封裝,同時(shí)又為Java層的Sensor類中的數(shù)據(jù)成員變量提供數(shù)據(jù)“源”,也就是說(shuō),Java中的Sensor的成員變量信息是由該C++中的Sensor類設(shè)置,后者又是根據(jù)sensor_t而獲取對(duì)應(yīng)的sensor信息。Java中的Sensor是應(yīng)用開(kāi)發(fā)的API類。在C++中的Sensor類中定義了sensor的枚舉類型:

enum {
TYPE_ACCELEROMETER = ASENSOR_TYPE_ACCELEROMETER, //
加速度
TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD, //
磁場(chǎng)
TYPE_GYROSCOPE = ASENSOR_TYPE_GYROSCOPE, //
陀螺儀
TYPE_LIGHT = ASENSOR_TYPE_LIGHT, //
光傳感器
TYPE_PROXIMITY = ASENSOR_TYPE_PROXIMITY //
距離傳感器
};

 

SensorService

frameworks/base/services/sensorservice/下面給出sensorService的相關(guān)實(shí)現(xiàn)代碼,它們最終生成libsensorservice.so庫(kù)文件,作為service被注冊(cè)到system server后,最終運(yùn)行于system_server后臺(tái)進(jìn)程空間。

Sensor service模塊的核心部分是SensorService類。另外還定義了幾個(gè)邏輯上的虛擬sensorGravitySensorLinearAccelerationSensorRotationVectorSensor,它們的接口由抽象類SensorInterface定義,物理意義上實(shí)際傳感器HardwareSensor也同樣遵循該接口規(guī)范。

SensorInterface與四個(gè)子類繼承關(guān)系圖如下:

SensorInterface是個(gè)抽象類,定義了五個(gè)接口:

virtual bool process(sensors_event_t* outEvent,const sensors_event_t& event) = 0; //處理原始數(shù)據(jù),換成上層應(yīng)用希望得到的數(shù)據(jù)

virtual status_t activate(void* ident, bool enabled) = 0; //激活與去激活

virtual sttus_t setDelay(void* ident, int handle, int64_t ns) = 0;//設(shè)置報(bào)告處理頻率

virtual Sensor getSensor() const = 0;//獲取對(duì)應(yīng)的sensor

virtual bool isVirtual() const = 0;//是否為虛擬的,即是否為邏輯(虛擬)傳感器

GravitySensorLinearAccelerationSensor,它們不是物理意義上的傳感器,只是邏輯意義上的傳感器,可稱之為虛擬(virtual)傳感器。它們實(shí)際上是將加速器(即gsensor)的值經(jīng)過(guò)處理過(guò)濾后再上報(bào)。

RotationVectorSensor方向向量傳感器,實(shí)際上它由加速器和磁場(chǎng)傳感器(compass)組成,根據(jù)它們上報(bào)的值來(lái)判斷是否旋轉(zhuǎn)屏幕。

引入虛擬傳感器的目的是方便上層程序的處理。在上層看來(lái),它不需要關(guān)注設(shè)備上的傳感器的某些原始數(shù)據(jù),只需要經(jīng)過(guò)加工處理后的數(shù)據(jù),如是否旋轉(zhuǎn)屏幕,它是依據(jù)虛擬的“傳感器”sensorRotationVectorSensor得來(lái)的經(jīng)過(guò)加工后的數(shù)據(jù)。這些虛擬傳感器包含了處理原始數(shù)據(jù)的算法。算法包含在重載的process函數(shù)中。

HardwareSensor代表了真正的傳感器,它繼承自SensorInterface,實(shí)現(xiàn)了各個(gè)抽象接口,但其實(shí)現(xiàn)是借助于與位于下層的HAL層的sensor硬件模塊打交道的類SensorDevice來(lái)完成的。

SensorDeviceHAL中的libsensors.so打交道,如獲取對(duì)應(yīng)的硬件module,打開(kāi)sensor設(shè)備,參見(jiàn)其構(gòu)造函數(shù):

SensorDevice::SensorDevice()
: mSensorDevice(0),
mSensorModule(0)
{
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const**)&mSensorModule);//
打開(kāi)sensor硬件模塊

LOGE_IF(err, “couldn’t load %s module (%s)”,
SENSORS_HARDWARE_MODULE_ID, strerror(-err));

if (mSensorModule) {
err = sensors_open(&mSensorModule->common, &mSensorDevice);//
打開(kāi)HAL層的poll設(shè)備
LOGE_IF(err, “couldn’t open device for module %s (%s)”,
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorDevice) {
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);//
獲取sensor_t列表
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
}
}
}
}

其結(jié)構(gòu)圖如下:

作為核心代碼的SensorService類有三個(gè)父類:

BinderService<SensorService>:繼承該父類使其成為一個(gè)標(biāo)準(zhǔn)的本地(nativeservice,將自己添加到系統(tǒng)的system server中去,其它感興趣者可以使用該service

BnSensorServer:意味著作為子類,SensorService是抽象類ISensorServer中定義的兩個(gè)接口(getSensorListcreateSensorEventConnection)的server側(cè)的真正實(shí)現(xiàn)者。一個(gè)接口是用來(lái)獲取系統(tǒng)的sensor列表,另一個(gè)則是創(chuàng)建一個(gè)事件連接(EventConnection),用于基于管道加上輪詢方式的event傳輸。

 

 

 

Thread:意味著它也是一個(gè)線程類,在SensorService創(chuàng)建后,有個(gè)單獨(dú)的線程去執(zhí)行重載的threadLoop。

這個(gè)threadLoop可以說(shuō)是整個(gè)sensor的調(diào)度處理中心,讓sensor相關(guān)的模塊都動(dòng)起來(lái)。作為一個(gè)后臺(tái)線程,它是個(gè)無(wú)限循環(huán),不斷去處理

bool SensorService::threadLoop()
{
LOGD(“nuSensorService thread starting…”);

const size_t numEventMax = 16 * (1 + mVirtualSensorList.size());
sensors_event_t buffer[numEventMax];
sensors_event_t scratch[numEventMax];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();

ssize_t count;
do {
count = device.poll(buffer, numEventMax);//
輪詢event數(shù)據(jù)到緩沖區(qū)
if (count<0) {
LOGE(“sensor poll failed (%s)”, strerror(-count));
break;
}

recordLastValue(buffer, count);//記錄每個(gè)sensor最新的值,記入到mLastEventSeen這個(gè)KeyedVector(從sensor標(biāo)識(shí)符到sensors_event_t的映射)中。

// handle virtual sensors
if (count && vcount) {//
下面是處理虛擬sensors數(shù)據(jù)
const DefaultKeyedVector<int, SensorInterface*> virtualSensors( getActiveVirtualSensors());

const size_t activeVirtualSensorCount = virtualSensors.size();

if (activeVirtualSensorCount) {
size_t k = 0;
for (size_t i=0 ; i<size_t(count) ; i++) {
sensors_event_t const * const event = buffer;
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
sensors_event_t out;
if (virtualSensors.valueAt(j)->process(&out, event[i])) {//
處理原始數(shù)據(jù),經(jīng)過(guò)處理轉(zhuǎn)換后的數(shù)據(jù)信息保存在out這個(gè)event
buffer[count + k] = out;//
將它們添加到buffer
k++;
}
}
}

if (k) {
// record the last synthesized values
recordLastValue(&buffer[count], k);//
同樣對(duì)虛擬的sensorevent最新值添加到mLastEventSeen
count += k;
// sort the buffer by time-stamps
sortEventBuffer(buffer, count);//
按時(shí)間戳排序
}
}
}

// send our events to clients…
const SortedVector< wp<SensorEventConnection> > activeConnections(
getActiveConnections());
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i<numConnections ; i++) {
sp<SensorEventConnection> connection(
activeConnections[i].promote());
if (connection != 0) {
connection->sendEvents(buffer, count, scratch);//
發(fā)送給client端,實(shí)際是寫入管道
}
}
} while (count >= 0 || Thread::exitPending());

LOGW(“Exiting SensorService::threadLoop!”);
return false;
}

因此,可以看出,SensorService的工作線程不斷去輪詢?cè)O(shè)備中是否有數(shù)據(jù)可用。當(dāng)有數(shù)據(jù)可用時(shí),將它們寫入管道。對(duì)方的應(yīng)用程序中的線程也不斷輪詢管道,當(dāng)有數(shù)據(jù)時(shí),便調(diào)用對(duì)應(yīng)的listener進(jìn)行處理。它們工作在不斷的線程中,或使用looper,或使用handler,在不同的線程循環(huán)中進(jìn)行處理,多次的異步操作構(gòu)成了sensor的處理過(guò)程。

 

HAL

Android HAL中只對(duì)sensors的數(shù)據(jù)結(jié)構(gòu)進(jìn)行了定義(見(jiàn)頭文件hardware/libhardware/include/hardware/sensors.h),其具體實(shí)現(xiàn)應(yīng)由芯片廠家給出。

在使用sensorsHAL時(shí),首先使用HAL提供的hw_get_module函數(shù),根據(jù)其模塊ID字符串(SENSORS_HARDWARE_MODULE_ID)獲取硬件模塊sensors_module_t,然后借助于sensors_module_t枚舉中設(shè)備中所帶的所有sensorssensor由結(jié)構(gòu)體sensor_t定義)列表。

數(shù)據(jù)結(jié)構(gòu)sensors_module_t定義了sensors硬件模塊,其中的get_sensors_list函數(shù)指針用于枚舉設(shè)備上的各種類型的sensor,實(shí)現(xiàn)由平臺(tái)廠商給出。

同樣,可以接著使用API函數(shù)sensors_open打開(kāi)HAL中定義的sensors_poll_device_t類型的設(shè)備,該結(jié)構(gòu)體定義三個(gè)API,用于激活/去激活sensor(見(jiàn)成員activate函數(shù)指針)、設(shè)置數(shù)據(jù)報(bào)告頻率(見(jiàn)setDelay函數(shù)指針)和輪訓(xùn)(見(jiàn)poll函數(shù)指針)。同樣,這三個(gè)函數(shù)也由平臺(tái)廠家實(shí)現(xiàn)。

這樣,我們可以使用hw_get_module函數(shù)打開(kāi)硬件模塊,并得到sensors列表,同時(shí),也可以使用sensors_open打開(kāi)sensors_poll_device_t類型的設(shè)備,對(duì)sensor進(jìn)行激活/去激活,輪詢讀數(shù)和設(shè)置數(shù)據(jù)報(bào)告頻率等基本操作。

結(jié)構(gòu)體sensor_t代表了一個(gè)sensor,定義了sensor的各種屬性,如:名稱、廠家、版本、句柄、類型、最大值范圍、解析度、功耗、數(shù)據(jù)上報(bào)頻率等。其定義具體如下:

struct sensor_t {
/* name of this sensors */
const char* name;//sensor
的名稱

/* vendor of the hardware part */
const char* vendor;//
廠家

/* version of the hardware part + driver. The value of this field is
* left to the implementation and doesn’t have to be monotonically
* increasing.
*/
int version;//
版本

/* handle that identifies this sensors. This handle is used to activate
* and deactivate this sensor. The value of the handle must be 8 bits
* in this version of the API.
*/
int handle;//
句柄,用于標(biāo)識(shí)是激活/去激活哪個(gè)sensor,亦即sensors_event_t中的int32_t sensor;它實(shí)際是由四個(gè)字符的ascii碼值來(lái)填充

/* this sensor’s type. */
int type;//sensor
類型,在sensor.h中定義了多達(dá)12種類型(有的為邏輯上的sensor),并以注釋的方式對(duì)它們進(jìn)行了詳細(xì)解釋

/* maximaum range of this sensor’s value in SI units */
float maxRange;//
最大取值范圍

/* smallest difference between two values reported by this sensor */
float resolution;//
解析度

/* rough estimate of this sensor’s power consumption in mA */
float power;//
估計(jì)的功耗,單位為mA

/* minimum delay allowed between events in microseconds. A value of zero means that this sensor doesn’t report events at a constant rate, but rather only when a new data is available */
int32_t minDelay;//
報(bào)告讀數(shù)值的events時(shí)間間隔(單位:ms),若為0,意味著不按該頻率報(bào)告,而是數(shù)據(jù)到來(lái)時(shí)才報(bào)告

/* reserved fields, must be zero */
void* reserved[8];//
保留
};

sensor的采樣值的上報(bào)可以按照某個(gè)固定的頻率進(jìn)行上報(bào),也可以當(dāng)有可用的數(shù)據(jù)時(shí)再上報(bào)(minDelay設(shè)為0)。上報(bào)數(shù)據(jù)以event的形式進(jìn)行,見(jiàn)結(jié)構(gòu)體sensors_event_t,它包含了sensor的標(biāo)識(shí)符、類型、數(shù)據(jù)采樣時(shí)間戳以及采樣數(shù)據(jù)。因?yàn)楦鞣Nsensor的采樣值各式各樣,它更多地是用聯(lián)合體union來(lái)定義,根據(jù)不同的sensor來(lái)解釋返回的值,比如,當(dāng)是加速器sensor或磁場(chǎng)sensor時(shí),就分別取聯(lián)合體中的accelerationmagnetic兩個(gè)字段,它們的類型是結(jié)構(gòu)體sensors_vec_t,其中又包含有union聯(lián)合體。這樣,Android將各種sensor統(tǒng)一成一種接口,依據(jù)不同的sensor分別對(duì)其標(biāo)識(shí)和類型對(duì)采樣值進(jìn)行解釋。

 

本文鏈接地址: http://www./?p=953

原創(chuàng)文章,版權(quán)?紅狼博客所有, 轉(zhuǎn)載隨意,但請(qǐng)注明出處。

    分享到:

相關(guān)文章:

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多