五、安卓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