"高通 sensor 從native到HAL" "高通HAL層之Sensor HAL" "高通HAL層之bmp18x.cpp" 問題現象: 當休眠後,再次打開preesure sensor的時候,會出現隔一段時候後,APK才會出現數據;(數據有時候會很難出現) 問題分析: 從上面幾節中,我們可以知道 ...
問題現象:
當休眠後,再次打開preesure sensor的時候,會出現隔一段時候後,APK才會出現數據;(數據有時候會很難出現)
問題分析:
從上面幾節中,我們可以知道,framework到HAL是通過調用sensors.msm8909.so
調用到函數PressureSensor::readEvents
中取出的;
int PressureSensor::readEvents(sensors_event_t* data, int count)
{
int i = 0;
if (count < 1)
return -EINVAL;
if (mHasPendingEvent) {
mHasPendingEvent = false;
mPendingEvent.timestamp = getTimestamp();
*data = mPendingEvent;
return mEnabled ? 1 : 0;
}
if (mHasPendingMetadata) {
mHasPendingMetadata--;
meta_data.timestamp = getTimestamp();
*data = meta_data;
return mEnabled ? 1 : 0;
}
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)) {
int type = event->type;
if (type == EV_ABS) {
float value = event->value;
mPendingEvent.pressure = value * CONVERT_PRESSURE;
ALOGI("the pressure is %f\n", mPendingEvent.pressure);
} else if (type == EV_SYN) {
switch (event->code) {
case SYN_TIME_SEC:
mUseAbsTimeStamp = true;
report_time = event->value*1000000000LL;
break;
case SYN_TIME_NSEC:
mUseAbsTimeStamp = true;
mPendingEvent.timestamp = report_time+event->value;
break;
case SYN_REPORT:
if(mUseAbsTimeStamp != true) {
mPendingEvent.timestamp = timevalToNano(event->time);
}
if (mEnabled) {
// ALOGI("timestamp = %ld mEnabledTime = %ld mUseAbsTimeStamp = %d enable here\n", mPendingEvent.timestamp, mEnabledTime, mUseAbsTimeStamp);
// if (mPendingEvent.timestamp >= mEnabledTime)
{
*data = mPendingEvent;
ALOGI("data pressure is %f\n", data->pressure);
// data++;
numEventReceived++;
}
count--;
}
break;
}
} else {
ALOGE("PressureSensor: unknown event (type=%d, code=%d)",
type, event->code);
}
mInputReader.next();
}
#if FETCH_FULL_EVENT_BEFORE_RETURN
/* if we didn't read a complete event, see if we can fill and
try again instead of returning with nothing and redoing poll. */
if (numEventReceived == 0 && mEnabled == 1) {
n = mInputReader.fill(data_fd);
if (n)
goto again;
}
#endif
ALOGI("end the data the pressure is %f\n", mPendingEvent.pressure);
return numEventReceived;
}
增加if (mPendingEvent.timestamp >= mEnabledTime)
判斷是為了判斷SYN_REPORT
不延遲的情況;
mPendingEvent.timestamp
在這裡被賦值:
input_event const* event; //這個可以一直進來 if(mUseAbsTimeStamp != true) { mPendingEvent.timestamp = timevalToNano(event->time); }
event->time
代表了按鍵時間;可以用struct timeval
獲取系統時間。
其中input_event
和timeval
結構體如下:struct input_event { struct timeval time; //按鍵時間 __u16 type; //類型,在下麵有定義 __u16 code; //要模擬成什麼按鍵 __s32 value;//是按下還是釋放 }; struct timeval { __kernel_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microseconds */ };
//將時間轉換為ns static int64_t timevalToNano(timeval const& t) { return t.tv_sec*1000000000LL + t.tv_usec*1000; }
通過列印可以知道問題出現的時候
mPendingEvent.timestamp
是小於mEnabledTime
的,進不了判斷,所以上層也就無法獲取相應的數據;
mEnabledTime
是在int PressureSensor::enable(int32_t, int en)
函數中實現:
....
mEnabledTime = getTimestamp() + IGNORE_EVENT_TIME;
....
int64_t SensorBase::getTimestamp() {
struct timespec t;
t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_BOOTTIME, &t);
return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}
//不過CLOCK_BOOTTIME計算系統suspend的時間,也就是說,不論是running還是suspend(這些都算是啟動時間),CLOCK_BOOTTIME都會累積計時,直到系統reset或者shutdown。
所以在睡眠起來後mEnabledTime
會大於mPendingEvent.timestamp
,所以此時是沒有上報數據的;將判斷去掉即可;