<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > WinCE電源管理的實(shí)現

WinCE電源管理的實(shí)現

作者: 時(shí)間:2011-02-24 來(lái)源:網(wǎng)絡(luò ) 收藏

電源管理的目的是節能,基本的節能方法是使系統適時(shí)的進(jìn)出休眠狀態(tài).比如用戶(hù)按下On/Off按鈕,或者監視用戶(hù)活動(dòng)的定時(shí)器超時(shí),或者應用呼叫api都可以使得系統休眠,用戶(hù)再次按下On/Off或者其他喚醒中斷將使得系統退出休眠.從而可見(jiàn),電源管理模塊和用戶(hù)活動(dòng)情況密不可分,電源管理是用戶(hù)活動(dòng)所驅動(dòng)的. WinCE中處理用戶(hù)與系統交互的部分是GWES,所以早期電源管理工作是由GWES來(lái)實(shí)現.( GWES:Graphics,Windows and Events Subsystem.圖形,窗口和事件子系統.主要負責圖形輸出和用戶(hù)交互). 但GWES提供的電源管理模塊功能過(guò)于粗糙死板:所有子設備只能有On和Suspend狀態(tài),應用程序無(wú)法得到任何狀態(tài)轉換通知,等等……直到WinCE4.0才引入了電源管理模塊用以替代GWES中的電源管理功能.(進(jìn)一步的,為了方便電源管理模塊的集中管理,還需要關(guān)閉原來(lái)GWES對電源管理功能.方法是注冊表HKLMSYSTEMCurrentControlSetControlPower設置DisableGwesPowerOff=1來(lái)禁止GWES插手電源管理.系統是默認禁止的.此外,一些用戶(hù)活動(dòng)情況仍舊依賴(lài)GWES獲得,設置注冊表HKLMsystemGWE下的ActivityEvent=PowerManager/ActivityTimer/UserActivity.從而告訴GWES,當鼠標,鍵盤(pán),觸摸屏等輸入發(fā)生時(shí)候,GWES要SetEvent這個(gè)全局事件以通知電源管理模塊.)

新的電源管理模塊提供更完整和靈活的功能,系統電源可以自由靈活設定,子設備電源狀態(tài)可以單獨設定,應用可以獲得電源通知等等.

[系統電源]

OEM可以依據需要任意定義系統電源狀態(tài),比如On,ScreenOff,UserIdle,SystemIdle,Suspend等.系統電源狀態(tài)更多的是代表系統電源的一種配置方案,它是各個(gè)子設備電源配置的集合.它設定一種可能出現的情景,并且事先擬定了此情景下電力分配策略(哪些子設備打開(kāi),哪些子設備關(guān)閉).比如,也許On可以代表常規工作的情景,所有子設備打開(kāi)的狀態(tài); ScreenOff可以代表LCD被用戶(hù)請求關(guān)閉的情景,LCD背燈電源被關(guān)閉的狀態(tài); UserIdle可以代表用戶(hù)一段時(shí)間沒(méi)有操作的情景,cpu/soc將進(jìn)入low power的狀態(tài); Suspend可以代表設備空閑很久了可以?huà)炱鸬那榫?所有非必要供電的子設備電源關(guān)閉的狀態(tài);等等…系統的電源狀態(tài)的定義很靈活而且自由. 可以在注冊表定義系統電源狀態(tài).比如:

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPowerStateOn]

"Default"=dword:0 ; D0

"Flags"=dword:10000 ; POWER_STATE_ON

上面定義了On狀態(tài),Flags是附加的狀態(tài)信息(hints),對應pm.h中的宏定義POWER_STATE_ON.defaule表示在這個(gè)狀態(tài)下所有子設備的默認狀態(tài).

電源管理模塊的重點(diǎn)之一是制訂系統電源管理策略,這包括定義系統電源狀態(tài),決定狀態(tài)間轉換的條件.以默認的版本為例子,簡(jiǎn)單圖示如下:

