五、安卓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; }这里是中断函数的实现,一开始先判断标志位是否使能,然后根据开启的模块读取相应的数据,最后调用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; }
重点是这一段代码
扫描二维码关注公众号,回复:
1539126 查看本文章
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的这个开发板,所以很多地方都是自己做了修改,本文只是提供下大致的思路,可能对伸手党不太友好。