Android Sensor (g-sensor) 系统源码分析

Android Sensor框架简述(一) Sensor整体框架 什么是Sensor? Sensor就是所谓的传感器,比如AccelerometerSensor、MagneticSensor、OrientationSensor、ProximitySensor、LightSensor、Gyro等。黄色部分:硬件,在I2C总线上红色部分:驱动,驱动注册到Kernel的Input Subsystem上,然后通过Event Device把Sens 阅读详情

探究一下Android的Sensor架构。主要目的是通过Sensor这个架构去初步了解Android系统是怎么的一个编程思想,整体架构和功能是怎么安排的。各个模块间是怎么进行通信和交互,最重要的了解一个整个数据流是怎么传送的。更要提高自己去大型源码的处理能力,这里以Gsensor为例

 

源码平台MTK Android 4.4.0源码。

日期:2015年3月22日

一. 在App的使用方法

1
2
3
4
5
6
7

 

SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor accSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.unregisterListener(this, accSensor);
//在Listener中实现数据的监听
public void onSensorChanged(SensorEvent event)
public void onAccuracyChanged(Sensor sensor, int accuracy)

我现在要从SensorManager为入口去探究

二. SensorManager的初始化

SensorManager就是整个Sensor架构最开始的地方,所以它的初始化也是整个Sensor架构的初始化。

SensorManager在Frameworks中被继承为SystemSensorManager。

SystemSensorManager在两处被调用。

1. 在frameworks\base\core\java\android\appContextimpl.java中,供App用getSystemService()来获取服务。

1
2
3
4
5
6

 

registerService(SENSOR_SERVICE, new ServiceFetcher() {
    public Object createService(ContextImpl ctx) {
        return new SystemSensorManager(ctx.getOuterContext(),
                                       ctx.mMainThread.getHandler().getLooper());
    }
});

2. frameworks\base\services\java\com\android\server\power\PowerManagerService.java 在系统初始化时systemReady()中被调用

1

 

new SystemSensorManager(mContext, mHandler.getLooper());

SystemSensorManager构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

 

public SystemSensorManager(Context context, Looper mainLooper) {
    /*  在base/core/jni/android_hardware_SensorManager.cpp中
        主要是找到Sensor类,并把类成员的jfieldID找到   */

    nativeClassInit();
    
    // initialize the sensor list
    final ArrayList<Sensor> fullList = sFullSensorsList;
    int i = 0;
    do {
        Sensor sensor = new Sensor();
        /*初始化JNI的SensorManager
        并通过SensorManager获取Sensor List,把List里的Sensor一个个传递上来*/

        i = nativeGetNextSensor(sensor, i);
        if (i >= 0) {
            fullList.add(sensor);
            sHandleToSensor.append(sensor.getHandle(), sensor);
        }
    } while (i > 0);
}

nativeGetNextSensor函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

 

static jint nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next){
    //初始化SensorManager
    SensorManager& mgr(SensorManager::getInstance());

    Sensor const* const* sensorList;
    //获取Sensor List
    size_t count = mgr.getSensorList(&sensorList); 

    Sensor const* const list = sensorList[next];
    const SensorOffsets& sensorOffsets(gSensorOffsets);
    jstring name = env->NewStringUTF(list->getName().string());
    jstring vendor = env->NewStringUTF(list->getVendor().string());
    env->SetObjectField(sensor, sensorOffsets.name,      name);
    //...后面的就是设置Sensor类成员了
}

native/libs/gui/SensorManager.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

 

SensorManager::SensorManager()
    assertStateLocked();
}

status_t SensorManager::assertStateLocked() const {
    if (mSensorServer == NULL) {
        // try for one second
        const String16 name("sensorservice");

        status_t err = getService(name, &mSensorServer);

        //注册sensorservice服务死亡通知
        mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
        mSensorServer->asBinder()->linkToDeath(mDeathObserver);
        
        //获取SensorList
        mSensors = mSensorServer->getSensorList();
        size_t count = mSensors.size();
        mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
        for (size_t i=0 ; i<count ; i++) {
            mSensorList[i] = mSensors.array() + i;
        }
    }
}

native/services/sensorservice/SensorService.cpp

1
2
3
4

 

Vector<Sensor> SensorService::getSensorList() {
    //......
    return mUserSensorList;
}

mUserSensorList在onFirstRef()函数里初始化

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

 