子,簡(jiǎn)單圖示如下:

On:用戶(hù)與系統交互時(shí)候的狀態(tài).

UserIdle: 代表用戶(hù)停止輸入,但可能仍然在使用的情景,比如閱讀文件.

SystemIdle: 代表用戶(hù)停止使用設備,但處理器仍然工作的情景,比如,后臺文件傳輸.

Suspend: 代表休眠狀態(tài).

用戶(hù)在使用時(shí)候,系統處于On狀態(tài),用戶(hù)停止輸入,系統自動(dòng)轉入UserIdle狀態(tài),持續沒(méi)有輸入時(shí)間后,進(jìn)入SystemIdle狀態(tài),持續一段時(shí)間后,系統將自動(dòng)進(jìn)入Suspend狀態(tài).應用程序也可以調用SetSystemPowerState()來(lái)進(jìn)行狀態(tài)切換.

在這個(gè)基礎上,根據自己的平臺特點(diǎn),增加新的策略就基本可以滿(mǎn)足常規產(chǎn)品需要.

1. On/Off按鍵. (A).電源管理模塊已經(jīng)支持了電源按鍵功能,最直接的辦法可以在pdd中增加電源按鍵定義,按鍵io的初始化,檢測等等,(B).從外部發(fā)送消息給電源管理模塊來(lái)通知按鍵事件.(C).使用api直接轉換狀態(tài).即不使用電源管理模塊提供的按鍵功能,直接調用SetSystemPowerState使得系統進(jìn)入Suspend狀態(tài).這是很常見(jiàn)的做法,我們設計一個(gè)電源按鍵的流驅動(dòng),檢測到按鍵時(shí)候,呼叫api將系統電源轉換到Suspend.

2. 加入背燈控制.比如在On狀態(tài)下打開(kāi)請求顯示驅動(dòng)打開(kāi)背燈,在UserIdle和SystemIdle狀態(tài)下請求顯示驅動(dòng)關(guān)閉背燈.

[設備電源]

支持電源管理的設備驅動(dòng)的實(shí)現,存在有大量的例子.簡(jiǎn)單介紹如下:

電源管理模塊并不直接實(shí)現對子設備的電源開(kāi)關(guān)控制,子設備的電源控制是由各個(gè)設備驅動(dòng)來(lái)控制的.電源管理模塊透過(guò)設備驅動(dòng)的IOCTLs來(lái)請求設備控制自身電源.系統電源狀態(tài)是靈活自由設定的,而設備電源狀態(tài)是固定的,最多有5個(gè):D0,D1,D2,D3,D4代表Full on,Low on, Standby, Sleep, Off這5個(gè)狀態(tài).

不是所有的設備驅動(dòng)都支持電源管理(至少,在電源管理出現前的早期的設備驅動(dòng)不會(huì )支持).電源管理模塊對設備驅動(dòng)提出了一個(gè)規范和架構,滿(mǎn)足規范的驅動(dòng)納入電源管理.對于流驅動(dòng)控制的設備,要支持電源管理要滿(mǎn)足的條件,簡(jiǎn)單來(lái)說(shuō)有:1.聲明自己是支持電源管理的(Iclass值).2.驅動(dòng)中實(shí)現電源管理模塊所要求的IOCTLs.3.驅動(dòng)加載時(shí)候要匯報所支持的電源狀態(tài)和相關(guān)特征.4.***_PowerDown和***_PowerUp接口接收系統休眠和喚醒通知.此外,設計驅動(dòng)還應該了解:設備不一定具備所有5種狀態(tài),但至少可以工作在D0;電源管理模塊可能會(huì )要求設備進(jìn)入任何設備電源狀態(tài),并不僅僅是設備所匯報自己支持的那幾個(gè);如果被要求進(jìn)入不支持的狀態(tài),應該進(jìn)入另一個(gè)它所支持的更高功耗的狀態(tài);當前狀態(tài)不需要重復設置;設備電源狀態(tài)不一定和系統的電源狀態(tài)同步.除了流驅動(dòng)外,還有許多內建驅動(dòng)需要支持電源管理功能.簡(jiǎn)單總結:1.顯示驅動(dòng)通過(guò)ExtCode接口(SETPOWERMANAGEMENT命令,類(lèi)似IOCTLs)來(lái)控制顯示驅動(dòng)的電源,還控制背燈.2鍵盤(pán)驅動(dòng)的接口KeybdDriverPowerHandler.3.觸摸屏是TouchPanelPowerHandler.4.內建網(wǎng)絡(luò )miniport驅動(dòng)是MiniportReset接口.5.PCMCIA驅動(dòng)是PowerUp和PowerDown.還有打印機,紅外等一些內建驅動(dòng).

