STMemsAndroidHAL分析

原创 2017年01月02日 21:21:35
一   代码结构图




二  代码分析

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];
        }
          


相关文章推荐

S5PV210启动过程分析

原文地址:http://www.51hei.com/bbs/dpj-25281-1.html S5PV210内部有96Kb的IRAM和64Kb的IROM。 DRAM0的地址:0x2000_00...

六自由度机械臂的运动学分析

  • 2017年11月13日 17:49
  • 221KB
  • 下载

mjpg-streamer项目源码分析

前一段时间自己买了个开发板(GT2440的),可是我没有够相应的买cmos摄像头,可是又想做下国嵌的usb视频采集和传输的哪个项目,没办法,只好网上找找相关的项目,最终发现了mjpg-streamer...

大型网站架构案例分析

  • 2017年11月12日 16:21
  • 3.24MB
  • 下载

语义分析的一些方法(中篇)

2 文本语义分析 前面讲到一些文本基本处理方法。一个文本串,对其进行分词和重要性打分后(当然还有更多的文本处理任务),就可以开始更高层的语义分析任务。 2.1 Topic Model ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:STMemsAndroidHAL分析
举报原因:
原因补充:

(最多只允许输入30个字)