void SensorService::onFirstRef() {

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

if (dev.initCheck() == NO_ERROR) {
        sensor_t const *list;
        ssize_t count = dev.getSensorList(&list);
if (count > 0) {
            ssize_t orientationIndex = -1;
bool hasGyro = false;
            uint32_t virtualSensorsNeeds =
                (1 << SENSOR_TYPE_GRAVITY) |
                (1 << SENSOR_TYPE_LINEAR_ACCELERATION) |
                (1 << SENSOR_TYPE_ROTATION_VECTOR);
            mLastEventSeen.setCapacity(count);
for (ssize_t i = 0 ; i < count ; i++) {
//把Sensor添加到SensorService的List中
                registerSensor( new HardwareSensor(list[i]) );              
//... 添加Sensor和Virtual Sensor
                
//启动子线程,主要用来捕获和分发数据。后面会讲到
                run("SensorService", PRIORITY_URGENT_DISPLAY);
    }
}

 

上面的主要是SensorDevice和SensorDevice.getSensorList();

SensorDevice开始与Hardware层打交道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

 

SensorDevice::SensorDevice(){
    /*获取hw模块,模块ID为SENSORS_HARDWARE_MODULE_ID*/
    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

    if (mSensorModule) {
        /*定义在hardware/sensors.h,主要是调用模块的open函数
            module->methods->open(...);*/

        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);

        if (mSensorDevice) {
            sensor_t const* list;
            //再次获取sensor list
            ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
            mActivationCount.setCapacity(count);
            Info model;
            for (size_t i=0 ; i<size_t(count) ; i++) {
                mActivationCount.add(list[i].handle, model);
                //激活Sensor
                mSensorDevice->activate(
                        reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
                        list[i].handle, 0);
            }
        }
    }
}

SENSORS_HARDWARE_MODULE_ID模块在hardware/sensor/Sensor.c中

sensors_open_1调用了此模块的open函数

1
2
3
4

 

static int open_sensors(const struct hw_module_t *module, const char *name,
                        struct hw_device_t **device) {
    return init_nusensors(module, device);
}

init_nusensors在hardware/sensor/Nusensors.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

 

int init_nusensors(hw_module_t const *module, hw_device_t **device) {
    
    sensors_poll_context_t *dev = new sensors_poll_context_t();
    memset(&dev->device, 0, sizeof(sensors_poll_device_1));
    //初始化hw_device_t
    dev->device.common.tag = HARDWARE_DEVICE_TAG;
    dev->device.common.version  = 0;//SENSORS_DEVICE_API_VERSION_1_1;
    dev->device.common.module   = const_cast<hw_module_t *>(module);
    dev->device.common.close    = poll__close;
    dev->device.activate        = poll__activate;
    dev->device.setDelay        = poll__setDelay;
    dev->device.poll            = poll__poll;
    dev->device.batch           = poll__batch;
    dev->device.flush           = poll__flush;
    *device = &dev->device.common;
    status = 0;
    return status;
}

SensorDevice然后调用sensor.cpp里的get_sensors_list

1
2
3
4
5
6

 

static int sensors__get_sensors_list(struct sensors_module_t *module,
                                     struct sensor_t const **list) {
    //这个就是最低层的sensorlist                                 
    *list = sSensorList;
    return ARRAY_SIZE(sSensorList);
}

hardware\sensor\hwmsen_chip_info.c  sSensorList里包含了所有的Sensor信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

 

struct sensor_t sSensorList[MAX_NUM_SENSOR] = 
{
#ifdef CUSTOM_KERNEL_ACCELEROMETER
    {  
        .name       = ACCELEROMETER,
        .vendor     = ACCELEROMETER_VENDER,
        .version    = 1,
        .handle     = ID_ACCELEROMETER,
        .type       = SENSOR_TYPE_ACCELEROMETER,
        .maxRange   = ACCELEROMETER_RANGE,//32.0f,
        .resolution = ACCELEROMETER_RESOLUTION,//4.0f/1024.0f,
        .power      = ACCELEROMETER_POWER,//130.0f/1000.0f,
        .reserved   = {}
    },  
    {  
        .name       = ACCELEROMETER_1,
        .vendor     = ACCELEROMETER_VENDER,
        .version    = 1,
        .handle     = ID_ACCELEROMETER,
        .type       = SENSOR_TYPE_ACCELEROMETER,
        .maxRange   = ACCELEROMETER_RANGE,//32.0f,
        .resolution = ACCELEROMETER_RESOLUTION,//4.0f/1024.0f,
        .power      = ACCELEROMETER_POWER,//130.0f/1000.0f,
        .reserved   = {}
    },
    {  
        .name       = ACCELEROMETER_2,
        .vendor     = ACCELEROMETER_VENDER,
        .version    = 1,
        .handle     = ID_ACCELEROMETER,
        .type       = SENSOR_TYPE_ACCELEROMETER,
        .maxRange   = ACCELEROMETER_RANGE,//32.0f,
        .resolution = ACCELEROMETER_RESOLUTION,//4.0f/1024.0f,
        .power      = ACCELEROMETER_POWER,//130.0f/1000.0f,
        .reserved   = {}
    },
#endif

#ifdef CUSTOM_KERNEL_ALSPS
    { 
        .name       = PROXIMITY,
        .vendor     = PROXIMITY_VENDER,
        .version    = 1,
        .handle     = ID_PROXIMITY,
        .type       = SENSOR_TYPE_PROXIMITY,
        .maxRange   = PROXIMITY_RANGE,//1.00f,
        .resolution = PROXIMITY_RESOLUTION,//1.0f,
        .power      = PROXIMITY_POWER,//0.13f,
        .reserved   = {}
    },
    //....
};

SensorDevice接着调用 mSensorDevice->activate();  

在这里我们先理清楚一下mSensorDevice的类型转换问题

mSensorDevice的类型为sensors_poll_device_1_t,在最后的初始化为*device = &dev->device.common; common为hw_device_t类型。dev为sensors_poll_context_t类型。

再来看看这几个类型之间的关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

 

struct sensors_poll_context_t {
    struct sensors_poll_device_t device; // must be first

    sensors_poll_context_t();

    int activate(int handle, int enabled);
    //...
};

struct sensors_poll_device_t {
    struct hw_device_t common;
    int (*activate)(struct sensors_poll_device_t *dev,
 
    int (*setDelay)(struct sensors_poll_device_t *dev,
   
    int (*poll)(struct sensors_poll_device_t *dev,
};


typedef struct sensors_poll_device_1 {
    union {
        struct sensors_poll_device_t v0;

        struct {
            struct hw_device_t common;
            
            int (*activate)(struct sensors_poll_device_t *dev,
            
            int (*setDelay)(struct sensors_poll_device_t *dev,
            
            int (*poll)(struct sensors_poll_device_t *dev,
        };
    };
    int (*batch)(struct sensors_poll_device_1* dev,
    int (*flush)(struct sensors_poll_device_1* dev, int handle);
    void (*reserved_procs[8])(void);
} sensors_poll_device_1_t;
 

sensors_poll_context_t的device和sensors_poll_device_t的common都在第一位,所以他们的指针地址都是一样的。

只要获取了首地址后,就可以通过类型的不同取到不同的值。

首先是mSensorDevice的sensors_poll_device_1_t,sensors_poll_device_1_t 的前半节成员位置分布是与 sensors_poll_context_t的一样的,所以mSensorDevice->activate调的就是初始化之后的poll__activate()。poll__activate的第一个参数又是mSensorDevice,poll__activate里又把它转换为sensors_poll_context_t,这样就可以调用sensors_poll_context_t里面的activate()函数。

sensors_poll_context_t的activate():

其中的handle是sSensorList里的handle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

 

int sensors_poll_context_t::activate(int handle, int enabled) {
    
    int index = handleToDriver(handle);
    //使能Sensor
    if(ID_ORIENTATION == handle)    {
        ((AccelerationSensor*)(mSensors[accel]))->enableNoHALDataAcc(enabled);
        ((Hwmsen*)(mSensors[hwmsen]))->enableNoHALDataAcc(enabled);
    }
    
    if(NULL != mSensors[index] && index >0 )    {
       ALOGD( "use new sensor index=%d, mSensors[index](%x)", index, mSensors[index]);
       err =  mSensors[index]->enable(handle, enabled);
    }
    
    if(err || index<0 ) {
        ALOGD("use old sensor err(%d),index(%d) go to old hwmsen\n",err,index);
        // notify to hwmsen sensor to support old architecture
        err =  mSensors[hwmsen]->enable(handle, enabled);
    }
    
    if (enabled && !err) {
    //通过管道发送唤醒消息。这里有个疑问,一初始化就把所有的Sensor setenable和wake了,不会耗电吗?不是另有其用
        const char wakeMessage(WAKE_MESSAGE);
        int result = write(mWritePipeFd, &wakeMessage, 1);
        ALOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));
    }
    return err;
}

其中的hwmsen是MTK提供的对所有的Sensor驱动进行统一管理的一个小架构。Hwmsen这个类会打开"/dev/hwmsensor"节点,访问hwmsen低层驱动,hwmsen集中了所有的sensor驱动,进行统一的管理。在sensors_poll_context_t()的构造函数中,把很多sensor类赋值给了mSensors,这里类继承了SensorBase。hardware层就是通过这些类去访问低层驱动。

三. Sensor数据的监听

这个要从App的registerListener说起。

App里getDefaultSensor根据Sensor Type从SensorList里获取出相应的Sensor传入到registerListener,先传入的是SensorManager.java的registerListener。

 

1
2
3
4
5
6
7
8
9

 

public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs) {
return registerListener(listener, sensor, rateUs, null);
}

public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
                                Handler handler) {
int delay = getDelay(rateUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}

 

registerListenerImpl在SystemSensorManager.java里实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

 

protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {

    SensorEventQueue queue = mSensorListeners.get(listener);
//以前没有添加过的Listener,走这里
    if (queue == null) {
//获取主线程的Looper
        Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
//新建一个SensorEventQueue
        queue = new SensorEventQueue(listener, looper, this);
//把Sensor添加进这个Queue
        if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
            queue.dispose();
return false;
        }
        mSensorListeners.put(listener, queue);
return true;
    } else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
    }
}

new SensorEventQueue()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

 

public SensorEventQueue(SensorEventListener listener, Looper looper,
                        SystemSensorManager manager) {
    super(looper, manager);
}

BaseEventQueue(Looper looper, SystemSensorManager manager) {
//创建Native层的EventQueue
    nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch); 
}
/*
nativeInitBaseEventQueue在native层对应的是nativeInitSensorEventQueue
在Frameworks/base/core/jni/android_hardware_SensorManager.cpp
*/


static jint nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQ, jobject msgQ, jfloatArray scratch) {
    SensorManager& mgr(SensorManager::getInstance());
//真正创建SensorEventQueue
    sp<SensorEventQueue> queue(mgr.createEventQueue());

    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);

//Receiver继承LooperCallback,主要用于数据的Poll。
    sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQ, scratch);
}

 