[OAL對電源管理的支持]

[系統的 idle狀態(tài)]

當沒(méi)有線(xiàn)程準備運行時(shí)候,內核就調用OEMIdle().這個(gè)函數在bsp中,可以由OEM來(lái)修改定制.一般我們在這個(gè)函數里面會(huì )要求cpu進(jìn)入low power狀態(tài)節省電流消耗.一般的cpu/soc都提供了對應idle的睡眠模式.當中斷發(fā)生或者喚醒事件發(fā)生時(shí)候,要保證cpu快速離開(kāi)idle狀態(tài),返回運行狀態(tài).

系統idle狀態(tài)和前面說(shuō)的UserIdle狀態(tài)是不同概念,前者是cpu負荷情況驅動(dòng),代表系統空閑;后者是用戶(hù)活動(dòng)驅動(dòng),代表用戶(hù)空閑.

一個(gè)OEMIdle()的推薦流程:

根據dwReschedTime變量來(lái)計算下次喚醒時(shí)間

判斷sleep類(lèi)型,假如需要,調整喚醒時(shí)間

Idle處理器和時(shí)鐘

中斷發(fā)生

判斷喚醒源

更新CurMSec, idle計數值.

[系統suspend狀態(tài)]

當用戶(hù)按下OFF按鈕或者應用調用api進(jìn)入suspend狀態(tài)時(shí)候,內核會(huì )調用OEMPowerOff()函數.在OEMPowerOff()函數里面實(shí)現系統掛起,并且系統喚醒后繼續從OEMPowerOff()被掛起處執行. OEMPowerOff()時(shí)候要進(jìn)入睡眠模式,睡眠模式根據cpu芯片的sleep模式來(lái)選擇,要選擇最低功耗的模式.如果cpu芯片提供的最低功耗模式是PowerDown模式,處理工作比較復雜,因為喚醒后是從reset處開(kāi)始執行,要恢復掛起時(shí)候的環(huán)境,使得應用程序不知道自己被掛起過(guò).一般按照這樣流程來(lái)處理:關(guān)屏,清framebuffer, 保存必須的寄存器到內存, 設置io, 保存通用寄存器, 保存wakeup地址, 靜止中斷,清除cache, 使能喚醒源中斷, 設置sdram自刷新, cpu進(jìn)入PowerDown. 喚醒后的流程相反即可. 對于PowerDown模式之外的其他模式,比如慢時(shí)鐘模式, 處理則簡(jiǎn)單很多,最重要的是設置喚醒源(一般是任何中斷可喚醒), sdram進(jìn)入自刷新?tīng)顟B(tài).

[SDRAM的控制]

SDRAM的耗電比較大,一般是系統里面除了lcd背光外,sdram是最大的電力消耗設備.常見(jiàn)有mobile sdram和normal sdram這2種,mobile sdram相對于normal sdram增加了溫度補償自刷新,局部陣列自刷新,深度休眠特性,更加適合功耗限制設備,(但mobile sdram工作在更低電壓(1.8~2.5v),我想,對有些3.3v總線(xiàn)的cpu未必適合,因為總線(xiàn)會(huì )增加很多電平轉換的電路.)

