Android驱动开发之陀螺仪(三)

Android驱动开发之陀螺仪(二)

 

五、安卓hal层驱动数据读取

使能陀螺仪后,由于我配置的是原始数据准备中断,所以陀螺仪数据一旦准备好,就会发送中断信号,之前在第二章已经分析过中断的注册流程,这里就直接上代码了。

irqreturn_t inv_read_fifo(int irq, void *dev_id)
{

	struct inv_mpu_state *st = (struct inv_mpu_state *)dev_id;
	struct iio_dev *indio_dev = iio_priv_to_dev(st);
	int result, bpm,i;
	u8 Adata[BYTES_PER_SENSOR],Gdata[BYTES_PER_SENSOR],Mdata[BYTES_PER_SENSOR],data[1];
	u16 fifo_count;
	struct inv_reg_map_s *reg;
	u64 pts1;

	if (!(iio_buffer_enabled(indio_dev)) || (!st->chip_config.enable)){
	if (!(iio_buffer_enabled(indio_dev))){
	    PRINT_ERR("++++++iio_buffer_enabled end_session : %d+++++\n",st->chip_config.enable);
		goto end_session;
	}

	reg = &st->reg;

	if (st->sensor[SENSOR_ACCEL].on) {
		result = inv_i2c_read(st, reg->raw_accel,BYTES_PER_SENSOR, Adata);
		if (result)
			goto end_session;
	}
	if (st->sensor[SENSOR_GYRO].on) {
        	result = inv_i2c_read(st, reg->raw_gyro,BYTES_PER_SENSOR, Gdata);
		if (result)
			goto end_session;
	}


	if (st->sensor[SENSOR_COMPASS].on) {
        	result = inv_secondary_read(0x02, 1 , data);
        	if (result){
            		goto end_session;
	}

	if(!(data && 0x01))
            	goto end_session;

	result = inv_secondary_read(0x03,BYTES_PER_SENSOR, Mdata);
	if (result)
            	goto end_session;

	result = inv_secondary_read(0x09, 1 , data);
	if (result)
            	goto end_session;

	inv_report_gyro_accel(indio_dev, Adata, Gdata, Mdata, get_time_ns());

	goto end_session;

end_session:
    	inv_process_motion(st);
	return IRQ_HANDLED;
}

Android 安卓层陀螺仪流程分析这里是中断函数的实现,一开始先判断标志位是否使能,然后根据开启的模块读取相应的数据,最后调用inv_report_gyro_accel这个函数。

static int inv_report_gyro_accel(struct iio_dev *indio_dev,
					u8 *adata,u8 *gdata,u8 *mdata, s64 t)
{
	struct inv_mpu_state *st = iio_priv(indio_dev);
	short s[THREE_AXIS];
	int ind;
	int i;

	ind = 0;
	if (st->sensor[SENSOR_ACCEL].on) {
		for (i = 0; i < 3; i++)
			s[i] = be16_to_cpup((__be16 *)(&adata[ind + i * 2]));
		inv_push_8bytes_buffer(st, ACCEL_HDR, t, s);
	}
	if (st->sensor[SENSOR_GYRO].on) {
		for (i = 0; i < 3; i++)
			s[i] = be16_to_cpup((__be16 *)(&gdata[ind + i * 2]));
		inv_push_8bytes_buffer(st, GYRO_HDR, t, s);
	}
    if (st->sensor[SENSOR_COMPASS].on) {
    	for (i = 0; i < 3; i++)
    	    s[i] = mdata[i*2] | (mdata[i*2+1] << 8);
    	inv_push_8bytes_buffer(st, COMPASS_HDR, t, s);
    }

	return 0;
}
static int inv_push_8bytes_buffer(struct inv_mpu_state *st, u16 hdr,
							u64 t, s16 *d)
{
	struct iio_dev *indio_dev = iio_priv_to_dev(st);
	u8 buf[IIO_BUFFER_BYTES];
	int i;

	memcpy(buf, &hdr, sizeof(hdr));
	for (i = 0; i < 3; i++)
		memcpy(&buf[2 + i * 2], &d[i], sizeof(d[i]));
	iio_push_to_buffers(indio_dev, buf);
	memcpy(buf, &t, sizeof(t));
	iio_push_to_buffers(indio_dev, buf);
	

	return 0;
}

接着调用iio_push_to_buffers()这个将buf里的数据写到设备节点。

han层又是如果接收这个数据的呢

这就要回到之前第四章所要关注的第二个接口-----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)
{
    VHANDLER_LOG;

    int nbEvents = 0;
    int nb, polltime = -1;

    polltime = ((MPLSensor*) mSensor)->getStepCountPollTime();

    nb = poll(mPollFds, numSensorDrivers, polltime);

    if (nb > 0) {
        LOGI("poll nb=%d, count=%d, pt=%d\n", nb, count, polltime);
        for (int i = 0; count && i < numSensorDrivers; i++) {
            if (mPollFds[i].revents & (POLLIN | POLLPRI)) {
                nb = 0;
                if (i == mpl) {
                    LOGI("HAL: buildMpuEvent start\n");
                    ((MPLSensor*) mSensor)->buildMpuEvent();
                    mPollFds[i].revents = 0;
                } else if (i == compass) {
                    LOGI("HAL: buildCompassEvent\n");
                    ((MPLSensor*) mSensor)->buildCompassEvent();
                    mPollFds[i].revents = 0;
                }
                #if 1
                if(nb == 0) {
                    nb = ((MPLSensor*) mSensor)->readEvents(data, count);
                    LOGI("sensors_mpl:readEvents() - "
                            "i=%d, nb=%d, count=%d, nbEvents=%d, "
                            "data->timestamp=%lld, data->data[0]=%f,",
                            i, nb, count, nbEvents, data->timestamp, 
                            data->data[0]);
                    if (nb > 0) {
                        count -= nb;
                        nbEvents += nb;
                        data += nb;
                    }
                }
                #endif
            }
        }

        /* to see if any step counter events */
        if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {
            nb = 0;
            nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
                            data, count, ID_SC, SENSOR_TYPE_STEP_COUNTER, 0);
            LOGI("sensors_mpl:readStepCount() - "
                    "nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, "
                    "data->data[0]=%f,",
                    nb, count, nbEvents, data->timestamp, data->data[0]);
            if (nb > 0) {
                count -= nb;
                nbEvents += nb;
                data += nb;
            }
        }
    } else if(nb == 0) {
        /* to see if any step counter events */
        if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {
            nb = 0;
            nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(
                            data, count, ID_SC, SENSOR_TYPE_STEP_COUNTER, 0);
            LOGI("sensors_mpl:readStepCount() - "
                    "nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, "
                    "data->data[0]=%f,",
                    nb, count, nbEvents, data->timestamp, data->data[0]);
            if (nb > 0) {
                count -= nb;
                nbEvents += nb;
                data += nb;
            }
        }

        if (mPollFds[numSensorDrivers].revents & POLLIN) {
            char msg;
            int result = read(mPollFds[numSensorDrivers].fd, &msg, 1);
            LOGE("error reading from wake pipe (%s)", strerror(errno));
            mPollFds[numSensorDrivers].revents = 0;
        }
    }
    return nbEvents;
}

