1. 程式人生 > 其它 >EasyCVR接入Ehome協議裝置PS流解析失敗?一文分析PS流解析注意點

EasyCVR接入Ehome協議裝置PS流解析失敗?一文分析PS流解析注意點

一、休眠概述

休眠,簡而言之就是裝置在不需要工作的時候把一些部件、外設關掉(掉電或讓它進入低功耗模式)。
為什麼要休眠呢?一言以蔽之:省電。
休眠分主動休眠和被動休眠。主動休眠:比如我電腦不用了,就通過設定讓系統進入休眠模式;被動休眠:系統檢測到自己閒的慌,為了節約故,自己就休眠去了。

二、Android休眠

休眠是核心的核心工作,而Android是基於Linux核心的,所以Android休眠和核心有著千絲萬縷的聯絡;由於Android的特殊應用場景:移動裝置,所以Android休眠和核心又有著特別的需求。
1、聯絡:
Android裝置停止使用,系統沒有什麼事情可做,進入休眠狀態的功能最終是由核心去實現的;每一類硬體都有自己的驅動,具體的驅動決定怎麼進入休眠以及處於何種層次的休眠。比如:對於platform_device,就按照platform_driver定義的規則,在suspend呼叫的時候,去做上面提到的事情:

structplatform_driver{
	int(*probe)(structplatform_device*);
	int(*remove)(structplatform_device*);
	void(*shutdown)(structplatform_device*);
	int(*suspend)(structplatform_device*,pm_message_tstate);
	int(*resume)(structplatform_device*);
	structdevice_driverdriver;
	conststructplatform_device_id*id_table;
};

2、Android的特別需求:
比如對於自己的電腦,不用讓它休眠好了;但是對於我們形影不離的手機,在休眠的時候還要睜一隻眼:來電了要通知你,QQ啊微信啊什麼的由資訊了也要通知你,所以Android在Linux核心休眠機制之上,提出了“Opportunistic Suspend”。

三、休眠實踐

絮絮叨叨這麼多,下面讓我們切切實實體驗下休眠。
1、休眠模式
休眠是分好幾種模式的,不同模式實現方式、耗電量不同,以下來自Documentation/power/states.txt:

Thekernelsupportsfourpowermanagementstatesgenerically,though
oneisgenericandtheotherthreearedependentonplatformsupport
codetoimplementthelow-leveldetailsforeachstate.
Thisfiledescribeseachstate,whattheyare
commonlycalled,whatACPIstatetheymapto,andwhatstringtowrite
to/sys/power/statetoenterthatstate

state:		Freeze/Low-PowerIdle
ACPIstate:	S0
String:		"freeze"

Thisstateisageneric,puresoftware,light-weight,low-powerstate.
Itallowsmoreenergytobesavedrelativetoidlebyfreezinguser
spaceandputtingallI/Odevicesintolow-powerstates(possibly
lower-powerthanavailableatruntime),suchthattheprocessorscan
spendmoretimeintheiridlestates.
ThisstatecanbeusedforplatformswithoutStandby/Suspend-to-RAM
support,oritcanbeusedinadditiontoSuspend-to-RAM(memorysleep)
toprovidereducedresumelatency.


State:		Standby/Power-OnSuspend
ACPIState:	S1
String:		"standby"

Thisstateoffersminimal,thoughreal,powersavings,whileproviding
averylow-latencytransitionbacktoaworkingsystem.Nooperating
stateislost(theCPUretainspower),sothesystemeasilystartsup
againwhereitleftoff.

Wetrytoputdevicesinalow-powerstateequivalenttoD1,which
alsoofferslowpowersavings,butlowresumelatency.Notalldevices
supportD1,andthosethatdon'tarelefton.


State:		Suspend-to-RAM
ACPIState:	S3
String:		"mem"

Thisstateofferssignificantpowersavingsaseverythinginthe
systemisputintoalow-powerstate,exceptformemory,whichis
placedinself-refreshmodetoretainitscontents.