SensorManager.cpp

1
2
3
4
5
6
7
8
9
10
11

 

sp<SensorEventQueue> SensorManager::createEventQueue() {
    sp<SensorEventQueue> queue;
//通过SensorServer创建一个Connection
    sp<ISensorEventConnection> connection =
            mSensorServer->createSensorEventConnection();

//通过这个Connection创建一个SensorEventQueue        
    queue = new SensorEventQueue(connection);

return queue;
}

 

SensorService.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

 

sp<ISensorEventConnection> SensorService::createSensorEventConnection() {
    uid_t uid = IPCThreadState::self()->getCallingUid();
    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
return result;
}

SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid){

const SensorDevice& device(SensorDevice::getInstance());
//这个VERSION在hardware/sensor/Sensor.c的sensor_module_t里
    if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
// Increase socket buffer size to 1MB for batching capabilities.
        mChannel = new BitTube(service->mSocketBufferSize);
    } else {
//代码里的VERSION是1.0
        mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
    }
}

 

native/libs.gui/BitTube.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

 

BitTube::BitTube(size_t bufsize)
    : mSendFd(-1), mReceiveFd(-1)   {

    init(bufsize, bufsize);
}

void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// sine we don't use the "return channel", we keep it small...
        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
        fcntl(sockets[0], F_SETFL, O_NONBLOCK);
        fcntl(sockets[1], F_SETFL, O_NONBLOCK);