在OEMPowerOff()函數里面,保存好當前環(huán)境到sdram,然后使得sdram進(jìn)入自刷新?tīng)顟B(tài),cpu就可以進(jìn)入最低功耗的sleep模式.喚醒后需要退出自刷新?tīng)顟B(tài).

[應用層于電源管理]

電源管理模塊也提供了應用層接口,使得應用程序也可以參與到電源管理.

應用層可以通過(guò)SetSystemPowerState()來(lái)設置系統電源狀態(tài),可以通過(guò)SetDevicePower來(lái)設置子設備電源狀態(tài),可以通過(guò)SetPowerRequirement通知電源管理模塊將子設備設置在特殊電源狀態(tài)下,不隨系統電源改變.此外,電源管理還提供了消息隊列,應用層還可以通過(guò)RequestPowerNotifications函數請求電源管理模塊發(fā)送相關(guān)消息(PBT_RESUME, PBT_POWERSTATUSCHANGE, PBT_TRANSITION, PBT_POWERINFOCHANGE).

設計應用程序也許有幾點(diǎn)值得考慮:不要無(wú)謂占用cpu,盡可能快的讓出cpu.比如一個(gè)很小的動(dòng)畫(huà),哪怕只占1%的cpu也會(huì )導致一些系統無(wú)法進(jìn)入低功耗.這里是2點(diǎn)建議:(1)當應用不在foreground時(shí)候,停止占用cpu.(2)用戶(hù)沒(méi)有和應用交互時(shí)候,停止應用對cpu的占用.另外一些應用也許是相反情況的,播放媒體文件時(shí)候,當開(kāi)始播放時(shí)候,不希望自動(dòng)進(jìn)入suspend模式.可以(1)每隔一些時(shí)間就reset一次定時(shí)器.(2)或者設置所有定時(shí)器為0,停止電源管理(tcpmp就是這樣的).

[電源管理的系統實(shí)現]

電源管理模塊實(shí)體是一個(gè)動(dòng)態(tài)鏈接庫pm.dll來(lái)實(shí)現的.可以在pb的catalog窗口中選擇電源管理組件添加到os中.如下圖,微軟提供了2個(gè)選擇(二選一).第一個(gè)代表完整功能,所有api全功能實(shí)現,第二個(gè)代表空實(shí)現(形式上提供接口,但空函數).

電源管理模塊的代碼結構是分層的,MDD PDD.MDD是抽象公共庫,不需要改動(dòng),PDD是平臺相關(guān),主要改動(dòng)都在PDD.針對平臺特性,微軟提供了2種類(lèi)型PDD示例.一種是default,另外一種是pda版本的.默認的情況,使用的是default.如果要使用pda版本的,需要在系統中指定環(huán)境變量SYSGEN_PM_PDA. default和pda版本的主要區別:

default版本定義了4種狀態(tài):On, UserIdle, SystemIdle, Suspend;

PDA版本定義了On, ScreenOff, Unattended, Resume, Suspend.

default版本的簡(jiǎn)單描述:UserIdle狀態(tài)是描述用戶(hù)在使用但沒(méi)有操作,比如閱讀.SystemIdle狀態(tài)描述用戶(hù)停止使用,但系統仍然工作,比如文件傳輸.

PDA版本簡(jiǎn)單描述:ScreenOff狀態(tài)描述用戶(hù)請求把屏幕背燈關(guān)閉.是用戶(hù)主動(dòng)關(guān)閉的情況,區別于UserIdle,UserIdle是自動(dòng)的.Unattended狀態(tài)表示后臺工作,用戶(hù)不會(huì )對其察覺(jué)的情景,比如ActiveSync每5分鐘喚醒系統同步,然后繼續suspend; Resume狀態(tài)描述喚醒后情景,比如喚醒后在指定時(shí)間內決定轉到哪個(gè)狀態(tài),否則繼續suspend.

[定制電源管理模塊的方法]