Systemanddevicestateissavedandkeptinmemory.Alldevicesare
suspendedandputintoD3.Inmanycases,allperipheralbuseslose
powerwhenenteringSTR,sodevicesmustbeabletohandlethe
transitionbacktotheOnstate.

ForatleastACPI,STRrequiressomeminimalboot-strappingcodeto
resumethesystemfromSTR.Thismaybetrueonotherplatforms.


State:		Suspend-to-disk
ACPIState:	S4
String:		"disk"

Thisstateoffersthegreatestpowersavings,andcanbeusedevenin
theabsenceoflow-levelplatformsupportforpowermanagement.This
stateoperatessimilarlytoSuspend-to-RAM,butincludesafinalstep
ofwritingmemorycontentstodisk.Onresume,thisisreadandmemory
isrestoredtoitspre-suspendstate.

雖說kernel支援上述四種休眠模式,但具體哪幾種可用取決於你的硬體。那麼怎麼知道自己的Android裝置支援的休眠模式呢?

答案:通過/sys/檔案系統。查詢支援的休眠模式可以cat檔案/sys/power/state:

cat/sys/power/state
freezemem

如果我們往/sys/power/state檔案echo上面的某一種模式的字串,系統就會進入相應的休眠模式:

echo"mem">/sys/power/state

如果你搜索過Android休眠相關的內容,在老版本的Android(4.4版本之前)會見有提到PowerManager的setPowerState()方法,該方法即是通過以上方式使系統進入休眠。但自從引入Autosleep後,就不在這麼做了,setPowerState()方法也銷聲匿跡。

2、/sys/power/目錄下檔案

檔案簡介:

  • /sys/power/state:用來控制系統的Power狀態。讀取該檔案可以獲取系統支援的休眠模式,寫入該檔案休眠模式的一種,系統進入到指定的休眠模式。如上所示例。
  • /sys/power/autosleep:從Android wakelocks補丁集中演化而來,用於取代Android wakelocks中的自動休眠功能。向該檔案寫入/sys/power/state返回值的某一種,系統會在適當的時候進入指定的休眠的模式;讀取該檔案返回之前寫入的數值。
  • /sys/power/wake_lock、/sys/power/wake_unlock:即我們常說的休眠鎖,如果應用持有休眠鎖,系統將無法進入休眠模式。在Android wakelocks時代,寫wake_lock獲取鎖,寫wake_unlock釋放鎖;在AutoSleep時代,具體參見【Android休眠】之AutoSleep
  • wakeup_count:用於解決“system suspend和system wakeup events之間的同步問題”。
  • /sys/power/pm_async:狀態切換開關,允許/禁止User空間對裝置進行非同步的suspend和resume操作。
  • /sys/power/pm_freeze_timeout:系統在執行休眠動作的時候要凍結(freeze)使用者控制元件的程序和核心空間的允許凍結的核心執行緒,執行這些操作要耗時間吧?該檔案指定所需時間的最大值。

四、其他需要明瞭的問題

1、Android裝置螢幕暗下來的時候,並不是立即就進入了休眠模式;當所有喚醒源都處於de-avtive狀態後,系統才會進入休眠。

2、Android裝置連著adb線到其他裝置的情況下,裝置是不會進入休眠模式的。

3、有休眠操作就有喚醒,就需要喚醒源。喚醒源有很多種,在核心註冊,比如常用的Power按鍵。

4、曾經困惑的一個問題:系統怎麼知道自己應該進入休眠模式了?它的判斷依據是什麼?

在wakelock時代,系統休眠過程中去檢測休眠鎖;如果系統中沒有其他部件持有休眠鎖,就嘗試進入休眠模式,沒有異常事件發生的話就進入休眠模式。
Android從4.4開始使用autosleep機制,只要不存在任何active的喚醒源(wakeup_source)了,就進入休眠模式。

5、系統Power Manager整體流程