//这里主要是初始化mReceiveFd和mSendFd,用来后面的消息和数据的传递
        mReceiveFd = sockets[0];
        mSendFd = sockets[1];
    } else {
        mReceiveFd = -errno;
        ALOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
    }
}

回到createEventQueue(),new SensorEventQueue(connection);

1
2
3
4

 

SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
    : mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0) {
    mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
}

这里android_hardware_SensorManager.cpp的nativeInitSensorEventQueue(),createEventQueue已经创建完。接下来创建了一个messageQueue。把SensorEventQueue和MessageQueue一起传给了Receiver,这个Receiver继承于LooperCallback。那这些类之间有什么联系呢。

写过APP的就都对Handler,Mesg和Looper有一些了解。而这些的底层实现就会刚才提到的这几个类有关,Android用此来实现进程间通信。这里简要说明:

MessageQueue是一个消息队列,用于存放消息。

Looper相当于一个消息管理者,它管理着队列里的消息进出,分发。它会把队列里的消息分发给相应的处理者。

整个进程间通信间通信用的是poll相关的FD来实现,此机制还提供了一个addFd接口。些接口传入了一个fd和一个LooperCallback,如果有消息过来,就会调用LooperCallback。

在Receiver的onFirstRef()

 

1
2
3
4
5
6
7

 

virtual void onFirstRef() {
    LooperCallback::onFirstRef();
//mSensorQueue->getFd(),得到的是BitTube里的mReceiveFd。
    //这里开始监听mReceiveFd。如果有消息过来则调用handleEvent
    mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
                                      ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
}

 

 

四. Sensor的使能

registerListenerImpl创建了一个queue后会把Sensor加入到queue里

1

 

queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)

这个函数主要是enableSensor,enableSensor可以追踪到SensorService的enable函数里。

SensorService的enable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

 

status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags){
//mSensorMap在registerSensor里初始化。
    //这个获取出来的sensor在registerSensor的时候就与SensorDevice绑定
    //即调用这个sensor里的函数就相当于调用SensorDevice里的函数
    SensorInterface* sensor = mSensorMap.valueFor(handle);

    rec = new SensorRecord(connection);
//把相应的Sensor handle(即Sensor Type)加入到activesSensor
    mActiveSensors.add(handle, rec);

//把handle与connection绑定
    if (connection->addSensor(handle)) {
        BatteryService::enableSensor(connection->getUid(), handle);

if (mActiveConnections.indexOf(connection) < 0) {
//并把connection加入到ActiveConnection的队列里
            mActiveConnections.add(connection);
        }
    } 

    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
                                 maxBatchReportLatencyNs);
if (err == NO_ERROR) {
        connection->setFirstFlushPending(handle, true);
        status_t err_flush = sensor->flush(connection.get(), handle);
// Flush may return error if the sensor is not activated or the underlying h/w sensor does
        // not support flush.
        if (err_flush != NO_ERROR) {
            connection->setFirstFlushPending(handle, false);
        }
    }

//真正启动Sensor
    sensor->activate(connection.get(), true);
}

 

