Android系统内置对传感器有很多,它们分别是:加速度传感器gsensor(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。
Android实现传感器系统代码位置在
framework层: frameworks\base\core\java\android\hardware\目录下
Sensor.java
SensorEventListener.java
SensorListener.java
SensorManager.java
jni :frameworks\base\core\jni
android_hardware_SensorManager.cpp
hal层,这个每个平台的代码位置可能不一样,我现在分析4.4MTK的
mediatek\hardware\sensor
Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h
对传感器类型的定义:
传感器模块的定义结构体如下:
该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表。
对任意一个sensor设备 都会有一个 sensor_t 结构体,其定义如下:
struct sensor_t {
/* name of this sensors */
const char* name;
/* vendor of the hardware part */
const char* vendor;
/* version of the hardware part + driver. The value of this field
* must increase when the driver is updated in a way that changes the
* output of this sensor. This is important for fused sensors when the
* fusion algorithm is updated.
*/
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;
/* this sensor's type. */
int type;
/* 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;
/* 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;
/* reserved fields, must be zero */
void* reserved[8];
};
下面来分析hal流程:
加载JNI时根据模块会找到sensor.c
由上面可以看出来open_sensors是整个加载流程入口
函数操作集合赋值,看到new了一个sensors_poll_context_t类,看看到底这里都做了什么
struct sensors_poll_context_t {
struct sensors_poll_device_t device; // must be first
sensors_poll_context_t();
~sensors_poll_context_t();
int activate(int handle, int enabled);
int setDelay(int handle, int64_t ns);
int pollEvents(sensors_event_t* data, int count);
private:
enum {
hwmsen = 0,
accel,
magnetic,
//gyro,
//light,
//proximity,
//pressure,
numSensorDrivers,
numFds,
};
int handleToDriver(int handle) const {
switch (handle) {
case ID_ACCELEROMETER:
return accel;
case ID_MAGNETIC:
case ID_ORIENTATION:
return magnetic;
case ID_PROXIMITY:
//return proximity;
case ID_LIGHT:
//return light;
case ID_GYROSCOPE:
//return gyro;
case ID_PRESSURE:
break;
//return pressure;
}
return -EINVAL;
}
static const size_t wake = numFds - 1;
static const char WAKE_MESSAGE = 'W';
struct pollfd mPollFds[numFds];
int mWritePipeFd;
SensorBase* mSensors[numSensorDrivers];
};
构造函数
重点来看pollEvents函数
poll是真正实现查询事件
int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
int nbEvents = 0;
int n = 0;
//ALOGE("pollEvents count =%d",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())) {
int nb = sensor->readEvents(data, count);
if (nb < count) {
// no more data for this sensor
mPollFds[i].revents = 0;
}
//if(nb < 0||nb > count)
// ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug
count -= nb;
nbEvents += nb;
data += nb;
//if(nb < 0||nb > count)
// ALOGE("pollEvents count error nb:%d, count:%d, nbEvents:%d", nb, count, nbEvents);//for sensor NE debug
}
}
if (count) {
// we still have some room, so try to see if we can get
// some events immediately or just wait if we don't have
// anything to return
n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
if (n<0) {
ALOGE("poll() failed (%s)", strerror(errno));
return -errno;
}
if (mPollFds[wake].revents & POLLIN) {
char msg;
int result = read(mPollFds[wake].fd, &msg, 1);
ALOGE_IF(result<0, "error reading from wake pipe (%s)", strerror(errno));
ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg));
mPollFds[wake].revents = 0;
}
}
// if we have events and space, go read them
} while (n && count);
return nbEvents;
}