Pm.dll是由device.exe加載的,首先device.exe當然是必須的,在pb的catalog中檢查Device Manager組件,或者檢查SYSGEN_DEVICE變量.其次,仍舊應該選擇上圖的電源管理組件power management full.

方案一(推薦方案):在bsp的驅動(dòng)目錄中新建一個(gè)pm目錄,在這里完成電源管理模塊PDD部分的實(shí)現,并鏈接MDD最終生成一個(gè)pm.dll替代原來(lái)系統的pm.dll.

PDD參考微軟提供的代碼platform.cpp,主要修改是增加狀態(tài)轉換的動(dòng)作執行單元.

方案二:完全不修改電源管理部分,因為默認的PDD在狀態(tài)轉換時(shí)候雖然沒(méi)有動(dòng)作,但是廣播了PBT_TRANSITION消息,可以截獲這個(gè)消息來(lái)進(jìn)行狀態(tài)轉換.這樣作法不如方案一直接.如果是進(jìn)程實(shí)現,還浪費一個(gè)寶貴進(jìn)程資源.

[影響系統功耗各方面考慮]

1.系統時(shí)鐘周期

典型的WinCE系統時(shí)鐘周期是1ms,增加時(shí)鐘周期有助進(jìn)一步降低設備功耗.在OEMInit()àOALTimerInit()修改系統時(shí)鐘.

2.可變系統時(shí)鐘節拍Variable Tick Scheduler

典型設計里wince每毫秒產(chǎn)生系統時(shí)鐘中斷,那么每隔1ms都會(huì )使得idle退出,如果發(fā)現沒(méi)有線(xiàn)程就緒時(shí)候繼續idle. 對有功耗限制的設計,可以考慮改變系統時(shí)鐘節拍后進(jìn)入idle狀態(tài).這樣在預期的時(shí)間段里,idle狀態(tài)不會(huì )被無(wú)謂的系統時(shí)鐘中斷喚醒.

3.LCD背燈的調節策略

早期的設計使用一個(gè)獨立的驅動(dòng)來(lái)實(shí)現背燈的控制和調節策略.簡(jiǎn)單介紹背燈驅動(dòng)原理:背燈驅動(dòng)啟動(dòng)一個(gè)監視工作線(xiàn)程,不停等待3個(gè)事件:

1. BackLightChangeEvent

2. PowerChangedEvent(供電電源發(fā)生變化,比如插手了AC電源,會(huì )獲得了這個(gè)事件)

3. PowerManager/ActivityTimer/UserActivity(用戶(hù)輸入事件)

從注冊表中讀取超時(shí)值,當超時(shí)事件發(fā)生,則將系統背燈關(guān)閉.背燈關(guān)閉期間,用戶(hù)重新活動(dòng)時(shí)候,發(fā)生第3個(gè)事件,則打開(kāi)背燈.注冊表的超時(shí)值決定了背燈工作時(shí)間.類(lèi)同pc上設置屏幕保護時(shí)間.此外,背燈驅動(dòng)也需要提供對系統電源狀態(tài)切換的支持.power down時(shí)候要關(guān)閉背燈,power up時(shí)候打開(kāi)背燈.

電源管理模塊可以定義一種系統電源狀態(tài)來(lái)描述背燈關(guān)閉的情景(比如在UserIdle或者ScreenOff狀態(tài)時(shí)候關(guān)閉背燈,On狀態(tài)時(shí)候打開(kāi)背燈)所以,背燈驅動(dòng)可以被取消.

4.IO口的漏電流

空載IO避免設置成為輸入口,考慮懸空輸入導致門(mén)電路開(kāi)關(guān),造成電流消耗.負載IO依照情況設定,一般設置輸出低.

5.電池驅動(dòng)

電池驅動(dòng)最主要的功能是監視系統電力.它提供了其他模塊和應用對系統電源狀態(tài)的查詢(xún),查詢(xún)是AC,還是battary供電,查詢(xún)電池電量等

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>