SensorDevice在初始化的时候与ID为SENSORS_HARDWARE_MODULE_ID的hardware层的模块进行了绑定。

上面的activate相当于调用了nusensors.cpp的poll__activate函数,poll__activate 再调用当前文件的activate函数。此activate函数根据handle调用相应Sensor类。如这里调用 了hwmsen类,就相当于调用了hwmsen.cpp里的activate。这个Sensor类,就直接与驱动文件打交道了

 

五. 数据的获取

SensorService继承了Thread,其中的onFirstRef()调用了run(),线程跑了起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

 

bool SensorService::threadLoop(){
    sensors_event_t buffer[minBufferSize];

do {
        count = device.poll(buffer, numEventMax);

//我们现在的机器没有虚拟传感器,所以忽略了虚拟传感器部分。
        //现在的版本为1.0,所以不会跑这里
        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { }

// 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);
// Some sensors need to be auto disabled after the trigger
                cleanupAutoDisabledSensor(connection, buffer, count);
            }
        }

// We have read the data, upper layers should hold the wakelock.
        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
    } while (count >= 0 || Thread::exitPending());
}

 

上面调用了SensorDevice的poll,由之前的逻辑可知。SensorDevice的poll最后会调用到nusensors.cpp的poll_poll,poll_poll调用了pollEvents()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

 

int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count){
do {
// see if we have some leftover from the last poll()
        for (int i=0 ; count && i<numSensorDrivers ; i++) {
            SensorBase* const sensor(mSensors[i]);
if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
//如果有数据就调用sensor的readEvents
                int nb = sensor->readEvents(data, count);
if (nb < count) {
// no more data for this sensor
                    mPollFds[i].revents = 0;
                }
                count -= nb;
                nbEvents += nb;
                data += nb;
            }
        }

if (count) {        
            n = poll(mPollFds, numFds, nbEvents ? 0 : -1);            
        }

// if we have events and space, go read them
    } while (n && count);
}

 

以hwmsen的readEvents为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

 

int Hwmsen::readEvents(sensors_event_t* data, int count){
//读取input数据
    ssize_t n = mInputReader.fill(mdata_fd);

int numEventReceived = 0;
    input_event const* event;

while (count && mInputReader.readEvent(&event)) {
int type = event->type;

if (type == EV_REL) 
        {
            processEvent(event->code, event->value);
            int64_t time = timevalToNano(event->time);

for (i=0 ; count && i<MAX_ANDROID_SENSOR_NUM ; i++) 
            {
if (mPendingMask & (1<<i)) 
               {
                    mPendingMask &= ~(1<<i);

                    *data++ = mPendingEvents[i];
                    count--;
                    numEventReceived++;
               }                    
            }
        }  
        mInputReader.next();
    }
return numEventReceived;
}

void Hwmsen::processEvent(int code, int value)
{
    hwm_trans_data sensors_data;

    sensors_data.date_type = value;//set flag to read specified sensor
    //真正获取Sensor Data
    err = ioctl(dev_fd, HWM_IO_GET_SENSORS_DATA, &sensors_data);

for(i =0; i < MAX_ANDROID_SENSOR_NUM; i++)  {
//根据不同的Snesor类型处理数据
        switch (i) {                  
case ID_ORIENTATION:
break;

case ID_MAGNETIC:
break;

case ID_ACCELEROMETER:

            mPendingMask |= 1<<Accelerometer;
            mPendingEvents[Accelerometer].type = SENSOR_TYPE_ACCELEROMETER;
            mPendingEvents[Accelerometer].sensor = sensors_data.data[ID_ACCELEROMETER].sensor;
            mPendingEvents[Accelerometer].acceleration.status = sensors_data.data[ID_ACCELEROMETER].status;
            mPendingEvents[Accelerometer].acceleration.v[0] = (float)sensors_data.data[ID_ACCELEROMETER].values[0];
            mPendingEvents[Accelerometer].acceleration.v[1] = (float)sensors_data.data[ID_ACCELEROMETER].values[1];
            mPendingEvents[Accelerometer].acceleration.v[2] = (float)sensors_data.data[ID_ACCELEROMETER].values[2];

            mPendingEvents[Accelerometer].acceleration.v[0]/=sensors_data.data[ID_ACCELEROMETER].value_divide;
            mPendingEvents[Accelerometer].acceleration.v[1]/=sensors_data.data[ID_ACCELEROMETER].value_divide;
            mPendingEvents[Accelerometer].acceleration.v[2]/=sensors_data.data[ID_ACCELEROMETER].value_divide;
            mPendingEvents[Accelerometer].timestamp = sensors_data.data[ID_ACCELEROMETER].time;
//ALOGE("[ID_ACCELEROMETER](%f,%f,%f) \r\n",mPendingEvents[Accelerometer].acceleration.v[0],mPendingEvents[Accelerometer].acceleration.v[1],mPendingEvents[Accelerometer].acceleration.v[2]);
            break;
case ID_GYROSCOPE:
break;

case ID_PROXIMITY:
break;

case ID_LIGHT:
break;
       }    
    }
}

