一.無法休眠
進入休眠後,如果系統不持有鎖,將會寫mem到/sys/power/state(可參考如果沒走到這一步,即列印資訊中沒有suspend entry,說明系統持有鎖,這時可將鎖列印出來。核心已經實現了該介面,呼叫介面,可將下面的**移植過去,就可找到具體的鎖了。
#include #include #include #include #include static struct wake_lock messages_wakelock;
static int print_thread_interval = 30;
static int sprd_deep_print_thread(void *data)
msleep(100);
wake_unlock(&messages_wakelock);
set_current_state(task_interruptible);
schedule_timeout(print_thread_interval * hz);
} return 0;
}static int __init deep_sleep_debug_init(void)
static void __exit deep_sleep_debug_exit(void)
module_init(deep_sleep_debug_init);
module_exit(deep_sleep_debug_exit);
module_author("www");
module_license("gpl");
drivers/base/power/wakeup.c
void pm_print_active_wakeup_sources(void)
else if (!active &&
(!last_activity_ws ||
ktime_to_ns(ws->last_time) >
ktime_to_ns(last_activity_ws->last_time)))
} if (!active && last_activity_ws)
pr_info("last active wakeup source: %s\n",
last_activity_ws->name);
srcu_read_unlock(&wakeup_srcu, srcuidx);
}export_symbol_gpl(pm_print_active_wakeup_sources);
休眠一段時間後,抓取核心資訊,然後查詢字元"active wakeup source"就可以知道誰持有鎖了。
休眠失敗(如某個驅動的syspend函式返回值不為0)
[ 1162.993597] pm: suspend entry (deep)
[ 1162.997519] pm: syncing filesystems ... done.
[ 1163.054265] gnss_pm_notify event:3
[ 1163.057889] sprd-sensor sprd-sensorhub: status=3
[ 1163.062745] [asoc: pcm ] sprd_pcm_pm_notifier, pm_suspend_prepare.
[ 1163.069098] [asoc: pcm ] sprd_pcm_pm_notifier, pm_suspend_prepare.
[ 1163.075503] freezing user space processes ...
[ 1163.076758] sec-nfc 1-0027: sec_nfc_poll: info: 96dd3018
[ 1163.078915] pm: wakeup pending, aborting suspend
[ 1163.086347] freezing of tasks aborted after 0.010 seconds
[ 1163.091928] oom killer enabled.
[ 1163.095297] restarting tasks ...
[ 1163.096082] sec-nfc 1-0027: sec_nfc_poll: info: 96dd3018
[ 1163.099011] done.
二.底電流大
2.0 確認下初始上電的漏電流
接電源,不開機,如果漏電流不在參考範圍內,需要進行排查。方法也比較簡單,選擇vbat的網路,對該網路的晶元乙個接乙個進行摘除,如果電流正常了,就是該模組引起的。
2.1 摘晶元能降低底電流的,一般比較容易排查問題
2.1.1 休眠後電流為30ma,由於audio pa的使能腳配置成高阻,導致使能腳沒有拉低,pa仍在工作。
2.1.2 霍爾感測器喚醒後,如果中斷腳配置沒有配置成輸入,也會導致底電流增大,因為感測器仍在工作。
2.1.3 沒有關閉相應的ldo,導致晶元漏電(某些共享ldo,**bug等)。
2.1.4 某些晶元,如果休眠時是斷電的,但由於i2c休眠預設也是上拉的,會引起漏電。
2.1.5 某些晶元,就算不沒有上拉io,也會漏電,這個不好排查,需要做實驗來確認。
2.16 如果摘除了所有外設,只保留了最小系統,電流仍然很大,可以排查下電路的差異部分。比如展訊有32k和非32k(省成本,通過pmic輸出32k波形,但功耗會大2ma)晶體方案,如果硬體問題導致軟體識別晶體型別出錯,就可能導致電流偏大。
2.2 射頻部分沒有正確配置(開飛行模式底電流正常)
cat /sys/kernel/debug/rpm_state vmin的值為0,看核心資訊也正常休眠了,原來刷機後,要接sim卡來啟用, 這是平台的bug,可通過高通提供的補丁修復。
2.3 功耗優化方法
2.4 高通的文件(kba-170221213554_4_高通通用功耗溫公升優化技術期刊.pdf)
2.5 某些電源沒有正確關閉(高通平台,通過ramdump抓取記憶體資訊給高通分析,發現usb電源沒有關閉)。 (ramdump抓取方法
2.6 遇到底電流大的情況,軟體這邊一般可以先用原始**進行測試,如果底電流正常,一般是修改導致的。
2.7 底電流除錯ok後,建議在當前**打tag(也可儲存刷機映象),後期遇到的底電流異常可用來對比下,是不是主機板差異導致的底電流異常,或是提供乙個參考節點。遇到底電流為12ma的情況,回退到底電流正常的tag,底電流也不正常。後來發現是硬體加了電源晶元,也沒有通知我們來是適配。
2.8 lcd導致的底電流大
2.9 部分機器底電流大,正常底電流2.5ma,異常的機器的底電流範圍為2.5ma到4.2ma,因為機器都是進入休眠狀態的,軟體上無有效分析方法。通過電流拆解(分別將主機板上的單路電源接穩壓電源,對比分析),發現是ddr物料差異引起的(同一款ddr,待機電流差異)。
2.10 手機除錯中,比較常見的是實網電流電流高,確保手機已校準,機器有接天線,訊號強度滿格(訊號弱會導致平均電流高)。還高的話,可以讓手機連線儀器(儀器會提供有標準的網路訊號)。遇到不同地點,待機電流有差異的情況,最後發現是小區布網有問題。還不行,需要給cpu廠商分析了。
三.喚醒後硬體無法正常工作
3.1 記一次晶元休眠除錯
3.2 i2c死鎖導致喚醒後,i2c無法正常工作(
3.3 打**過程中,熄屏後過陣子喇叭沒有聲音,對方手機仍能聽到聲音,說明射頻仍在工作。然來為了省電,打**的過程中ap側會休眠,休眠時pa的使能腳被設定成了高阻,導致pa不工作了。讓pa的使能腳在休眠的時候上拉,就能保持高電平了。在正常的休眠中,pa的使能腳已經拉低,由於是弱上拉,不會導致晶元漏電,對休眠電流沒影響。(展訊)
Android設定系統休眠
可以通過以下方法進行系統休眠時間的獲取,設定休眠時間,喚醒螢幕等 測試環境android5.1 設定休眠時間 param millisecond param context public static void setscreensleeptime int millisecond,context c...
Android休眠設定時間
預設情況下,android系統在超過n分鐘沒操作,會自動關屏並進入休眠狀態。實際上,有些專案要求超時不休眠,如果只是針對單個應用程式,我們可以通過電源管理設定狀態來實現,方法一 調整 settings.system.putint getcontentresolver android.provider...
Android 禁止系統休眠,使屏
用了第二種,有效 android 禁止系統休眠,使螢幕不變暗,保持遊戲中螢幕高亮 實現這一功能的方法有兩種,一種是在manifest.xml檔案裡面宣告,一種是在 裡面修改layoutparams的標誌位。具體如下 1 在manifest.xml檔案裡面用user permission宣告。如下 這...