Sensor系列二 HAL层分析

一、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层的交互工作。



你可能感兴趣的:(02-Android,sensor系统)