快捷搜索:

[Android的系统移植与平台开发]Sensor HAL框架分析

的观点

Sensor即传感器,在当前智妙手机上大年夜量存在:G-Sensor、LightsSensor、ProximitySensor、TemperatureSensor等,其作为Android系统的一个输入设备,对付注重用户体验的移动设备来说是必弗成少的。Sensor虽然是一个输入设备,然则它又不合于触摸屏,键盘,按键等这些老例的输入设备,由于Sensor的数据输入从传感器硬件到设备的,而老例的输入设备是从用户到设备的,比如:温度传感器用于感知温度的变更,采样传感器数据上报给设备。而传感器硬件的事情与否,采样精度是由用户来节制的,以是对应Sensor而言是其事情要领是双向的,即:节制硬件的节制流,硬件上报的数据流。这也抉择了Sensor的框架不合与触摸屏等老例输入子系统。

本章节主要钻研的Sensor框架代码与SensorHAL的实现细节,统统照样从Sensor框架开始,首先往返首下Led HAL的实现框架。

Led HAL是我们自己实现的,主要分为四部分:

Led App:Led的利用法度榜样

Led Service框架:Led利用的API供给者

LedService本地:LedService办事的本地实现,上层与底层的通信转化接口

Led HAL Stub:HAL层代码,详细硬件驱动操作接口

很显着,我们写的Led HAL代码是范例的节制流,反馈结果便是Led灯的亮与灭,它的架构不适用于Sensor架构,详细有如下几点:

l Led是纯真的节制流,而Sensor是节制流与数据流

Sensor的数据流不是实时的,而是有采样速度,并且数据不是继续的,壅闭在读取硬件设备数据上,只稀有据获得才返回。

l Sensor是供给给所有传感器的通用框架,不是针对某一特定硬件的架构

Sensor包孕多种类型,在上层和底层都有对Sensor详细类型的樊篱,让它通用所有传感器。

l Sensor的办事不是由利用法度榜样创建启动的,应该是伴随系统启动的

任何一个利用法度榜样里都可以应用Sensor办事,这抉择了Sensor办事应该伴随系统启动。

的框架阐发

本节是本系列第一个阐发的详细设备的框架,从Android SensorService的注册启动开始,到利用法度榜样得到SensorManager注册传感器监听器,具体阐发从利用层到Java框架层再到本地代码,着末调用HAL层整个历程。

1.1 Sensor办事的启动

由前面Android启动流程章节可知,Zygote启动起来后,运行的每一个Java进程是SystemServer,它用来启动并治理所有的Android办事:

public static void main(String[] args) {

System.loadLibrary("android_servers");

init1(args);

}

由SystemServer的main措施可知,其加载了libandroid_servers.so的库,并且调用了init1()措施。

我们经由过程下面的敕令来找到该库的编译目录:

find ./frameworks/base –name Android.mk –exec grep –l libandroid_servers{}\;

经由过程打印的信息知道,其对应的源码目录在:frameworks/base/services/jni/下,着实Android框架层的代码的特征便是Java目录下寄放的是对应的Java框架代码,对应的jni目录下是对应的本地代码。

在这个目录所有的代码最紧张的便是:com_android_server_SystemServer.cpp:

namespace android {

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv*env, jobject clazz)

{

system_init();

}

/*

* JNIregistration.

*/

static JNINativeMethod gMethods[] = {

/* name,signature, funcPtr */

{"init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1},

};

int register_android_server_SystemServer(JNIEnv* env)

{

returnjniRegisterNativeMethods(env, "com/android/server/SystemServer",

gMethods, NELEM(gMethods));

}

}; // namespace android

代码不是很多,也对照好读,调用jniRegisterNativeMethods措施注册SystemServer的Java措施也本地措施映射关系,jniRegisterNativeMethods是一个本地措施的注册Helper措施。

SystemServer.java在加载了libandroid_servers.so库之后,调用了init1(),经由过程上面代码中的映射关系可知,它调用了本地的android_server_SystemServer_init1措施,该措施直接调用system_init(),着实现在frameworks/base/cmds/system_server/library/system_init.cpp中实现:

extern "C" status_t system_init()

