一、HAL层入口
hal层主要是调用驱动接口,获取sensor驱动中传输上来的数据,提供给上层接口,屏蔽底层的细节,
具有承上启下的作用,将android系统分成了用户空间和内核空间两部分,其中硬件抽象层(HAL)运行在用户
空间,而sensor的hal程序运行在内核空间。
./vendor/mediatek/proprietary/hardware/sensor/sensors.c
static struct hw_module_methods_t sensors_module_methods = {
//获取sensor中的一些实现方法
.open = open_sensors
};
struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
//framework层通过该id寻找hw_module_t中的common成员
.id = SENSORS_HARDWARE_MODULE_ID,
.name = "MTK SENSORS Module",
.author = "Mediatek",
.methods = &sensors_module_methods,
},
//寻找系统支持的sensor类型
.get_sensors_list = sensors__get_sensors_list,
};
//打开所有的sensor, 并返回一个hw_device_t结构
static int open_sensors(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
ALOGD("%s: name: %s! fwq debug\r\n", __func__, name);
return init_nusensors(module, device);
}
上面sensors__get_sensors_list是根据平台有定义支持哪些sensor来获取sensorlist列表:
struct sensor_t sSensorList[] =
{
......
#if defined(CUSTOM_KERNEL_ALSPS) || defined(CUSTOM_KERNEL_PS)
{
.name = PROXIMITY,
.vendor = PROXIMITY_VENDER,
.version = 1,
.handle = ID_PROXIMITY+ID_OFFSET,
.type = SENSOR_TYPE_PROXIMITY,
.maxRange = PROXIMITY_RANGE,//1.00f,
.resolution = PROXIMITY_RESOLUTION,//1.0f,
.power = PROXIMITY_POWER,//0.13f,
.reserved = {}
},
#endif
#if defined(CUSTOM_KERNEL_ALSPS) || defined(CUSTOM_KERNEL_ALS)
{
.name = LIGHT,
.vendor = LIGHT_VENDER,
.version = 1,
.handle = ID_LIGHT+ID_OFFSET,
.type = SENSOR_TYPE_LIGHT,
.maxRange = LIGHT_RANGE,//10240.0f,
.resolution = LIGHT_RESOLUTION,//1.0f,
.power = LIGHT_POWER,//0.13f,
.reserved = {}
},
#endif
};
二、sensor HAL 使能过程
下面继续分析打开sensor的open_sensors相关操作:
init_nusensors首先new了一个sensors_poll_context_t结构,然后设置dev中的成员。
vendor/mediatek/proprietary/hardware/sensor/nusensors.cpp
int init_nusensors(hw_module_t const* module, hw_device_t** device)
{
int status = -EINVAL;
dev = new sensors_poll_context_t();
memset(&dev->device, 0, sizeof(sensors_poll_device_1));
dev->device.common.tag = HARDWARE_DEVICE_TAG;
#if defined(SENSOR_BATCH_SUPPORT) || defined(CUSTOM_KERNEL_SENSORHUB)
dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_1;
#else
dev->device.common.version = SENSORS_DEVICE_API_VERSION_1_0;
#endif
dev->device.common.module = const_cast(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;
}
下面sensors_poll_context_t::sensors_poll_context_t()
sensors_poll_context_t::sensors_poll_context_t()
{
......
memset(&device, 0, sizeof(device));
mSensors[proximity] = new ProximitySensor();
mPollFds[proximity].fd = ((ProximitySensor*)mSensors[proximity])->mdata_fd;
mPollFds[proximity].events = POLLIN;
mPollFds[proximity].revents = 0;
......
int wakeFds[2];
int result = pipe(wakeFds);
if (result < 0) {
ALOGE_IF(result < 0, "error creating wake pipe (%s)", strerror(errno));
mWritePipeFd = -1;
} else {
result = fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
ALOGE_IF(result < 0, "fcntl(wakeFds[0] fail (%s)", strerror(errno));
ALOGE_IF(result < 0, "fcntl(wakeFds[1] fail (%s)", strerror(errno));
mWritePipeFd = wakeFds[1];
}
mPollFds[wake].fd = wakeFds[0];
mPollFds[wake].events = POLLIN;
mPollFds[wake].revents = 0;
}
mSensors是一个SensorBase类型的类,而mPollFds是一个pollfd结构。mSensors保存了各个打开的sensor,mPollFds用来监听sensor的时候用的。
ProximitySensor()中打开相应的节点,并获取sensor的描叙符fd。
vendor/mediatek/proprietary/hardware/sensor/Proximity.cpp
ProximitySensor::ProximitySensor()
: SensorBase(NULL, "m_alsps_input"),//PRO_INPUTDEV_NAME
mEnabled(0),
mInputReader(32)
{
mPendingEvent.version = sizeof(sensors_event_t);
mPendingEvent.sensor = ID_PROXIMITY;
mPendingEvent.type = SENSOR_TYPE_PROXIMITY;
memset(mPendingEvent.data, 0x00, sizeof(mPendingEvent.data));
mPendingEvent.flags = 0;
mPendingEvent.reserved0 = 0;
mEnabledTime =0;
mDataDiv = 1;
mPendingEvent.timestamp = 0;
mPendingEvent.distance = -1; //initialize p sensor value to invalid.
input_sysfs_path_len = 0;
memset(input_sysfs_path, 0, PATH_MAX);
char datapath[64]={"/sys/class/misc/m_alsps_misc/psactive"};
int fd = -1;
char buf[64]={0};
int len;
mdata_fd = FindDataFd();
if (mdata_fd >= 0) {
strcpy(input_sysfs_path, "/sys/class/misc/m_alsps_misc/");
input_sysfs_path_len = strlen(input_sysfs_path);
}
else
{
ALOGE("couldn't find input device ");
return;
}
ALOGD("prox misc path =%s", input_sysfs_path);
fd = open(datapath, O_RDWR);
if (fd >= 0)
{
len = read(fd,buf,sizeof(buf)-1);
if (len <= 0)
{
ALOGD("read div err, len = %d", len);
}
else
{
buf[len] = '\0';
sscanf(buf, "%d", &mDataDiv);
ALOGD("read div buf(%s), mdiv %d", datapath,mDataDiv);
}
close(fd);
}
else
{
ALOGE("open acc misc path %s fail ", datapath);
}
}
int ProximitySensor::FindDataFd() {
int fd = -1;
int num = -1;
char buf[64]={0};
const char *devnum_dir = NULL;
char buf_s[64] = {0};
int len;
devnum_dir = "/sys/class/misc/m_alsps_misc/psdevnum";
fd = open(devnum_dir, O_RDONLY);
if (fd >= 0)
{
len = read(fd, buf, sizeof(buf)-1);
close(fd);
if (len <= 0)
{
ALOGD("read devnum err, len = %d", len);
return -1;
}
else
{
buf[len] = '\0';
sscanf(buf, "%d\n", &num);
}
}
sprintf(buf_s, "/dev/input/event%d", num);
fd = open(buf_s, O_RDONLY);//打开相应的input节点,获取描叙符
ALOGE_IF(fd<0, "couldn't find input device");
return fd;
}
三、sensor使能与数据传输
1、sensor使能
根据enable传入的en来判断具体是使能还是关闭sensor。
int ProximitySensor::enable(int32_t handle, int en)
{
int fd=-1;
int flags = en ? 1 : 0;
ALOGD("PS enable: handle:%d, en:%d \r\n",handle,en);
strcpy(&input_sysfs_path[input_sysfs_path_len], "psactive");
ALOGD("path:%s \r\n",input_sysfs_path);
fd = open(input_sysfs_path, O_RDWR);
if(fd<0)
{
ALOGD("no PS enable control attr\r\n" );
return -1;
}
char buf[2]={0};
buf[1] = 0;
if (flags)
{
buf[0] = '1';
mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
mPendingEvent.distance = -1; //reset p sensor value to invalid.
}
else
{
buf[0] = '0';
}
mEnabled = flags; //assign enable after reset p sensor value.
write(fd, buf, sizeof(buf));
close(fd);
ALOGD("PS enable(%d) done", mEnabled );
return 0;
}
2、数据传输
上面在init_nusensors中有设置poll__poll对象,下面根据poll_poll的流程分析数据传输的过程:
static int poll__poll(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count) {
sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;
return ctx->pollEvents(data, count);
}
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 && ihasPendingEvents())) {
int nb = sensor->readEvents(data, count);//调用sensor的数据读取readEvent
if (data->type == SENSOR_TYPE_PEDOMETER) {
ALOGD("pollEvents pedometer buffer data[0]:%f data[1]:%f data[2]:%f data[3]:%f ",
data->data[0], data->data[1], data->data[2], data->data[3]);
}
if (data->type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
ALOGD("pollEvents significant buffer data[0]:%f ",
data->data[0]);
}
if (nb < count) {
// no more data for this sensor
mPollFds[i].revents = 0;
}
for (int j=0;j 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) {
int err;
err = errno;
ALOGE("poll() failed (%s)", strerror(errno));
return -err;
}
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;
}
下面看下Proximity的readEvents:
int ProximitySensor::readEvents(sensors_event_t* data, int count)
{
//ALOGE("fwq read Event 1\r\n");
if (count < 1)
return -EINVAL;
ssize_t n = mInputReader.fill(mdata_fd);//从输入设备中读取数据
if (n < 0)
return n;
int numEventReceived = 0;
input_event const* event;
while (count && mInputReader.readEvent(&event)) {//读取当前一个event的数据
int type = event->type;
//ALOGE("fwq1....\r\n");
if (type == EV_REL)//事件的坐标
{
processEvent(event->code, event->value);
//ALOGE("fwq2....\r\n");
}
else if (type == EV_SYN)//获取数据结束
{
//ALOGE("fwq3....\r\n");
int64_t time = android::elapsedRealtimeNano();//systemTime(SYSTEM_TIME_MONOTONIC);//timevalToNano(event->time);
mPendingEvent.timestamp = time;
if (mEnabled && mPendingEvent.distance >= 0)
{
//ALOGE("fwq4....\r\n");
if (mPendingEvent.timestamp >= mEnabledTime)
{
//ALOGE("fwq5....\r\n");
*data++ = mPendingEvent;
numEventReceived++;
}
count--;
mPendingEvent.distance = -1;
}
}
else if (type != EV_REL)
{
ALOGE("ProximitySensor: unknown event (type=%d, code=%d)",
type, event->code);
}
mInputReader.next();
}
//ALOGE("fwq read Event 2\r\n");
return numEventReceived;
}
到这里sensor HAL层从模块的加载、sensor的打开和数据的传输就已经结束完毕,下面会分析sensor framework与HAL层的交互工作。