高通非adsp 架構下的sensor的bug調試

来源:https://www.cnblogs.com/linhaostudy/archive/2018/08/15/9483255.html
-Advertisement-
Play Games

"高通 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_eventtimeval結構體如下:

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,所以此時是沒有上報數據的;將判斷去掉即可;

patch地址

patch


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 插入排序,是迴圈遍歷一個無序數組(例如有10個元素),把遍歷出來的數值(第i個元素)插入到已經排過順序的數組(這個有序數組有10-i個元素)中。 用一個 數組 舉個例子: 初始數組:1, 89, 4, 34, 56, 40, 59, 60, 39, 1, 40, 90, 48 第一次迴圈(i=0): ...
  • 最近公司需要在伺服器上實現兩個音頻的合成及效果處理。 哇,乍一聽功能很簡單吧,就是將兩個音頻疊加,隨便一個媒體處理軟體幾秒鐘即可完成,但這僅僅只是針對單用戶而言而已。其次,本來這種服務原本就不應該在伺服器上面實現,為何? 流媒體處理是相當耗費伺服器資源的,包括IO,CPU,bandwidth等等。 ...
  • [TOC] 背景敘述 在前面幾篇 MEF 插件式開發 系列博客中,我分別在 和 兩種框架下實驗了 MEF 的簡單實驗,由於 由來已久,因此基於該框架下衍生出的很多優秀的 MEF 框架較多。但是對於 來說,情況有所不同,由於它本身對 DI 內置並提供支持,因此我嘗試使用它的全新 依賴註入(DI) 來做 ...
  • CentOS 7 建議在一個純凈的 centos7上進行下麵的安裝部署$ setenforce 0 # 臨時關閉,重啟後失效$ systemctl stop firewalld.service # 臨時關閉,重啟後失效# 修改字元集,否則可能報 input/output error的問題,因為日誌里 ...
  • pidof     我們知道每個小孩一齣生就會一個全國唯一的編號來對其進行標識,用於以後上學,辦社保等,就是我們的身份證號。那麼在Linux系統中,用來管理運行程式的標識叫做PID,就是大家熟知的進程ID。那麼如何來找到程式的PID了,那麼就需要用到命令 pidof ,其功能主要 ...
  • 按照網上的命令都為安裝php5-fpm 和 php5-sqlite, 但是發現無法找到軟體,可能是系統版本比較高的緣故,原來的版本已經不支持了。 經過努力華找到如下安裝方法 sudo apt get install php fpm (預設安裝的是php7) sudo apt get install ...
  • 文本文件log.txt中,若某行開頭含有“Modified”字元串,去除之,新的文件放在1.txt中。上述命令在命令行中執行即可。 mark一下 參考 ...
  • 又過了比較長的時間,基本上都是一周一更了,這期我們就來演示Linux系統中OpenSUSE系統的安裝吧! 安裝OpenSUSE系統 系統映像文件下載 OpenSUSE 15下載地址: https://www.7down.com/soft/278533.html https://www.xp510.c ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...