app开启陀螺仪功能之后,就通过这个接口轮询sensor事件,一旦设备节点有数据传递过来,会被poll()捕获。

nb = poll(mPollFds, numSensorDrivers, polltime);
                if (i == mpl) {
                    LOGI("HAL: buildMpuEvent start\n");
                    ((MPLSensor*) mSensor)->buildMpuEvent();
                    mPollFds[i].revents = 0;
                } else if (i == compass) {
                    LOGI("HAL: buildCompassEvent\n");
                    ((MPLSensor*) mSensor)->buildCompassEvent();
                    mPollFds[i].revents = 0;
                }

捕获到数据后,若是加速度和角加速度,则调用buildMpuEvent(),若是磁场,则调用buildCompassEvent()。

这里就举例分析加速度吧,都一样的原理。

void MPLSensor::buildMpuEvent(void)
{
    VHANDLER_LOG;


    LOGI("HAL:enter buildMpuEvent:%d\n",mLeftOverBufferSize);
    mSkipReadEvents = 0;
    int64_t mGyroSensorTimestamp=0, mAccelSensorTimestamp=0, latestTimestamp=0;
    int lp_quaternion_on = 0, sixAxis_quaternion_on = 0,
        ped_quaternion_on = 0, ped_standalone_on = 0;
    size_t nbyte;
    unsigned short data_format = 0;
    int i, nb, mask = 0,
    sensors = 3;
    char *rdata = mIIOBuffer;
    ssize_t rsize = 0;
    size_t readCounter = 0;
    char *rdataP = NULL;
    /* 2 Bytes header + 6 Bytes x,y,z data | 8 bytes timestamp */
    nbyte= (BYTES_PER_SENSOR + 8) * sensors * 1;

    /* special case for 6 Axis or LPQ */
    /* 2 Bytes header + 4 Bytes x data + 2 Bytes n/a */
    /* 4 Bytes y data | 4 Bytes z data */
    /* 8 Bytes timestamp */

    if (mLeftOverBufferSize > 0) {
        LOGI("append old buffer size=%d", mLeftOverBufferSize);
        memcpy(rdata, mLeftOverBuffer, mLeftOverBufferSize);
            LOGI(
            "HAL:input retrieve rdata=:%d, %d, %d, %d,%d, %d, %d, %d,%d, %d, "
            "%d, %d,%d, %d, %d, %d\n",
            rdata[0], rdata[1], rdata[2], rdata[3],
            rdata[4], rdata[5], rdata[6], rdata[7],
            rdata[8], rdata[9], rdata[10], rdata[11],
            rdata[12], rdata[13], rdata[14], rdata[15]);
    }
    rdataP = rdata + mLeftOverBufferSize;
    /* read expected number of bytes */
    rsize = read(iio_fd, rdataP, nbyte);
    LOGV("HAL:input data read iio_fd = %d", rsize);
    if(rsize < 0) {
        /* IIO buffer might have old data.
           Need to flush it if no sensor is on, to avoid infinite
           read loop.*/
        LOGE("HAL:input data file descriptor not available - (%s)",
             strerror(errno));
        if (sensors == 0) {
            rsize = read(iio_fd, rdata, MAX_SUSPEND_BATCH_PACKET_SIZE);
        }
        return;
    }
#if 1
    if((rsize + mLeftOverBufferSize) == 8) {
        /* store packet then return */
        memcpy(mLeftOverBuffer, rdataP, rsize);
        mLeftOverBufferSize += rsize;
        LOGV_IF(1, "HAL:input data has partial packet");


        LOGV("HAL:input catch up retrieve rdata=:%d, %d, %d, %d, %d, %d, %d, %d",
            mLeftOverBuffer[0], mLeftOverBuffer[1], mLeftOverBuffer[2], mLeftOverBuffer[3],
            mLeftOverBuffer[4], mLeftOverBuffer[5], mLeftOverBuffer[6], mLeftOverBuffer[7]);
        mSkipReadEvents = 1;
        return;
    }
    LOGV("HAL:input data mLeftOverBufferSize=%d", mLeftOverBufferSize);
#endif
    /* reset data and count pointer */
    rdataP = rdata;
    readCounter = rsize + mLeftOverBufferSize;

    while (readCounter > 0) {
        // since copied buffer is already accounted for, reset left over size
        mLeftOverBufferSize = 0;
        // clear data format mask for parsing the next set of data
        mask = 0;
        data_format = *((short *)(rdata));
        LOGV("HAL:input data_format = %d", data_format);
        LOGV("HAL:input readCounter = %d", readCounter);
        LOGV_IF(INPUT_DATA && ENG_VERBOSE,
                "HAL:input data_format=%x", data_format);


        if ((data_format & ~DATA_FORMAT_MASK) || (data_format == 0)) {
            LOGE("HAL:input invalid data_format 0x%02X", data_format);
            return;
        }


        if (data_format & DATA_FORMAT_STEP) {
            if (data_format == DATA_FORMAT_STEP) {
                rdata += BYTES_PER_SENSOR;
                latestTimestamp = *((long long*) (rdata));
                LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x - ts: %lld", data_format, latestTimestamp);
                // readCounter is decrement by 24 because DATA_FORMAT_STEP only applies in batch  mode
                readCounter -= BYTES_PER_SENSOR_PACKET;
            } else {
                LOGV_IF(0, "STEP DETECTED:0x%x", data_format);
            }
            mPedUpdate |= data_format;
            mask |= DATA_FORMAT_STEP;
            // cancels step bit
            data_format &= (~DATA_FORMAT_STEP);
        }


        if (data_format & DATA_FORMAT_MARKER) {
            LOGV_IF(ENG_VERBOSE, "MARKER DETECTED:0x%x", data_format);
            // cancels marker bit
            data_format &= (~DATA_FORMAT_MARKER);
            mFlushBatchSet = 1;
        }


        if (data_format == DATA_FORMAT_QUAT) {
            mCachedQuaternionData[0] = *((int *) (rdata + 4));
            mCachedQuaternionData[1] = *((int *) (rdata + 8));
            mCachedQuaternionData[2] = *((int *) (rdata + 12));
            rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
            mQuatSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_QUAT;
            readCounter -= BYTES_QUAT_DATA;
        }
        else if (data_format == DATA_FORMAT_6_AXIS) {
            mCached6AxisQuaternionData[0] = *((int *) (rdata + 4));
            mCached6AxisQuaternionData[1] = *((int *) (rdata + 8));
            mCached6AxisQuaternionData[2] = *((int *) (rdata + 12));
            rdata += QUAT_ONLY_LAST_PACKET_OFFSET;
            mQuatSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_6_AXIS;
            readCounter -= BYTES_QUAT_DATA;
        }
        else if (data_format == DATA_FORMAT_PED_QUAT) {
            mCachedPedQuaternionData[0] = *((short *) (rdata + 2));
            mCachedPedQuaternionData[1] = *((short *) (rdata + 4));
            mCachedPedQuaternionData[2] = *((short *) (rdata + 6));
            rdata += BYTES_PER_SENSOR;
            mQuatSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_PED_QUAT;
            readCounter -= BYTES_PER_SENSOR_PACKET;
        }
        else if (data_format == DATA_FORMAT_PED_STANDALONE) {
            LOGV_IF(ENG_VERBOSE, "STEP DETECTED:0x%x", data_format);
            rdata += BYTES_PER_SENSOR;
            mStepSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_PED_STANDALONE;
            readCounter -= BYTES_PER_SENSOR_PACKET;
            mPedUpdate |= data_format;
        }
        else if (data_format == DATA_FORMAT_GYRO) {
            mCachedGyroData[0] = *((short *) (rdata + 2));
            mCachedGyroData[1] = *((short *) (rdata + 4));
            mCachedGyroData[2] = *((short *) (rdata + 6));
            rdata += BYTES_PER_SENSOR;
            mGyroSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_GYRO;
            readCounter -= BYTES_PER_SENSOR_PACKET;
        }
        else if (data_format == DATA_FORMAT_ACCEL) {
            mCachedAccelData[0] = *((short *) (rdata + 2));
            mCachedAccelData[1] = *((short *) (rdata + 4));
            mCachedAccelData[2] = *((short *) (rdata + 6));
            rdata += BYTES_PER_SENSOR;
            mAccelSensorTimestamp = *((long long*) (rdata));
            mask |= DATA_FORMAT_ACCEL;
            readCounter -= BYTES_PER_SENSOR_PACKET;
        }
        else  if (data_format == DATA_FORMAT_COMPASS) {
            if (mCompassSensor->isIntegrated()) {
                mCachedCompassData[0] = *((short *) (rdata + 2));
                mCachedCompassData[1] = *((short *) (rdata + 4));
                mCachedCompassData[2] = *((short *) (rdata + 6));
                rdata += BYTES_PER_SENSOR;
                mCompassTimestamp = *((long long*) (rdata));
                mask |= DATA_FORMAT_COMPASS;
                readCounter -= BYTES_PER_SENSOR_PACKET;
            }
        }
        rdata += BYTES_PER_SENSOR;


        /* handle data read */
        if (mask & DATA_FORMAT_GYRO) {
            /* batch mode does not batch temperature */
            /* disable temperature read */
            if (!(mFeatureActiveMask & INV_DMP_BATCH_MODE)) {
                // send down temperature every 0.5 seconds
                // with timestamp measured in "driver" layer
                if(mGyroSensorTimestamp - mTempCurrentTime >= 500000000LL) {
                    mTempCurrentTime = mGyroSensorTimestamp;
                    long long temperature[2];
                    if(inv_read_temperature(temperature) == 0) {
                        LOGV_IF(INPUT_DATA,
                        "HAL:input inv_read_temperature = %lld, timestamp= %lld",
                        temperature[0], temperature[1]);
                        inv_build_temp(temperature[0], temperature[1]);
                     }


                }
            }
            mPendingMask |= 1 << Gyro;
            mPendingMask |= 1 << RawGyro;


            if (mLocalSensorMask & INV_THREE_AXIS_GYRO) {
                inv_build_gyro(mCachedGyroData, mGyroSensorTimestamp);
                LOGV_IF(INPUT_DATA,
                        "HAL:input inv_build_gyro: %+8d %+8d %+8d - %lld",
                        mCachedGyroData[0], mCachedGyroData[1],
                        mCachedGyroData[2], mGyroSensorTimestamp);
           }
           latestTimestamp = mGyroSensorTimestamp;
        }


        if (mask & DATA_FORMAT_ACCEL) {
            mPendingMask |= 1 << Accelerometer;
            if (mLocalSensorMask & INV_THREE_AXIS_ACCEL) {
                inv_build_accel(mCachedAccelData, 0, mAccelSensorTimestamp);
                 LOGV_IF(INPUT_DATA,
                    "HAL:input inv_build_accel: %+8ld %+8ld %+8ld - %lld",
                    mCachedAccelData[0], mCachedAccelData[1],
                    mCachedAccelData[2], mAccelSensorTimestamp);
                /* remember inital 6 axis quaternion */
                inv_time_t tempTimestamp;
                inv_get_6axis_quaternion(mInitial6QuatValue, &tempTimestamp);
                if (mInitial6QuatValue[0] != 0 || mInitial6QuatValue[1] != 0 ||
                        mInitial6QuatValue[2] != 0 || mInitial6QuatValue[3] != 0) {
                    mInitial6QuatValueAvailable = 1;
                    LOGV_IF(INPUT_DATA && ENG_VERBOSE,
                        "HAL:input build 6q init: %+8ld %+8ld %+8ld %+8ld",
                        mInitial6QuatValue[0], mInitial6QuatValue[1],
                        mInitial6QuatValue[2], mInitial6QuatValue[3]);
                }


            }
            latestTimestamp = mAccelSensorTimestamp;
        }


        if ((mask & DATA_FORMAT_COMPASS)) {
            int status = 0;
            if (mCompassSensor->providesCalibration()) {
                status = mCompassSensor->getAccuracy();
                status |= INV_CALIBRATED;
            }
            if (mLocalSensorMask & INV_THREE_AXIS_COMPASS) {
            inv_build_compass(mCachedCompassData, status,
                              mCompassTimestamp);
            LOGV_IF(INPUT_DATA,
                    "HAL:input inv_build_compass: %+8ld %+8ld %+8ld - %lld",
                    mCachedCompassData[0], mCachedCompassData[1],
                    mCachedCompassData[2], mCompassTimestamp);
            }
            latestTimestamp = mCompassTimestamp;
        }


        if (isLowPowerQuatEnabled() && lp_quaternion_on == 1
                                && (mask & DATA_FORMAT_QUAT)) {
            /* if bias was applied to DMP bias,
               set status bits to disable gyro bias cal */
            int status = 0;
            if (mGyroBiasApplied == true) {
                LOGV_IF(INPUT_DATA && ENG_VERBOSE, "HAL:input dmp bias is used");
                status |= INV_BIAS_APPLIED;
            }
            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
            inv_build_quat(mCachedQuaternionData,
                       status,
                       mQuatSensorTimestamp);
            LOGV_IF(INPUT_DATA,
                    "HAL:input inv_build_quat-3x: %+8ld %+8ld %+8ld - %lld",
                    mCachedQuaternionData[0], mCachedQuaternionData[1],
                    mCachedQuaternionData[2],
                    mQuatSensorTimestamp);
            latestTimestamp = mQuatSensorTimestamp;
        }


        if ((mask & DATA_FORMAT_6_AXIS) && check6AxisQuatEnabled()
                                    && (sixAxis_quaternion_on == 1)) {
            /* if bias was applied to DMP bias,
               set status bits to disable gyro bias cal */
            int status = 0;
            if (mGyroBiasApplied == true) {
                LOGV_IF(INPUT_DATA && ENG_VERBOSE, "HAL:input dmp bias is used");
                status |= INV_QUAT_6AXIS;
            }
            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
            inv_build_quat(mCached6AxisQuaternionData,
                       status,
                       mQuatSensorTimestamp);
            LOGV_IF(INPUT_DATA,
                    "HAL:input inv_build_quat-6x: %+8ld %+8ld %+8ld - %lld",
                    mCached6AxisQuaternionData[0], mCached6AxisQuaternionData[1],
                    mCached6AxisQuaternionData[2], mQuatSensorTimestamp);
            latestTimestamp = mQuatSensorTimestamp;
        }


        if ((mask & DATA_FORMAT_PED_QUAT) && checkPedQuatEnabled()
                                          && (ped_quaternion_on == 1)) {
            /* if bias was applied to DMP bias,
               set status bits to disable gyro bias cal */
            int status = 0;
            if (mGyroBiasApplied == true) {
                LOGV_IF(INPUT_DATA && ENG_VERBOSE,
                        "HAL:input dmp bias is used");
                status |= INV_QUAT_6AXIS;
            }
            status |= 32 | INV_QUAT_3AXIS; /* default 32 (16/32bits) */
            mCachedPedQuaternionData[0] = mCachedPedQuaternionData[0] << 16;
            mCachedPedQuaternionData[1] = mCachedPedQuaternionData[1] << 16;
            mCachedPedQuaternionData[2] = mCachedPedQuaternionData[2] << 16;
            inv_build_quat(mCachedPedQuaternionData,
                       status,
                       mQuatSensorTimestamp);


            LOGV_IF(INPUT_DATA,
                    "HAL:HAL:input inv_build_quat-ped_6x: %+8ld %+8ld %+8ld - %lld",
                    mCachedPedQuaternionData[0], mCachedPedQuaternionData[1],
                    mCachedPedQuaternionData[2], mQuatSensorTimestamp);
            latestTimestamp = mQuatSensorTimestamp;
        }


        /* take the latest timestamp */
        if (mask & DATA_FORMAT_STEP) {
        /* work around driver output duplicate step detector bit */
            if (latestTimestamp > mStepSensorTimestamp) {
                mStepSensorTimestamp = latestTimestamp;
                LOGV_IF(INPUT_DATA,
                    "HAL:input build step: 1 - %lld", mStepSensorTimestamp);
            } else {
                mPedUpdate = 0;
            }
        }
   }    //while end
} 