Input上来的是什么样的数据?!!数据类型是什么,后面的buffer[i].type == SENSOR_TYPE_STEP_COUNTER的type在哪里被初始化

 

SensorService的threadloop就这样把数据读出来。然后会把数据通过activeConnections队列,connection->sendEvents 把数据分发到所有的connection。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

 

status_t SensorService::SensorEventConnection::sendEvents(
        sensors_event_t const* buffer, size_t numEvents,
        sensors_event_t* scratch)
{
// filter out events not for this connection
    size_t count = 0;

//这里传入的scratch为空
    if (scratch) {
    } else {
        scratch = const_cast<sensors_event_t *>(buffer);
        count = numEvents;
    }

// Send pending flush events (if any) before sending events from the cache.
    {
        ASensorEvent flushCompleteEvent;
        flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
        flushCompleteEvent.sensor = 0;
        Mutex::Autolock _l(mConnectionLock);
// Loop through all the sensors for this connection and check if there are any pending
        // flush complete events to be sent.
        for (size_t i = 0; i < mSensorInfo.size(); ++i) {
            FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
while (flushInfo.mPendingFlushEventsToSend > 0) {
                flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
                ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
if (size < 0) {
// ALOGW("dropping %d events on the floor", count);
                    countFlushCompleteEventsLocked(scratch, count);
return size;
                }
                ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
                         flushCompleteEvent.meta_data.sensor);
                flushInfo.mPendingFlushEventsToSend--;
            }
        }
    }

// Early return if there are no events for this connection.
    if (count == 0) {
return status_t(NO_ERROR);
    }
//把数据发送出去
    // NOTE: ASensorEvent and sensors_event_t are the same type
    ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
}

 

在前面SensorEventQueue通过fd与Reciver绑定,上面的SensorEventQueue.write之后便触发了Reciver的回调函数handleEvent()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

 

virtual int handleEvent(int fd, int events, void* data) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
    ssize_t n;
    ASensorEvent buffer[16];
while ((n = q->read(buffer, 16)) > 0) {
for (int i=0 ; i<n ; i++) {

if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
// step-counter returns a uint64, but the java API only deals with floats
                float value = float(buffer[i].u64.step_counter);
                env->SetFloatArrayRegion(mScratch, 0, 1, &value);
            } else {
                env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
            }

if (buffer[i].type == SENSOR_TYPE_META_DATA) {
// This is a flush complete sensor event. Call dispatchFlushCompleteEvent
                // method.
                env->CallVoidMethod(mReceiverObject,
                                    gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
                                    buffer[i].meta_data.sensor);
            } else {
//调用了SystemSensorManager.ava的dispatchSensorEvent函数,
                //dispatchSensorEvent又调用了Listener.onSensorChanged把数据传到App层
                env->CallVoidMethod(mReceiverObject,
                                    gBaseEventQueueClassInfo.dispatchSensorEvent,
                                    buffer[i].sensor,
                                    mScratch,
                                    buffer[i].vector.status,
                                    buffer[i].timestamp);
            }
        }
    } 
}

 

探秘SensorHAL /************************************************************/ 本文仅供学习交流,如用于商业用途,请征得作者同意。 欢迎转载,转载请注明出处。 http://blog.csdn.net/airk000/article/details/8659453 E-mail: airk908@gmail.com /************ 阅读详情

相关推荐

Android 11---WMS之横竖屏切换流程详解之一

本文以Activity.setRequestedOrientation为入口梳理下横竖屏切换的详细流程。 代码均是基于最新的11.0版本。 第一篇主要讲了横竖屏切换时的准备操作: 更新方向,执行冻屏,截图显示以及计算更新基于新的方向的DisplayInfo和Configuration。 第二篇主要讲下如何将更新后的Configuration通知到树形的窗口结构以及应用中。 第三篇主要讲下解冻的流程以及横竖屏旋转动画的流程。 场景:假设此时手机处于横屏90度状态,当前Activity处...

肥鸟21号的博客 6891

sensor----HAL分析

sensor----framework(一)的后面,我们跟进到了mSensorDevice->activate ,下面我们就来具体看看这个怎么样链接到HAL,DRIVER里面去的。如何使能一个SENOSR的。 step 1: \frameworks\native\services\sensorservice\SensorDevice.cpp   SensorDevice::SensorD

liyanfei123456的博客 1365

MT6236平台HI253摄像头驱动源码分析与调试实践

摄像头传感器(sensor)驱动是嵌入式系统中连接图像传感器与主控芯片的关键适配层,它负责完成I2C通信、GPIO控制、上下电时序协调等底层操作,其质量直接影响预览和拍照的稳定性。在MTK功能机平台中,MAUI软件栈基于Nucleus RTOS运行,sensor驱动被封装为一组回调函数,供camera hal层在切换状态时调用,这种架构要求开发者具备平台级视野。掌握sensor驱动的移植与调试方法,能快速解决预览黑屏、花屏等常见工程问题,这对于老平台维护及传感器方案更替尤为实用。本文围绕MT6236主控与H

