关闭

STMemsAndroidHAL分析

212人阅读 评论(0) 收藏 举报
分类:
一   代码结构图




二  代码分析

open_sensors

//创建 sensors_poll_context_t 实例
// sensors_poll_context_t 继承Android 定义的struct sensors_poll_device_t, 
//实现了Android hal 定义的必要的接口
//也是对sensor 实例操作的核心结构体
/** Open a new instance of a sensor device using name */
static int open_sensors(const struct hw_module_t* module,
            const char __attribute__((unused))*id,
            struct hw_device_t** device)
{
    int status = -EINVAL;

    //实例化两个结构体   SensorBase* mSensors[numSensorDrivers], struct pollfd mPollFds[numFds];
    //主要通过这两个结构体对hal sensor进行操作
    sensors_poll_context_t *dev = new sensors_poll_context_t();

    //以下是对hal 规定的比较的方法和变量进行初始化
    memset(&dev->device, 0, sizeof(SENSOR_POLL_DEVICE));

    dev->device.common.tag        = HARDWARE_DEVICE_TAG;
     ...
    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;


    *device = &dev->device.common;
    status = 0;

    return status;
}

//根据配置,实例华对应的sensor
//mSensors 是一个SensorBase的实例
//mPollFds 是一个pollfd结构,用来监听sensor
sensors_poll_context_t::sensors_poll_context_t()
{
#if (SENSORS_MAGNETIC_FIELD_ENABLE == 1)
    mSensors[magn] = new MagnSensor();
    mPollFds[magn].fd = mSensors[magn]->getFd();
    mPollFds[magn].events = POLLIN;
    mPollFds[magn].revents = 0;
#endif

#if (SENSORS_GYROSCOPE_ENABLE == 1)
    mSensors[gyro] = new GyroSensor();
    mPollFds[gyro].fd = mSensors[gyro]->getFd();
    mPollFds[gyro].events = POLLIN;
    mPollFds[gyro].revents = 0;
#endif
   ...... 
}

以gyro为例
//首先初始化SensorBase, SensorBase 主要是打开gyro 对应的文件,返回一个文件句柄data_fd,
GyroSensor::GyroSensor()
    : SensorBase(NULL, SENSOR_DATANAME_GYROSCOPE),
    mInputReader(6),文件句柄
    mHasPendingEvent(false)
{
    pthread_mutex_init(&dataMutex, NULL);

//首先初始化mPendingEvent, mPendingEvent 是sensors_event_t结构体,表示的是传感器的数据
#if (GYROSCOPE_GBIAS_ESTIMATION_FUSION == 0)
    mPendingEvent[Gyro].version = sizeof(sensors_event_t);
    mPendingEvent[Gyro].sensor = ID_GYROSCOPE;
    mPendingEvent[Gyro].type = SENSOR_TYPE_GYROSCOPE;
    mPendingEvent[Gyro].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
//好像是对gyro数据进行校准的
  #if ((SENSORS_UNCALIB_GYROSCOPE_ENABLE == 1) && (GYROSCOPE_GBIAS_ESTIMATION_STANDALONE == 1))
    mPendingEvent[GyroUncalib].version = sizeof(sensors_event_t);
    mPendingEvent[GyroUncalib].sensor = ID_UNCALIB_GYROSCOPE;
    mPendingEvent[GyroUncalib].type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
    mPendingEvent[GyroUncalib].gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
  #endif
#endif

#if defined(STORE_CALIB_GYRO_ENABLED)
    pStoreCalibration = StoreCalibration::getInstance();
#endif

//判断sensor的节点文件是否存在
    if (data_fd) {的节点文件是否存在
        STLOGI("GyroSensor::GyroSensor gyro_device_sysfs_path:(%s)", sysfs_device_path);
    } else {
        STLOGE("GyroSensor::GyroSensor gyro_device_sysfs_path:(%s) not found", sysfs_device_path);
    }
//从driver获取到的原始数据
    memset(data_raw, 0, sizeof(data_raw));

//好像是对gyro数据进行校准的,会用到了iNemoEngine 和 AccelSensor对gyro进行校准
#if (GYROSCOPE_GBIAS_ESTIMATION_STANDALONE == 1)
    iNemoEngine_API_gbias_Initialization(NULL);
  #if (SENSORS_ACCELEROMETER_ENABLE == 1)
    acc = new AccelSensor();
  #endif
#endif
}