从代码中可以看到从设备节点读取数据。

rsize = read(iio_fd, rdataP, nbyte);

然后进行在下面这段代码中,将读取到的数据赋予sensors.accel这个对象

inv_error_t inv_build_accel(const long *accel, int status, inv_time_t timestamp)
{
    if ((status & INV_CALIBRATED) == 0) {
        sensors.accel.raw[0] = (short)accel[0];
        sensors.accel.raw[1] = (short)accel[1];
        sensors.accel.raw[2] = (short)accel[2];
        sensors.accel.status |= INV_RAW_DATA;
        inv_apply_calibration(&sensors.accel, inv_data_builder.save_accel_mpl.accel_bias);
    } else {
        sensors.accel.calibrated[0] = accel[0];
        sensors.accel.calibrated[1] = accel[1];
        sensors.accel.calibrated[2] = accel[2];
        sensors.accel.status |= INV_CALIBRATED;
        sensors.accel.accuracy = status & 3;
        inv_data_builder.save.accel_accuracy = status & 3;
    }
    sensors.accel.status |= INV_NEW_DATA | INV_SENSOR_ON;
    sensors.accel.timestamp_prev = sensors.accel.timestamp;
    sensors.accel.timestamp = timestamp;

    return INV_SUCCESS;
}

运行完buildMpuEvent()接着就是readEvents();