weixin_33922672的博客 509

Android的 google hal层 sensor分析

分析的Android版本为:Android 8.0,Android 8.11.,google-hal层的sensor作为一个server在运行,通过ps |grep sensor可以看到如下进程名字,通过hidl机制与framework的SensorService(的SensorDevice)通信,源码位于android/hardware/interfaces/sensors/1.0/defaul...

goodnight1994的博客 6098

Android计步器应用开发入门:源码解析与实践

随着智能设备的普及,移动健康应用,特别是计步器,成为了人们关注自身活动水平的重要工具。本章将为读者提供一个关于Android计步器应用开发的概览,介绍其发展背景、市场需求、以及开发中的关键技术和开发流程。

weixin_42186015的博客 1045

COLMAP性能优化实战:如何用GPU加速和并行计算让重建速度提升300%

本文详细介绍了如何通过GPU加速、并行计算和参数调优显著提升COLMAP的三维重建效率。从硬件资源分配到计算流程优化,再到大型数据集的分块处理策略,全面解析了将重建速度提升300%以上的实用技巧,特别适合处理无人机航拍和室内扫描等大规模三维重建项目。

weixin_29098391的博客 202

Qcom_Sensor(三)--- 之 Android Sensor HAL层初始化流程

Qcom_Sensor(三)--- 之 Android Sensor HAL层初始化流程一、Sensor HAL打开/初始化过程二、sensor1 API详解2.1 、SensorsContext() --> sensor1_init() 调用流程三、获取sensor列表getSensorList四、addSensor具体过程五、添加其他的sensor六、updateSensorList更新...

|~~~热爱生活、努力学习的小伙汁~~~| 4090

FPGA实战笔记——SDRAM乒乓缓存与OV5640视频采集(VGA显示优化篇)

本文详细介绍了基于FPGA的SDRAM乒乓缓存技术在OV5640视频采集与VGA显示优化中的应用。通过设计多时钟域同步和双Bank乒乓缓存策略,有效解决了摄像头30fps输出与VGA 60fps显示之间的帧率不匹配问题,实现了720P高清视频的流畅稳定显示,为实时图像处理系统提供了可靠的硬件解决方案。

ss78901的博客 882

Android Sensor架构和原理分析

https://blog.csdn.net/u010164190/article/details/51908477 本文主要描述了在android2.3平台G-sensor相关软硬件的体系架构和实现原理,按照Applications、Framework、HAL、Driver和Hardware五大层次分别介绍。 1.系统架构 (Architecture) 1.1 Android体系架构图 ...

haigand的专栏 5186

ansys workbench 静力结构分析 高阶教程

ansys workbench 静力结构分析 高阶教程 目录ansys workbench 静力结构分析 高阶教程新建工程模型导入设置材料模型简化: 主要内容: 材料设置、模型简化、网格细化、约束分析、接触设置、求解设置、报错处理、结果分析 基础教程: ansys workbench 静力结构分析 基础操作流程(入门) ansys版本: 19.0(16.0及以上均可) 参考资料: 推荐教学视频《有限元分析 张晔》(超详细 ???? )、ansys workbench 超级学习手册(查阅用) 说明:一些基

weixin_43434624的博客 5万+

保姆级教程:用MATLAB搞定运动模糊图片修复(附完整代码与避坑指南)

本文提供了一份详细的MATLAB运动模糊图片修复教程,涵盖盲复原、图像复原等核心技术。通过傅里叶变换和Radon变换分析模糊参数,对比逆滤波、维纳滤波和Lucy-Richardson算法效果,并附完整代码与避坑指南,帮助用户实现专业级图像处理。

weixin_26765363的博客 228

android g-sensor 驱动源码分析

环境:MTK Android4.4 硬件:MT8127 MMA8653 日期:2015年6月19日 在MTK的Gsensor构架中有一个auto detect的功能,只要作用是可以添加多个GSensor驱动,然后会自动找到与硬件匹配的Gsensor驱动,这个功能是用hwmsen驱动模块来完成的。 先来看看驱动里是如何使用auto detect的 1 2 3 ...

shell812的专栏 4727

Zephyr 开发必备技能:一文搞懂 west manifest

本文深入解析Zephyr项目的westmanifest工具与Manifest文件管理,从基础概念到高级应用。文章首先介绍westmanifest作为Zephyr模块化架构的核心工具,负责管理west.yml文件中的模块信息、Git地址及版本控制。随后详细讲解Manifest文件的基本结构、字段含义,以及westmanifest子命令的使用方法,包括查看内容、冻结版本、验证文件等操作。文章还探讨了Manifest的导入继承机制和在团队协作中的版本管理策略,并给出常见问题排查技巧。最后强调Manifest文件作

hemoparrot的专栏 1256

Android 知识体系

Android归档前言 前言 感谢: Gityuan:Android系统架构开篇 刘望舒的博客:知识体系

许浑的博客 8197

深入解析CAN总线BusOff故障的检测与恢复机制

本文深入解析了CAN总线BusOff故障的检测与恢复机制。BusOff是CAN节点因发送错误过多而被强制离线的一种严重状态。文章详细阐述了其触发原理,即发送错误计数器(TEC)超过255,并重点介绍了通过软件实现的快慢恢复机制,以增强网络在异常情况下的稳定性和韧性。

weixin_29158047的博客 525

保姆级教程:在树莓派5B上用AI Kit跑YOLOv8,实测134fps的完整配置流程

本文提供了一份详细的树莓派5B搭配AI Kit部署YOLOv8的教程,从硬件组装到模型转换、优化和部署,最终实现134FPS的高帧率推理性能。通过Hailo-8L AI加速模块和HEF模型转换,这套方案为边缘AI计算提供了强大支持,适用于智能监控、无人机视觉导航等应用场景。

weixin_28725407的博客 448

Camera学习1(TODO)

可以,而且我反而建议你。如果你的最终目标还是之前说的。

fanged的专栏 219

自定义模型训练——打造专属OpenClaw模型(2026AI版)

本文介绍了OpenClaw自定义模型训练的核心流程,包括框架选择(PyTorch、TensorFlow、HuggingFace和原生OpenClaw框架)、训练环境搭建脚本、以及数据收集系统的设计。数据收集器支持从数据库、API、文件和网络等多种来源获取训练数据,并提供灵活的过滤机制确保数据质量。通过这套系统,开发者可以高效准备训练数据,为后续模型训练打下坚实基础。

博客 876

Android 之永乐大典

如下编译脚本逻辑,这里通过DISABLE_DEXPREORT_CHECK宏控来失能是否进行DEXPREOPT优化检测,如果为true则失能,默认需要进行优化检测,通过过滤所有PRODUCT_PACKAGES安装的应用,即先过滤ALL_DEFAULT_INSTALLED_MODULES宏控指定列表里面的应用,然后在过滤DEXPREOPT_SYSTEMSERVER_ARTIFACTS列表中指定的需要dexpreort优化的系统jar。Android DexOpt前世今生:参考。

qq_27672101的博客 1899

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

一条命令装齐 VC++ 运行库:VisualCppRedist AIO 完整安装手册

VisualCppRedist AIO(vcredist)是开源一键安装器:把 2005–2022 全部 Visual C++ 运行库压进一个 exe,一条命令完成安装、更新、修复与移除。适合处理 dll 缺失报错的普通用户,也适合做运行库批量部署的运维。 下文是 vcredist 一键安装的完整流程——从单机缺文件到整机房的 VC++ 运行库批量部署,所有参数均按仓库文档核实,可直接照抄。

gitblog_00982的博客 366

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

wifi收集

Broadcom softmac WLAN 驱动解析(1) Broadcom softmac WLAN 驱动解析(2)

温柔一刀 2544

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

HAL

功能:   生成lights.xxx.so文件   构造所有硬件支持的light设备(主要在于set_light不同)供上层调用 源码分析: LIGHTS_HARDWARE_MODULE_ID是light HAL的唯一标示,JNI通过该ID load对应的so文件。 主要关注lights_module_methods struct hw_module_t HAL_MODULE_IN...

weixin_30726161的博客 87

android sensor 驱动,Android Sensor Driver(一)——概述

Android传感器Android系统支持加速度传感器(accelerometer)、陀螺仪(gyroscope)、环境光照传感器(light)、磁力传感器(magnetic field)、方向传感器(orientation)、压力传感器(pressure)、距离传感器(proximity)和温度传感器(temperature)八种物理传感器和三种虚拟传感器重力加速度传感器GRAVITY、线性加速...

weixin_31682031的博客 855

Android Native到HAL源码剖析,以sensor为例

Google为了保护硬件厂商的信息,在Android中添加了一层,它就是大名鼎鼎的HAL层。 在看HAL的编写方法的过程中,会发现整个模块貌似没有一个入口。一般说来模块都要有个入口,比如应用程序的main函数,可以被加载器进行加载执行,dll文件有dllmain,而对于我们自己写的动态链接库,我们可以对库中导出的任何符号进行调用。 那么问题来了,Android中的HAL是具有通用性的,需要上层...

接私活,免费帮家长照顾20-25岁的好看的女孩子。 6538

Android sensor 代码框架

Android sensor整体框架 Java层到sensor service Sensor Service层到 Sensor HAL层 SEE层到 Sensor HAL 参考: https://blog.csdn.net/goodnight1994/article/details/97503586 https://source.android.com/devic...

u011279649的专栏 2714

Android sensor hal 详解

<!-- @page {margin:0.79in} p {margin-bottom:0.08in} -->                                               Android sensor hal 详解 这里面有关于hal、JNI的详细讲解 代码的路径是在:ics_ventana/frameworks/ba

sunweizhong1024的专栏 7963
上一篇: 编写Android.mk中的LOCAL_SRC_FILES的终极技巧
下一篇: android g-sensor 驱动源码分析
shell812
博客等级 码龄18年 202粉丝 28原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值