poll__activate

GyroSensor::enable
调用sensor的接口 writeEnable,writeDelay进行设置,这两个是linux input设备的概念。只有将enable节点设成1,才能从input event获取到数据。

3 poll


int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
{
    int nbEvents = 0;
    int n = 0;

    do {
        if (count) {
            n = poll(mPollFds, numFds, nbEvents ? 0 : -1);
            if (n < 0) {
                STLOGE("poll() failed (%s)", strerror(errno));
                return -errno;
            }
        }
        for (int i=0 ; count && i<numSensorDrivers ; i++) {
            SensorBase* const sensor(mSensors[i]);
            if((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents()))
            {
                //通过readEvents去获取event数据
                int nb = sensor->readEvents(data, count);
                if (nb < count) {
                    mPollFds[i].revents = 0;
                }
                count -= nb;
                nbEvents += nb;
                data += nb;
            }
        }
#if (ANDROID_VERSION >= ANDROID_JBMR2)
        if(mPollFds[flushFD].revents & POLLIN && count) {
            if (read(mPollFds[flushFD].fd, data, sizeof(struct sensors_event_t)) > 0) {
                count--;
                nbEvents++;
                data++;
            }
            mPollFds[flushFD].revents = 0;
        }
#endif
    } while (n && count);

    return nbEvents;
}

主要看GyroSensor::readEvents(
int GyroSensor::readEvents(sensors_event_t* data, int count)
{
    if (count < 1)
        return -EINVAL;

    if (mHasPendingEvent) {
        mHasPendingEvent = false;
    }

    ssize_t n = mInputReader.fill(data_fd);
    if (n < 0)
        return n;

    int numEventReceived = 0;
    input_event const* event;

#if (FETCH_FULL_EVENT_BEFORE_RETURN)
    again:
#endif

    while (count && mInputReader.readEvent(&event)) {
        
        if (event->type == EVENT_TYPE_GYRO) {
           //每次循环,分别读取event里面的  x, y, z 和timestamp数据
#if (DEBUG_GYROSCOPE == 1)
    STLOGD("GyroSensor::readEvents (event_code=%d)", event->code);
#endif

            float value = (float) event->value;
            if (event->code == EVENT_TYPE_GYRO_X) {
                data_raw[0] = value * CONVERT_GYRO_X;
            }
            else if (event->code == EVENT_TYPE_GYRO_Y) {
                data_raw[1] = value * CONVERT_GYRO_Y;
            }
            else if (event->code == EVENT_TYPE_GYRO_Z) {
                data_raw[2] = value * CONVERT_GYRO_Z;
            }
#if defined(GYRO_EVENT_HAS_TIMESTAMP)
            else if (event->code == EVENT_TYPE_TIME_MSB) {
                timestamp = ((int64_t)(event->value)) << 32;
            }
            else if (event->code == EVENT_TYPE_TIME_LSB) {
                timestamp |= (uint32_t)(event->value);
            }
#endif
            else {
                STLOGE("GyroSensor: unknown event code (type = %d, code = %d)", event->type, event->code);
            }
        } else if (event->type == EV_SYN) {
            //当收到EV_SYN,表示一次对sensor的数据已经读取完,接下来会对sensor数据进行处理,gyro数据处理将另外介绍
           ...
            //最后会将数据返回到data
            *data++ = mPendingEvent[Gyro];
        }
          


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11076次
    • 积分:184
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:19篇
    • 译文:0篇
    • 评论:0条