int MPLSensor::readEvents(sensors_event_t* data, int count)
{
    VHANDLER_LOG;
 
    inv_execute_on_data();

    int numEventReceived = 0;

    long msg;
    msg = inv_get_message_level_0(1);

    LOGI("\nHAL:enter readEvents:%x\n",msg);

    // handle partial packet read
    if (mSkipReadEvents)
        return numEventReceived;

    for (int i = 0; i < NumSensors; i++) {
        int update = 0;

        // load up virtual sensors
        if (mEnabled & (1 << i)) {
            update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i);
            mPendingMask |= (1 << i);

            if (update && (count > 0)) {
                *data++ = mPendingEvents[i];
                count--;
                numEventReceived++;
            }
        }
    }
    LOGV("\nHAL:readEvents end\n");
    return numEventReceived;
}

重点是这一段代码

if (mEnabled & (1 << i)) {
            update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i);
            mPendingMask |= (1 << i);

            if (update && (count > 0)) {
                *data++ = mPendingEvents[i];
                count--;
                numEventReceived++;
            }
        }

在构造函数里有这么一句代码

mHandlers[Accelerometer] = &MPLSensor::accelHandler;

那么下面这句也就不难看懂,就是运行accelHandler

#define CALL_MEMBER_FN(pobject, ptrToMember) ((pobject)->*(ptrToMember))
update = CALL_MEMBER_FN(this, mHandlers[i])(mPendingEvents + i);
int MPLSensor::accelHandler(sensors_event_t* s)
{
    VHANDLER_LOG;
    int update;
    LOGI("\nHAL:enter accelHandler\n");
    update = inv_get_sensor_type_accelerometer(
        s->acceleration.v, &s->acceleration.status, &s->timestamp);
    LOGV_IF(HANDLER_DATA, "HAL:accel data : %+f %+f %+f -- %lld - %d",
            s->acceleration.v[0], s->acceleration.v[1], s->acceleration.v[2],
            s->timestamp, update);
    mAccelAccuracy = s->acceleration.status;
    return update;
}
int inv_get_sensor_type_accelerometer(float *values, int8_t *accuracy,
                                       inv_time_t * timestamp)
{
    int status;
    /* Converts fixed point to m/s^2. Fixed point has 1g = 2^16.
     * So this 9.80665 / 2^16 */
#define ACCEL_CONVERSION 0.000149637603759766f
    long accel[3];
    inv_get_accel_set(accel, accuracy, timestamp);
    values[0] = accel[0] * ACCEL_CONVERSION;
    values[1] = accel[1] * ACCEL_CONVERSION;
    values[2] = accel[2] * ACCEL_CONVERSION;
    if (hal_out.accel_status & INV_NEW_DATA)
        status = 1;
    else
        status = 0;
    MPL_LOGV("accel values:%f %f %f -%d -%lld", values[0], values[1],
                              values[2], status, *timestamp);
    return status;
}

    这里将raw accel数据转换成accel数据后传递给mPendingEvents这个对象,mPendingEvents这个对象又赋值给data这个对象,而data这个对象就是frameworks层通过poll传递下来的参数,frameworks层再将这个参数一层层传递到app的onSensorChanged();

至此,android陀螺仪的驱动开发梳理完毕。

 

六、总结

    据说君正是有调试过MPU9250的,但是实际上很多地方都对不上,代码也是残缺的,我估计调试的并不是我们买的newton2_plus的这个开发板,所以很多地方都是自己做了修改,本文只是提供下大致的思路,可能对伸手党不太友好。

hal层和kernel层的代码分析完了 ,顺便把安卓层分析了一遍,做了UML模型,下面是传送门:

https://blog.csdn.net/u014078917/article/details/82259640

    

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值