分享

Sensor 代码流程分析

 jemeen 2012-02-02

本文针对android 2.3 版本的sensor从应用到hal层接口进行逐层分析。4.0的代码也拿到了,不过还没有来得及进行分析。

一、应用程序,一般的应用程序写法:

package com.sensors.testSensor; 

import android.app.Activity;

import android.os.Bundle;

 

import android.util.Log;

import android.widget.TextView;

import android.hardware.SensorManager;

import android.hardware.Sensor;

import android.hardware.SensorEvent;

import android.hardware.SensorEventListener;

 

public class testSensor extends Activity {

    SensorManager sensormanager = null;

    Sensor lightSensor = null;

    TextView accTextView = null;

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    sensormanager = (SensorManager)getSystemService(SENSOR_SERVICE);   // 获取SensorManager 客户端对象

    lightSensor = sensormanager.getDefaultSensor(Sensor.TYPE_LIGHT);   // 获取LIGTH传感器,或者直接传入Sensor.TYPE_ALL 获取所有的sensorList

    accTextView = (TextView)findViewById(R.id.textview_name);

    }

   

    SensorEventListener lsn = new SensorEventListener() {  

        public void onSensorChanged(SensorEvent e) {

       if (e.sensor == lightSensor) {

             Log.d("sensor", "found light sensor");

                accTextView.setText("data is " + e.values[0]);

        }

        }  

 

        public void onAccuracyChanged(Sensor s, int accuracy) {  

//TODO

        }  

    };    

    @Override   

    protected void onResume() {       //注册传感器

     super.onResume();      // register this class as a listener for the orientation and accelerometer sensors       

     sensormanager.registerListener(lsn, lightSensor, SensorManager.SENSOR_DELAY_NORMAL);

    }       

    @Override   

    protected void onStop() {        // unregister listener        

     sensormanager.unregisterListener(lsn, lightSensor);

     super.onStop();   

    }  

}


总之,应用中实现如下两个重要回调函数即可捕获sensor data数据:

public void onSensorChanged(SensorEvent e)
public void onAccuracyChanged(Sensor s, int accuracy)


首先来张整体模块图,让大家有个总体认识 :



二、分析客户端的实现

首先获取到所有sensor列表
public List<Sensor> getSensorList(int type)


加入到ListenerDelegate监控列表中
public boolean registerListener(SensorListener listener, int sensors)


l = new ListenerDelegate(listener, sensor, handler);
sListeners.add(l);


使能或禁能调用(启动哪些sensor采集数据):
private boolean enableSensorLocked(Sensor sensor, int delay)


sensors_enable_sensor --> jni (sensors_enable_sensor) -->  
利用binder调用sensorservice 的 enableDisable函数


获取数据:
final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
--> jni (sensors_data_poll) --> 调用sensordevice中的ssize_t poll(sensors_event_t* buffer, size_t count)函数


不过这个中间有个sensorchannel的机制,这里充分利用了pipe机制
SensorChannel::SensorChannel()
    : mSendFd(-1), mReceiveFd(-1)
{
    int fds[2];
    if (pipe(fds) == 0) {
        mReceiveFd = fds[0];
        mSendFd = fds[1];
        fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
        fcntl(mSendFd, F_SETFL, O_NONBLOCK);
    }
}

/* sensorservice 往管道中写入数据 */
ssize_t SensorChannel::write(void const* vaddr, size_t size)
{
    ssize_t len = ::write(mSendFd, vaddr, size);
    if (len < 0)
        return -errno;
    return len;
}


/* 从管道中读取数据 */
ssize_t SensorChannel::read(void* vaddr, size_t size)
{
    ssize_t len = ::read(mReceiveFd, vaddr, size);
    if (len < 0)
        return -errno;
    return len;
}


对于SensorManager.cpp 说明一下:

首先获取sensorService的服务:

    const String16 name("sensorservice");
    while (getService(name, &mSensorServer) != NO_ERROR) {
        usleep(250000);
    }


三、分析服务端的实现

sensorService的注册:

system_init.cpp 

extern "C" status_t system_init()
{  

   // Start the sensor service
     SensorService::instantiate();

}

-->

static void instantiate() { publish(); }

    static status_t publish() {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
    }


利用BinderService的publish方法进行注册,所以可以在这里看到:

class SensorService :
        public BinderService<SensorService>,
        public BnSensorServer,
        protected Thread

重要的一些函数说明:

加入监控的sensor设备
virtual status_t enableDisable(int handle, bool enabled);
--->
sensor->activate(connection.get(), true)
-->
SensorRecord * rec = new SensorRecord(connection);;
rec->addConnection(connection) --> connection->sendEvents(&event, 1);


获取sensordevice的数据并写入sensorchannel:
bool SensorService::threadLoop()
{
while(1){
/* poll sensor device data */
count = device.poll(buffer, numEventMax);

recordLastValue(buffer, count);

// send our events to clients...
connection->sendEvents(buffer, count, scratch);
...
}
}


四、客户端与服务端通讯过程

利用binder机制即可,列出重要的代码:

class ISensorEventConnection : public IInterface  // 用于客户端
{
public:
    DECLARE_META_INTERFACE(SensorEventConnection);     // 声明一个SensorEventConnection模板

...

}


class BnSensorEventConnection : public BnInterface<ISensorEventConnection> // 服务端代码

{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

实现中重要的实现:

IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");


status_t BnSensorEventConnection::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {

case XXX:

break;

    }

return BBinder::onTransact(code, data, reply, flags);

}


ok, 对于binder机制的问题可以参考, 在此就不详细介绍了:

http://blog.csdn.net/andyhuabing/article/details/7004593


五、 HAL层接口

上层调用类 SensorDevice:

主要调用逻辑:

   // 加载动态库 

    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

  // 打开sensor 设备

  sensors_open(&mSensorModule->common, &mSensorDevice);


 最重要的四个hal接口函数:

    int (*get_sensors_list)(struct sensors_module_t* module,
            struct sensor_t const** list);  // sensorList列表信息

    int (*activate)(struct sensors_poll_device_t *dev,
            int handle, int enabled);    int (*setDelay)(struct sensors_poll_device_t *dev,
            int handle, int64_t ns);   // 使用及禁止

    int (*setDelay)(struct sensors_poll_device_t *dev,
            int handle, int64_t ns);  // 延时或采样频率

    int (*poll)(struct sensors_poll_device_t *dev,
            sensors_event_t* data, int count);  // poll数据


这块代码实现可以参考:

device\htc\passion-common\libsensors

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多