分析背景:
Android4.1.2(Based on CyanogenMod 10)
DASH(https://github.com/sonyxperiadev/DASH)
1.接口头文件sensors.h(hardware/libhardware/include/sensors.h)
刚一打开就看到SENSOR HAL的ID 为"SENSORS_HARDWARE_MODULE_ID"。
- /**
- * Handles must be higher than SENSORS_HANDLE_BASE and must be unique.
- * A Handle identifies a given sensors. The handle is used to activate
- * and/or deactivate sensors.
- * In this version of the API there can only be 256 handles.
- */
- #define SENSORS_HANDLE_BASE 0
- #define SENSORS_HANDLE_BITS 8
- #define SENSORS_HANDLE_COUNT (1<<SENSORS_HANDLE_BITS)
- /* 8位能够支持256个handle */
- /**
- * Sensor types
- */
- #define SENSOR_TYPE_ACCELEROMETER 1 //加速度传感器
- #define SENSOR_TYPE_MAGNETIC_FIELD 2 //磁力传感器
- #define SENSOR_TYPE_ORIENTATION 3 //方向传感器
- #define SENSOR_TYPE_GYROSCOPE 4 //陀螺仪
- #define SENSOR_TYPE_LIGHT 5 //亮度传感器
- #define SENSOR_TYPE_PRESSURE 6 //压力传感器
- #define SENSOR_TYPE_TEMPERATURE 7 // deprecated 温度传感器,以后的版本中将看不到任何身影
- #define SENSOR_TYPE_PROXIMITY 8 //距离传感器
- #define SENSOR_TYPE_GRAVITY 9 //重力传感器
- #define SENSOR_TYPE_LINEAR_ACCELERATION 10 //速度传感器
- #define SENSOR_TYPE_ROTATION_VECTOR 11 //旋转矢量传感器
- #define SENSOR_TYPE_RELATIVE_HUMIDITY 12 //相对湿度传感器
- #define SENSOR_TYPE_AMBIENT_TEMPERATURE 13 //环境温度传感器
支持的传感器还很多,但是 一般设备并不会用到这么多传感器,也就是加速度传感器、重力传感器、方向传感器、距离传感器、光线传感器这些,陀螺仪都很少见。
- /**
- * Definition of the axis
- * ----------------------
- *
- * This API is relative to the screen of the device in its default orientation,
- * that is, if the device can be used in portrait or landscape, this API
- * is only relative to the NATURAL orientation of the screen. In other words,
- * the axis are not swapped when the device's screen orientation changes.
- * Higher level services /may/ perform this transformation.
- *
- * x<0 x>0
- * ^
- * |
- * +-----------+--> y>0
- * | |
- * | |
- * | 设备 |
- * | | / z<0
- * | 面朝天空 | /
- * | | /
- * O-----------+/
- * |[] [ ] []/
- * +----------/+ y<0
- * /
- * /
- * |/ z>0 (toward the sky)
- *
- * O: Origin (x=0,y=0,z=0)
还用有趣的符号图形形象的描述了“轴”的概念。然后就是一坨坨的传感器知识,blablabla......
定义了几个结构体:
1) sensors_vec_t 对单个传感器的泛用性封装,包含坐标、角度、状态等信息;
2) sensors_event_t 对传感器细致的数据再封装,包含版本号、传感器类型、数据、加速度、磁力、角度、重力等等等等的信息;
3) sensor_t 对应每个传感器,是都会有的数据,包括传感器名称、版本、handle句柄、类型、最大范围、解析度、耗能、最小延迟等信息;
4) sensors_module_t 对hw_module_t的扩展,不仅有common为hw_module_t,还定义了一个函数get_sensors_list用来获取所支持的传感器,返回值为传感器总数;
5) sensors_poll_device_t 每个传感器所私有的数据操作,包括(反)激活、设置延时、提取数据等动作。
最后定义了两个API函数用来打开/关闭一个传感器。
- static inline int sensors_open(const struct hw_module_t* module,
- struct sensors_poll_device_t** device) {
- return module->methods->open(module,
- SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
- }
- static inline int sensors_close(struct sensors_poll_device_t* device) {
- return device->common.close(&device->common);
- }
2. 服务开启之路(1)
sensor服务由system_server开启:
frameworks/base/cmds/system_server/system_init.cpp
- extern "C" status_t system_init()
- {
- ALOGI("Entered system_init()");
- sp<ProcessState> proc(ProcessState::self());
- sp<IServiceManager> sm = defaultServiceManager();
- ALOGI("ServiceManager: %p\n", sm.get());
- ...
- }
- property_get("system_init.startsensorservice", propBuf, "1");
- if (strcmp(propBuf, "1") == 0) {
- // Start the sensor service
- SensorService::instantiate();
- }
- ...
- }
- void SensorService::onFirstRef()
- {
- ALOGD("nuSensorService starting...");
- SensorDevice& dev(SensorDevice::getInstance());
- SensorDevice::SensorDevice()
- : mSensorDevice(0),
- mSensorModule(0)
- {
- status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
- (hw_module_t const**)&mSensorModule);
- ALOGE_IF(err, "couldn't load %s module (%s)",
- SENSORS_HARDWARE_MODULE_ID, strerror(-err));
- if (mSensorModule) {
- err = sensors_open(&mSensorModule->common, &mSensorDevice);
- ALOGE_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);
- 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);
- }
- }
- }
- }
这段负责打开HAL,取得需要的数据及handle,对应的部分在HAL的代码中,见DASH/sensors_module.c
- struct sensors_module_t HAL_MODULE_INFO_SYM = {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: SENSORS_HARDWARE_MODULE_ID,
- name : "dash",
- author : "oskar.andero@sonymobile.com",
- methods: &sensors_module_methods,
- },
- get_sensors_list: sensors_list_get
- };
ID对上了,即可以成功打开,mSensorModule变得有效了。
然后SensorDevice.cpp调用API sensors_open,这个函数在接口头文件中有定义:
- static inline int sensors_open(const struct hw_module_t* module,
- struct sensors_poll_device_t** device) {
- return module->methods->open(module,
- SENSORS_HARDWARE_POLL, (struct hw_device_t**)device);
- }
是开调用HAL的open方法:
- static int sensors_module_open(const struct hw_module_t* module, const char* id, struct hw_device_t** device)
- {
- struct sensors_poll_device_t *dev;
- if (strcmp(id, SENSORS_HARDWARE_POLL))
- return 0;
- dev = malloc(sizeof(*dev));
- if (!dev)
- return -1;
- memset(dev, 0, sizeof(*dev));
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
- dev->common.module = (struct hw_module_t*)module;
- dev->common.close = sensors_module_close;
- dev->activate = sensors_module_activate;
- dev->setDelay = sensors_module_set_delay;
- dev->poll = sensors_module_poll;
- *device = (struct hw_device_t*) dev;
- sensors_config_read(NULL);
- sensors_fifo_init();
- sensors_list_foreach_api(sensors_init_iterator, NULL);
- return 0;
- }
- struct hw_module_methods_t sensors_module_methods = {
- open: sensors_module_open
- };
实际调用到了sensors_module_open,此函数返回0代表成功,-1代表打开失败,主要工作是组装device,最终将句柄交给mSensorDevice,即:
- mSensorDevice->common.tag = HARDWARE_DEVICE_TAG;
- mSensorDevice->common.version = 0;
- mSensorDevice->common.module = (struct hw_module_t*)module;
- mSensorDevice->common.close = sensors_module_close;
- mSensorDevice->activate = sensors_module_activate;
- mSensorDevice->setDelay = sensors_module_set_delay;
- mSensorDevice->poll = sensors_module_poll;
之前在说明接口头文件时,说明了,对于传感器的数据操作有三个重要函数就是avtivate, setDelay, poll。记住这几个函数,稍后做分析。
在mSensorDevice成功被组装后,调用sensors_module_t自创的另一重要接口:get_sensors_list。瞧一瞧此函数在本实例中的具体实现(DASH/sensors_list.c):
- static struct sensor_t sensors[DASH_MAX_SENSORS];
- static struct sensor_api_t* sensor_apis[DASH_MAX_SENSORS];
- static int number_of_sensors = 0;
- int sensors_list_get(struct sensors_module_t* module, struct sensor_t const** plist)
- {
- *plist = sensors;
- return number_of_sensors;
- }
此函数完成两个工作,一将传感器列表赋给指针plist,二返回传感器数量。这里sensors列表和number_of_sensors是如何运作的:
- int sensors_list_register(struct sensor_t* sensor, struct sensor_api_t* api)
- {
- if (!sensor || !api)
- return -1;
- if (number_of_sensors > DASH_MAX_SENSORS-1)
- return -1;
- sensor_apis[number_of_sensors] = api;
- /* We have to copy due to sensor API */
- memcpy(&sensors[number_of_sensors++], sensor, sizeof(*sensor));
- return 0;
- }
每个传感器都会调用sensors_list_register将自己注册进sensors列表中,并且会将自己的API也注册进sensors_apis列表中,来一个例子吧(DASH/sensors/bma150_input.c):
- struct sensor_desc {
- struct sensors_select_t select_worker;
- struct sensor_t sensor;
- struct sensor_api_t api;
- int input_fd;
- float current_data[3];
- char *rate_path;
- /* config options */
- int axis_x;
- int axis_y;
- int axis_z;
- int neg_x;
- int neg_y;
- int neg_z;
- int64_t delay_requests[MAX_CLIENTS];
- };
- static struct sensor_desc bma150_input = {
- .sensor = {
- name: "BMA150 accelerometer",
- vendor: "Bosch Sensortec GmbH",
- version: sizeof(sensors_event_t),
- handle: SENSOR_ACCELEROMETER_HANDLE,
- type: SENSOR_TYPE_ACCELEROMETER,
- maxRange: 9.81,
- resolution: 20,
- power: 0.13,
- minDelay: 5000
- },
- .api = {
- init: bma150_input_init,
- activate: bma150_input_activate,
- set_delay: bma150_input_fw_delay,
- close: bma150_input_close
- },
- .input_fd = -1,
- .axis_x = 0,
- .axis_y = 1,
- .axis_z = 2,
- .neg_x = 0,
- .neg_y = 0,
- .neg_z = 0
- };
以上是BMA150注册了属于自己的初始化、激活、延迟、关闭等操作。
每次注册完成后自会对number_of_sensors进行+1操作。这样所有的传感器注册完成后,就会形成两个列表和一个传感器总数。sensors_list_get也就理解了。
在获取到总数后,会根据总数进行循环遍历,挨个激活传感器。
- for (size_t i=0 ; i<size_t(count) ; i++) {
- mActivationCount.add(list[i].handle, model);
- mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
- }
OK,这下,引出了三大数据处理函数之一:activate。
sensors_module.c
- /* mSensorDevice->activate = sensors_module_activate; */
- static int sensors_module_activate(struct sensors_poll_device_t *dev,
- int handle, int enabled)
- {
- struct sensor_api_t* api = sensors_list_get_api_from_handle(handle);
- if (!api) {
- ALOGE("%s: unable to find handle!", __func__);
- return -1;
- }
- if (api->activate(api, enabled) < 0)
- return -1;
- return 0;
- }
sensors_list.c
- struct sensor_api_t* sensors_list_get_api_from_handle(int handle)
- {
- int i;
- for (i = 0; i < number_of_sensors; i++)
- if (sensors[i].handle == handle)
- return sensor_apis[i];
- return NULL;
- }
比如BMA150的handle就是SENSOR_ACCELEROMETER_HANDLE,通过简单的匹配后,就能找到对应的sensors_api[x],然后执行active也就是bma150_input_activate函数,有兴趣就简单看一下代码,大体意思就是打开驱动获取句柄,然后组装给相关参数。
至此SensorDevice的大体工作也就完成了,总结就是成功获取HAL后,对每个传感器执行activate操作。
3.服务开启之路(2)
之所分(1)(2)是觉得SensorDevice部分可以单独成一部分,毕竟多数是在跟HAL在交互,这部分将分析完服务部分。
回头看SensorService::onFirstRef()
- void SensorService::onFirstRef()
- {
- ALOGD("nuSensorService starting...");
- SensorDevice& dev(SensorDevice::getInstance());
- if (dev.initCheck() == NO_ERROR) {
- /**********************************
- 检测SensorDevice执行是否成功,所获取的数据是否有效。
- >status_t SensorDevice::initCheck() const {
- return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
- }
- **********************************/
- sensor_t const* list;
- ssize_t count = dev.getSensorList(&list);
- /* 执行与(1)中sensors_list_get一样的工作 */
- 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++) {
- registerSensor( new HardwareSensor(list[i]) );
- switch (list[i].type) {
- case SENSOR_TYPE_ORIENTATION:
- orientationIndex = i;
- break;
- case SENSOR_TYPE_GYROSCOPE:
- hasGyro = true;
- break;
- case SENSOR_TYPE_GRAVITY:
- case SENSOR_TYPE_LINEAR_ACCELERATION:
- case SENSOR_TYPE_ROTATION_VECTOR:
- virtualSensorsNeeds &= ~(1<<list[i].type);
- break;
- }
- }
- /* 遍历查看SENSOR HAL都支持哪些类型的传感器 */
- // it's safe to instantiate the SensorFusion object here
- // (it wants to be instantiated after h/w sensors have been
- // registered)
- const SensorFusion& fusion(SensorFusion::getInstance());
- if (hasGyro) {
- // Always instantiate Android's virtual sensors. Since they are
- // instantiated behind sensors from the HAL, they won't
- // interfere with applications, unless they looks specifically
- // for them (by name).
- registerVirtualSensor( new RotationVectorSensor() );
- registerVirtualSensor( new GravitySensor(list, count) );
- registerVirtualSensor( new LinearAccelerationSensor(list, count) );
- // these are optional
- registerVirtualSensor( new OrientationSensor() );
- registerVirtualSensor( new CorrectedGyroSensor(list, count) );
- // virtual debugging sensors...
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.sensors", value, "0");
- if (atoi(value)) {
- registerVirtualSensor( new GyroDriftSensor() );
- }
- } else if (orientationIndex != -1) {
- // If we don't have a gyro but have a orientation sensor from
- // elsewhere, we can compute rotation vector from that.
- // (Google Maps expects rotation vector sensor to exist.)
- registerVirtualSensor( &RotationVectorSensor2::getInstance() );
- }
- // build the sensor list returned to users
- mUserSensorList = mSensorList;
- if (hasGyro &&
- (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
- // if we have the fancy sensor fusion, and it's not provided by the
- // HAL, use our own (fused) orientation sensor by removing the
- // HAL supplied one form the user list.
- if (orientationIndex >= 0) {
- mUserSensorList.removeItemsAt(orientationIndex);
- }
- }
- run("SensorService", PRIORITY_URGENT_DISPLAY);
- mInitCheck = NO_ERROR;
- }
- }
- }
从上面可以看出,如果传感器中有SENSOR_TYPE_GYROSCOPE类型的话,也就是陀螺仪(高端传感器),会定义hasGyro,从而注册多个虚拟传感器,blablabla……
最后会触发一个重要动作:run。
回头查看SensorService类的定义:
- class SensorService :
- public BinderService<SensorService>,
- public BnSensorServer,
- protected Thread
发现SensorService是继承了Thread的。
那么run的工作实际是启动了线程,threadLoop:
- bool SensorService::threadLoop()
- {
- ALOGD("nuSensorService thread starting...");
- const size_t numEventMax = 16;
- const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
- sensors_event_t buffer[minBufferSize];
- sensors_event_t scratch[minBufferSize];
- SensorDevice& device(SensorDevice::getInstance());
- const size_t vcount = mVirtualSensorList.size();
- ssize_t count;
- do {
- count = device.poll(buffer, numEventMax);
- if (count<0) {
- ALOGE("sensor poll failed (%s)", strerror(-count));
- break;
- }
- ...
- }
发现这个线程会一直执行poll操作,这个操作是什么呢?还记得“服务开启之路(1)”中提到的吗?
- mSensorDevice->poll = sensors_module_poll;
是在HAL中的函数,最终指向sensors_module_poll ( DASH/sensors_module.c )
- static int sensors_module_poll(struct sensors_poll_device_t *dev,
- sensors_event_t* data, int count)
- {
- int ret;
- while ((ret = sensors_fifo_get_all(data, count)) == 0)
- ;
- return ret;
- }
( DASH/sensors_fifo.c )
- void sensors_fifo_put(sensors_event_t *data)
- {
- pthread_mutex_lock(&sensors_fifo.mutex);
- if (sensors_fifo.fifo_i < FIFO_LEN)
- sensors_fifo.fifo[sensors_fifo.fifo_i++] = *data;
- pthread_cond_broadcast(&sensors_fifo.data_cond);
- pthread_mutex_unlock(&sensors_fifo.mutex);
- }
- int sensors_fifo_get_all(sensors_event_t *data, int len)
- {
- int i;
- /* This function deliberately drops all packets above len. */
- pthread_mutex_lock(&sensors_fifo.mutex);
- pthread_cond_wait(&sensors_fifo.data_cond, &sensors_fifo.mutex);
- for (i = 0; (i < sensors_fifo.fifo_i) && (i < len); i++)
- data[i] = sensors_fifo.fifo[i];
- sensors_fifo.fifo_i = 0;
- pthread_mutex_unlock(&sensors_fifo.mutex);
- return i;
- }
上边的函数用到了线程等待,有兴趣的可以去百度,很好理解,就是两个线程等待一个变量data_cond,sensors_fifo_put在放置完data后会释放掉data_cond,而sensors_fifo_get_all在data_cond释放之前会一直进行等待。
继续向前跟踪sensors_fifo_put ( DASH/sensors/bma150_input.c ):
- static void *bma150_input_read(void *arg)
- {
- struct sensor_api_t *s = arg;
- struct sensor_desc *d = container_of(s, struct sensor_desc, api);
- struct input_event event;
- int fd = d->select_worker.get_fd(&d->select_worker);
- sensors_event_t data;
- memset(&data, 0, sizeof(data));
- while (read(fd, &event, sizeof(event)) > 0) {
- switch (event.type) {
- case EV_ABS:
- switch (event.code) {
- case ABS_X:
- d->current_data[0] = ev2grav(event.value);
- break;
- case ABS_Y:
- d->current_data[1] = ev2grav(event.value);
- break;
- case ABS_Z:
- d->current_data[2] = ev2grav(event.value);
- break;
- case ABS_MISC:
- default:
- break;
- }
- break;
- case EV_SYN:
- data.acceleration.x = (d->neg_x ? -d->current_data[d->axis_x] :
- d->current_data[d->axis_x]);
- data.acceleration.y = (d->neg_y ? -d->current_data[d->axis_y] :
- d->current_data[d->axis_y]);
- data.acceleration.z = (d->neg_z ? -d->current_data[d->axis_z] :
- d->current_data[d->axis_z]);
- data.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
- data.sensor = bma150_input.sensor.handle;
- data.type = bma150_input.sensor.type;
- data.version = bma150_input.sensor.version;
- data.timestamp = get_current_nano_time();
- sensors_fifo_put(&data);
- goto exit;
- default:
- goto exit;
- }
- }
- exit:
- return NULL;
- }
上述函数很好理解,首先取得此传感器的内核驱动句柄,然后等待此句柄输出信息,当取得信息后,对信息进行解析与再封装,最终写入到data中。那么bma150_input_read又是谁来调用呢?答案在此传感器的初始化过程中:
- static int bma150_input_init(struct sensor_api_t *s)
- {
- struct sensor_desc *d = container_of(s, struct sensor_desc, api);
- int fd;
- bma150_input_read_config(d);
- /* check for availablity */
- fd = open_input_dev_by_name(BMA150_INPUT_NAME, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- ALOGE("%s: unable to find %s input device!\n", __func__,
- BMA150_INPUT_NAME);
- return -1;
- }
- d->rate_path = bma150_get_rate_path(fd);
- close(fd);
- sensors_select_init(&d->select_worker, bma150_input_read, s, -1);
- return 0;
- }
下面一次解决,问题1:
- static struct sensor_desc bma150_input = {
- ...
- .api = {
- init: bma150_input_init,
- activate: bma150_input_activate,
- set_delay: bma150_input_fw_delay,
- close: bma150_input_close
- },
- ...
- };
( DASH/sensors_module.c )
- static int sensors_module_open(const struct hw_module_t* module, const char* id, struct hw_device_t** device)
- {
- ...
- sensors_list_foreach_api(sensors_init_iterator, NULL);
- return 0;
- }
- static int sensors_init_iterator(struct sensor_api_t* api, void *arg)
- {
- return api->init(api);
- }
( DASH/sensors_list.c )
- void sensors_list_foreach_api(int (*f)(struct sensor_api_t* api, void* arg),
- void *arg)
- {
- int i;
- for (i = 0; i < number_of_sensors; i++)
- if (f(sensor_apis[i], arg) != SENSOR_OK) {
- sensors_list_deregister(sensor_apis[i]);
- /* need to revisit this position after deregister */
- --i;
- }
- }
问题2:
( DASH/sensors_select.c )
- void sensors_select_init(struct sensors_select_t* s,
- void* (*select_func)(void *arg), void* arg, int fd)
- {
- s->suspend = sensors_select_suspend;
- s->resume = sensors_select_resume;
- s->destroy = sensors_select_destroy;
- s->set_delay = sensors_select_set_delay;
- s->set_fd = sensors_select_set_fd;
- s->get_fd = sensors_select_get_fd;
- s->select_callback = select_func;
- s->arg = arg;
- s->fd = fd;
- s->delay = 0;
- if (pipe(s->ctl_fds) < 0)
- ALOGE("%s: pipe failed: %s", __func__, strerror(errno));
- sensors_worker_init(&s->worker, sensors_select_callback, s);
- s->worker.set_delay(&s->worker, 0);
- pthread_mutex_init(&s->fd_mutex, NULL);
- }
bma150_init_read为该函数的第二个参数,即select_func, 组装给了s->select_callback。送去sensors_worker_init函数( DASH/sensors_worker.c ):
- void sensors_worker_init(struct sensors_worker_t* worker,
- void* (*work_func)(void *arg), void* arg)
- {
- worker->mode = SENSOR_SLEEP;
- worker->poll_callback = work_func;
- worker->suspend = sensors_worker_suspend;
- worker->resume = sensors_worker_resume;
- worker->destroy = sensors_worker_destroy;
- worker->set_delay = sensors_worker_set_delay;
- worker->delay_ns = 200000000L;
- worker->arg = arg;
- pthread_mutex_init (&worker->mode_mutex, NULL);
- pthread_cond_init (&worker->suspend_cond, NULL);
- pthread_create(&worker->worker_thread_id, NULL,
- sensors_worker_internal_worker, (void*) worker);
- }
该函数第二个参数为sensors_select_init所送入的sensors_select_callback, 暂放此处,稍后分析,只记得他化身work_func组装给了worker->poll_callback, 最终被当作参数送入新开启的线程sensors_worker_internal_worker中:
- static void *sensors_worker_internal_worker(void *arg)
- {
- struct sensors_worker_t* worker = (struct sensors_worker_t*) arg;
- enum sensors_worker_mode mode;
- while (1) {
- pthread_mutex_lock(&worker->mode_mutex);
- mode = worker->mode;
- pthread_mutex_unlock(&worker->mode_mutex);
- switch (mode) {
- case SENSOR_DESTROY:
- goto exit;
- case SENSOR_SLEEP:
- pthread_mutex_lock(&worker->mode_mutex);
- pthread_cond_wait(&worker->suspend_cond, &worker->mode_mutex);
- pthread_mutex_unlock(&worker->mode_mutex);
- break;
- default:
- worker->poll_callback(worker->arg);
- break;
- }
- if (worker->delay_ns)
- sensor_nano_sleep(worker->delay_ns);
- }
- exit:
- return NULL;
- }
这是一个工作线程,用来处理不同模式的不同动作,这些不同的模式由worker->mode来进行控制,同时worker->mode又由互斥锁worker->mode_mutex进行保护来防止读写冲突。此mode实际有三种:
SENSOR_SLEEP
SENSOR_RUNNING
SENSOR_DESTROY
分别对应三个工作函数:
sensors_worker_suspend
sensors_worker_resume
sensors_worker_destroy
这三个工作函数又在sensors_worker_init初始化时分别分配给了:
worker->suspend
worker->resume
worker->destroy
综上, sensors_worker_internal_worker中default即为SENSOR_RUNNING,其他状态暂不说明,先解决了这个RUNNING。在第一次初始化的时候默认给出的是SLEEP状态,则会等待suspend_cond变量,试看谁在使用这个变量。在sensors_worker.c中不难发现,在resume和destroy函数中,当前一状态为SLEEP时,会释放suspend_cond:
- static void sensors_worker_resume(struct sensors_worker_t* worker)
- {
- enum sensors_worker_mode prev_mode;
- pthread_mutex_lock(&worker->mode_mutex);
- prev_mode = worker->mode;
- worker->mode = SENSOR_RUNNING;
- if (prev_mode == SENSOR_SLEEP)
- pthread_cond_broadcast(&worker->suspend_cond);
- pthread_mutex_unlock(&worker->mode_mutex);
- }
- static void sensors_worker_destroy(struct sensors_worker_t* worker)
- {
- enum sensors_worker_mode prev_mode;
- pthread_mutex_lock(&worker->mode_mutex);
- prev_mode = worker->mode;
- worker->mode = SENSOR_DESTROY;
- if (prev_mode == SENSOR_SLEEP)
- pthread_cond_broadcast(&worker->suspend_cond);
- pthread_mutex_unlock(&worker->mode_mutex);
- pthread_join(worker->worker_thread_id, NULL);
- }
两者不同之处在于,resume会让传感器的状态切换到RUNNING,而destroy会使其切换至DESTROY状态,从而导致线程sensors_worker_internal_worker退出,传感器工作停止。问题又来了,初始化的状态是SLEEP,什么时候?谁?来激活这个工作线程呢?问题的答案在bma150_input.c ( DASH/bma150_input.c ):
- static int bma150_input_activate(struct sensor_api_t *s, int enable)
- {
- struct sensor_desc *d = container_of(s, struct sensor_desc, api);
- int fd = d->select_worker.get_fd(&d->select_worker);
- /* suspend/resume will be handled in kernel-space */
- if (enable && (fd < 0)) {
- fd = open_input_dev_by_name(BMA150_INPUT_NAME,
- O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- ALOGE("%s: failed to open input dev %s\n", __func__,
- BMA150_INPUT_NAME);
- return -1;
- }
- d->select_worker.set_fd(&d->select_worker, fd);
- d->select_worker.resume(&d->select_worker);
- } else if (!enable && (fd > 0)) {
- d->select_worker.set_fd(&d->select_worker, -1);
- d->select_worker.suspend(&d->select_worker);
- }
- return 0;
- }
前面只是一代而过activate函数,没有进行分析,回头来看,原来resume与suspend操作就在这里,当未初始化且要求开启时,寻找驱动句柄,并设置句柄,然后执行resume操作,从而使sensors_worker_internal_worker工作线程开启,执行worker->poll_callback函数。在回去之前还是把avtivate看完,除了上边说的开启的情况,就是关闭的情况。当驱动句柄有效,且要求关闭时,设置句柄为-1(无效),并执行suspend操作,使传感器进入SLEEP状态,继续等待suspend_cond变量。
在执行poll_callback时候一层层向回摸吧,worker->arg就等于sensors_worker_init所带入的arg。
worker->poll_back = (work_func);
(work_func) = sensors_select_callback;
( DASH/sensors_select.c )
- static void *sensors_select_callback(void *arg)
- {
- fd_set readfds;
- int ret;
- struct sensors_select_t *s = arg;
- int maxfd;
- LOCK(&s->fd_mutex);
- maxfd = s->ctl_fds[0] > s->fd ? s->ctl_fds[0] : s->fd;
- FD_ZERO(&readfds);
- FD_SET(s->ctl_fds[0], &readfds);
- FD_SET(s->fd, &readfds);
- UNLOCK(&s->fd_mutex);
- ret = select(maxfd + 1, &readfds, NULL, NULL, NULL);
- if (ret < 0) {
- ALOGE("%s: select failed!\n", __func__);
- } else if (ret) {
- if (FD_ISSET(s->ctl_fds[0], &readfds)) {
- read(s->ctl_fds[0], &ret, sizeof(ret));
- } else if (FD_ISSET(s->fd, &readfds)) {
- LOCK(&wrapper_mutex);
- LOCK(&s->fd_mutex);
- if (s->fd >= 0)
- s->select_callback(s->arg);
- UNLOCK(&s->fd_mutex);
- UNLOCK(&wrapper_mutex);
- }
- }
- return NULL;
- }
一层层的设置执行,最终执行到s->select_callback,参数为s->arg。
select_callback = (select_func);
(select_func) = bma150_input_read;
终于执行到了这一步,问题2解决。
总结: 一切的一切始于SensorService的threadLoop,他执行了一个poll操作,从而层层调用到SensorHAL,HAL经过初始化及激活后,开启了一个工作线程。当工作线程处于RUNNING(default)状态时,会无限循环来读取硬件驱动句柄所发出的数据,然后经过解析重构发回到SensorService中。至此,服务成功开启,从驱动中源源不断的获取数据。这个SensorService的threadLoop工作还有很多,大体概括就是对获取到的驱动数据进行分类,处理,最后发送……blablabla,这里边涉及到很多专业知识,也就不便再进行分析。总之SensorHAL的运作流程即使如此。