{

LOGI("Entered system_init()");

sp

proc(ProcessState::self());

sp sm = defaultServiceManager();

LOGI("ServiceManager: %p\n", sm.get());

sp grim = new GrimReaper();

sm->asBinder()->linkToDeath(grim, grim.get(), 0);

charpropBuf[PROPERTY_VALUE_MAX];

property_get("system_init.startsurfaceflinger", propBuf,"1");

if(strcmp(propBuf, "1") == 0) {

// Startthe SurfaceFlinger

SurfaceFlinger::instantiate();

}

property_get("system_init.startsensorservice", propBuf,"1");

if(strcmp(propBuf, "1") == 0) {

// Startthe sensor service

SensorService::instantiate();

}

LOGI("Systemserver: starting Android runtime.\n");

AndroidRuntime* runtime = AndroidRuntime::getRuntime();

LOGI("System server: starting Android services.\n");

JNIEnv* env =runtime->getJNIEnv();

if (env ==NULL) {

returnUNKNOWN_ERROR;

}

jclass clazz= env->FindClass("com/android/server/SystemServer");

if (clazz ==NULL) {

returnUNKNOWN_ERROR;

}

jmethodIDmethodId = env->GetStaticMethodID(clazz, "init2","()V");

if (methodId== NULL) {

returnUNKNOWN_ERROR;

}

env->CallStaticVoidMethod(clazz, methodId);

LOGI("System server: entering thread pool.\n");

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

LOGI("System server: exiting thread pool.\n");

}

假如懂得Binder机制的话,应该知道,sp

proc(ProcessState::self())打开Binder驱动并会创建一个ProcessState工具并保持当提高程的Binder通信的办事器端。

假如系统属性里设置设置设备摆设摆设了system_init.startsensorservice 属性为1,则经由过程SensorService::instantiate()启动Sensor办事。

对付初学者最头疼的便是追面向工具代码中的重载,重写的代码了,SensorService::instantiate()调用的是其父类的措施,我们可以经由过程子类的定义找其承袭关系,然后顺着承袭关系再来查找措施的实现,假如在子类里和父类里都有措施的实现,那么看参数的匹配,假如参数都互相匹配,那么便是所谓的重写,调用的是子类的措施。SensorService的定义如下:

@frameworks/base/services/sensorservice/SensroService.h

class SensorService :

publicBinderService,

publicBnSensorServer,

protectedThread

{

经由过程SensorService的定义可知,在当前类里没有instantiate措施的声明,阐明其调用的是父类的措施,其承袭了BinderService,BnSensorServer,Thread类(难道SensorService是一个线程??),顺着承袭关系找,在BinderService里可以找到instantiate措施的声明。

@frameworks/base/include/binder/BinderService.h

template

class BinderService

{

public:

staticstatus_t publish() {

sp sm(defaultServiceManager());

returnsm->addService(String16(SERVICE::getServiceName()), new SERVICE());

}

static voidpublishAndJoinThreadPool() {

sp

proc(ProcessState::self());

sp sm(defaultServiceManager());

sm->addService(String16(SERVICE::getServiceName()), new SERVICE());

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

static void instantiate() { publish(); }

staticstatus_t shutdown() {

returnNO_ERROR;

}

};

经由过程上面代码阐发可知,instantiate措施创建了SensorService并经由过程addService将自己新创建的SensorService办事添加到Android办事列表里了。

Ok,那我们来到SensorService办事中。

@frameworks/base/services/sensorservice/SensorService.cpp

SensorService::SensorService()

:mInitCheck(NO_INIT)

{

}

void SensorService::onFirstRef()

{

LOGD("nuSensorService starting...");

SensorDevice& dev(SensorDevice::getInstance());

SensorService的构造措施对照简单,初始化了成员变量mInitCheck为NO_INIT。

要留意构造措施后面的onFirstRef措施,它是Android系统里引用计数系统里的一个措施。当RefBase的子类工具被第一次强引用时自动调用其措施,以是当第一次应用SensorService办事里该措施被自动回调。

形如:

sp sm(mSensorService);

注:关于引用计数系统,假如读者不太懂得,请参考邓凡平师长教师的:深入理解:Android系统核心 卷I中的三板斧部分。

SensorService的启动到此停息,等待上层利用的应用SensorService办事并调用onFirstRef措施。

转自:http://blog.csdn.net/mr_raptor/article/details/8090474

您可能还会对下面的文章感兴趣: