在所有版本的Windows CE操作系統(tǒng)中,圖形、視窗和事件子系統(tǒng)(GWES)在電源管理方面都發(fā)揮了關(guān)鍵作用。這是因?yàn)樵缙诎姹镜?a target="_blank">電源管理功能是由用戶的活動(dòng)所驅(qū)動(dòng)的,而GWES負(fù)責(zé)處理所有用戶的輸入,如鍵盤、鼠標(biāo)和觸摸屏。GWES設(shè)置定時(shí)器監(jiān)控用戶的活動(dòng),當(dāng)一段時(shí)間內(nèi)用戶沒有任何輸入時(shí),便使系統(tǒng)進(jìn)入休眠狀態(tài)。通過注冊(cè)表可以設(shè)置這幾個(gè)定時(shí)器的超時(shí)值,它們可以分別被用于電池供電或外部電源供電時(shí)。當(dāng)然,通過注冊(cè)表也可以禁用GWES的電源管理功能,它在Windows CE.NET以后的版本中是默認(rèn)被禁用的,這有利于電源管理器的集中管理。
對(duì)應(yīng)有5種系統(tǒng)電源狀態(tài)(等級(jí)):No Power, On, Suspend, Idle, Critical off。相關(guān)描述和轉(zhuǎn)換方式參見上表。?基本的電源管理功能所采用的節(jié)能方法是使系統(tǒng)適時(shí)的進(jìn)入休眠狀態(tài),當(dāng)下面的一種事件發(fā)生時(shí),系統(tǒng)將進(jìn)入休眠狀態(tài)(SUSPEND):* ??用戶按下On/Off按鈕;
-
?監(jiān)控用戶活動(dòng)的定時(shí)器超時(shí);
-
應(yīng)用程序調(diào)用API,如GwesPowerOffSystem或SetSystemPowerState。當(dāng)下面的一種事件發(fā)生時(shí),系統(tǒng)將退出休眠狀態(tài):
-
???用戶再次按下On/Off按鈕;
-
發(fā)生某個(gè)警告事件,如某個(gè)日期或時(shí)間定時(shí)器的到時(shí)提醒;
-
發(fā)生某個(gè)喚醒事件,由外設(shè)如串口設(shè)備或者網(wǎng)卡觸發(fā)中斷來(lái)喚醒系統(tǒng)。雖然通過用戶操作、應(yīng)用程序或者外設(shè)都可以使系統(tǒng)進(jìn)入或者退出休眠狀態(tài),但基本的電源管理功能所能控制的粒度過大,對(duì)應(yīng)于CPU只有三種狀態(tài):On,Idle和Suspend,對(duì)應(yīng)于所有外設(shè)只有兩種狀態(tài):On和Suspend。而且,當(dāng)系統(tǒng)進(jìn)出休眠狀態(tài)時(shí),應(yīng)用程序都得不到任何通知。Windows CE的高級(jí)電源管理功能加入了電源管理組件的Windows CE具有高級(jí)的電源管理功能,它允許每個(gè)外設(shè)具有自己的電源狀態(tài),有別于一般的系統(tǒng)電源狀態(tài)(System Power State),被稱作設(shè)備電源狀態(tài)(Device Power State)?,F(xiàn)在應(yīng)用程序有能力設(shè)置個(gè)別外設(shè)的電源狀態(tài),比如一個(gè)文件傳輸程序,在保持串口或者藍(lán)牙端口正常通訊時(shí),可以關(guān)閉顯示屏幕和背光。這就為實(shí)現(xiàn)更高級(jí)別的動(dòng)態(tài)電源管理提供了可能。我們可以通過注冊(cè)表任意設(shè)定一組系統(tǒng)電源狀態(tài),使其對(duì)應(yīng)于我們?cè)O(shè)計(jì)的狀態(tài)模型。對(duì)于設(shè)備電源狀態(tài)則沒有這么大的靈活度,它具有5個(gè)設(shè)備狀態(tài):D0:Full on;D1:Low on;D2:Standby;D3:Sleep;D4:Off當(dāng)定義好系統(tǒng)電源狀態(tài),并為每個(gè)外設(shè)分配了設(shè)備電源狀態(tài)后,通過注冊(cè)表,我們可以將兩者進(jìn)行映射。在某個(gè)系統(tǒng)電源狀態(tài)下,比如一個(gè)電池供電的系統(tǒng),當(dāng)電池電量已經(jīng)少于50%時(shí),顯示屏幕和背光可能處于D1狀態(tài),而網(wǎng)絡(luò)設(shè)備可以設(shè)置為D3狀態(tài)。也就是說,在同一時(shí)刻,不同的外設(shè)可能處于不同的設(shè)備電源狀態(tài)中。這樣的靈活性意味著每個(gè)設(shè)備可以最小程度的消耗電池資源。
?????? 圖2 Windows CE高級(jí)電源管理框架如圖2所示,電源管理器實(shí)現(xiàn)為一個(gè)名為Pm.dll的動(dòng)態(tài)鏈接庫(kù),電源管理接口分為應(yīng)用程序和驅(qū)動(dòng)程序兩部分。驅(qū)動(dòng)程序通過DeviceIoControl服務(wù)例程來(lái)處理電源管理器發(fā)來(lái)的設(shè)備電源狀態(tài)改變請(qǐng)求,另外電源管理器通過消息隊(duì)列通知應(yīng)用程序電源相關(guān)的事件。
??? 為了獲得高級(jí)電源控制的功能,必須通過Platform Builder將電源管理組件編譯到內(nèi)核鏡像中。實(shí)現(xiàn)的源代碼參見{WINCEROOT}\\Private\\Winceos\\Coreos\\Device\\PMIF\\pmif.c,這段代碼只是一個(gè)封裝,它會(huì)調(diào)用{WINCEROOT}\\Public\\Common\\Oak\\Drivers\\PM中的組件。參考這個(gè)實(shí)現(xiàn)OEM可以根據(jù)需要設(shè)計(jì)自己的電源管理策略。?1. OAL的電源管理OEM AdaptaTIon Layer(OAL)是一層與硬件平臺(tái)相關(guān)的代碼,它在電源狀態(tài)轉(zhuǎn)換中扮演著重要的角色。首先必須實(shí)現(xiàn)的是以下幾個(gè)與硬件相關(guān)的函數(shù):OEMInit:初次上電時(shí)(或在冷啟后)被調(diào)用,一般在這個(gè)函數(shù)中處理一些重要的初始化工作,如初始化系統(tǒng)內(nèi)存,建立調(diào)試環(huán)境,設(shè)置系統(tǒng)中斷等;OEMIdle:沒有線程可調(diào)度運(yùn)行時(shí)被內(nèi)核調(diào)用,這時(shí)可將CPU置于低功耗狀態(tài),并保證其可以快速返回運(yùn)行狀態(tài);OEMPowerOff:系統(tǒng)進(jìn)入休眠(Suspend)狀態(tài)前被調(diào)用,它即是系統(tǒng)進(jìn)入休眠狀態(tài)前被調(diào)用的最后一個(gè)函數(shù),也是在系統(tǒng)被喚醒后所執(zhí)行的第一個(gè)函數(shù)(中斷處理程序以外);Interrupt Handler:一些用來(lái)喚醒系統(tǒng)的中斷處理程序。當(dāng)中斷發(fā)生時(shí),內(nèi)核首先調(diào)用中斷處理程序,其中一些中斷是可以將系統(tǒng)從睡眠狀態(tài)中喚醒的,但中斷時(shí)間內(nèi)能處理的事情非常少,在中斷處理程序里大部分API也是不能被調(diào)用的。高級(jí)的電源管理功能允許任何設(shè)備驅(qū)動(dòng)將其中斷作為系統(tǒng)的喚醒源,在版本W(wǎng)indows CE.NET 4.1以前,OAL掌管著所有的中斷處理,這就意味著在生成內(nèi)核鏡像以后,我們就無(wú)法在系統(tǒng)中添加新的中斷處理程序了?,F(xiàn)在即使這個(gè)設(shè)備是在運(yùn)行時(shí)才安裝到系統(tǒng)中來(lái)的,比如PCMCIA或者CF接口的無(wú)線網(wǎng)卡,它可以通過調(diào)用API(LoadIntChainHandler和FreeIntChainHandler)實(shí)現(xiàn)中斷處理程序的安裝和卸載。在系統(tǒng)中添加了新的中斷處理程序后,它就可以通過內(nèi)核IOCTL代碼(IOCTL_HAL_ENABLE_WAKE)實(shí)現(xiàn)其作為系統(tǒng)的喚醒源。位于操作系統(tǒng)內(nèi)核層的電源管理策略,也要為設(shè)備驅(qū)動(dòng)及上層應(yīng)用程序提供接口,通過PowerPolicyNoTIfy向電源管理組件發(fā)送事件請(qǐng)求,設(shè)備及應(yīng)用程序就可以參與到系統(tǒng)的電源管理策略中來(lái)。?2.?設(shè)備驅(qū)動(dòng)的電源管理我們可以為設(shè)備驅(qū)動(dòng)添加電源管理功能,首先就是要在驅(qū)動(dòng)程序中添加電源管理的IOCTL代碼,然后通知電源管理器該驅(qū)動(dòng)是支持電源管理的,最后在驅(qū)動(dòng)中編碼實(shí)現(xiàn)該設(shè)備支持的幾種電源狀態(tài)。2.1?建立支持電源管理的設(shè)備驅(qū)動(dòng)為了建立一個(gè)能夠?qū)υO(shè)備進(jìn)行電源管理的驅(qū)動(dòng)程序,我們必須首先建立一個(gè)支持non-COM-related設(shè)備接口的驅(qū)動(dòng)程序。non-COM-related設(shè)備接口標(biāo)明這個(gè)設(shè)備是支持電源管理的??梢杂靡韵路绞浇⑦@種接口:
-
? ? ? ?可以在注冊(cè)表中,用激活設(shè)備所用的IClass值定義接口;
-
? ? ? ? 可以在驅(qū)動(dòng)程序的Init函數(shù)中,設(shè)置注冊(cè)表中的IClass值;
-
? ? ? ? 可以使用AcTIvateDeviceEx的參數(shù)REGINI設(shè)置IClass值;
-
? ? ?可以在驅(qū)動(dòng)程序中顯示地調(diào)用AdverTIseInterface函數(shù)。電源管理器通過IOCTL代碼來(lái)和驅(qū)動(dòng)通信。通常情況下,當(dāng)一個(gè)驅(qū)動(dòng)程序聲明為支持電源管理時(shí),驅(qū)動(dòng)只需要在DeviceIoControl中實(shí)現(xiàn)電源的管理即可。下面是電源管理器用來(lái)與驅(qū)動(dòng)通信的IOCTL代碼:
-
?IOCTL_POWER_CAPABILITIES:代表電源管理器請(qǐng)求設(shè)備驅(qū)動(dòng)返回設(shè)備支持的電源狀態(tài)及相關(guān)特征;
-
?IOCTL_POWER_SET:請(qǐng)求驅(qū)動(dòng)更新設(shè)備的電源狀態(tài);
-
?IOCTL_POWER_QUERY:電源管理器詢問設(shè)備是否準(zhǔn)備好進(jìn)行狀態(tài)切換;
-
?IOCTL_POWER_GET:請(qǐng)求驅(qū)動(dòng)返回當(dāng)前設(shè)備的電源狀態(tài);
-
?IOCTL_REGISTER_POWER_RELATIONSHIP:通知父設(shè)備注冊(cè)所有它所控制的設(shè)備。其中IOCTL_POWER_CAPABILITIES和IOCTL_POWER_SET是支持電源管理的設(shè)備驅(qū)動(dòng)必須實(shí)現(xiàn)的。2.2 IOCTL代碼的實(shí)現(xiàn)在設(shè)備自舉的時(shí)候,設(shè)備驅(qū)動(dòng)必須使設(shè)備處于D0狀態(tài),當(dāng)電源管理器通過IOCTL_POWER_CAPABILITIES向設(shè)備發(fā)出查詢時(shí),設(shè)備驅(qū)動(dòng)應(yīng)該盡可能詳細(xì)的報(bào)告該設(shè)備的電源管理能力,以便將自己納入到系統(tǒng)的電源管理策略中去。在自舉完成后,電源管理器可以根據(jù)管理策略,調(diào)用IOCTL_POWER_SET調(diào)整設(shè)備的電源狀態(tài)。在設(shè)備自我管理電源的情況下,設(shè)備應(yīng)該通過DevicePowerNotify函數(shù)請(qǐng)求系統(tǒng)改變它們的電源狀態(tài)。在實(shí)現(xiàn)對(duì)IOCTL_POWER_SET支持時(shí),設(shè)備驅(qū)動(dòng)開發(fā)應(yīng)該注意以下幾點(diǎn):
-
?設(shè)備并不一定具備所有五種設(shè)備電源狀態(tài),但至少可以工作在D0狀態(tài);
-
??? 電源管理器可能會(huì)要求設(shè)備進(jìn)入任何設(shè)備電源狀態(tài),并不僅僅是設(shè)備聲明支持的幾個(gè)。
-
? 如果一個(gè)設(shè)備被要求進(jìn)入一個(gè)它并不支持的電源狀態(tài),它就會(huì)進(jìn)入另一個(gè)它支持的更高功耗的狀態(tài)。例如,一個(gè)設(shè)備并不支持D2,它會(huì)被要求進(jìn)入D1。
-
????電源管理器可能會(huì)通過發(fā)出IOCTL_POWER_SET,使設(shè)備再次進(jìn)入它已經(jīng)處于的當(dāng)前狀態(tài)。在這種情況下,設(shè)備驅(qū)動(dòng)程序簡(jiǎn)單的返回成功即可。
-
?? ? 設(shè)備的電源狀態(tài)不一定與系統(tǒng)的電源狀態(tài)同步,因?yàn)樗赡苁艿綉?yīng)用程序需求的限制。2.3?休眠和喚醒的處理支持電源管理的流設(shè)備驅(qū)動(dòng)通過XXX_PowerDown和XXX_PowerUp接收系統(tǒng)休眠和喚醒的通知,這些通知在內(nèi)核調(diào)用OEMPowerOff之前發(fā)出,并處于中斷上下文中。設(shè)備驅(qū)動(dòng)的開發(fā)者必須清楚,在系統(tǒng)休眠期間,設(shè)備應(yīng)該處于何種狀態(tài)。并不是所有的設(shè)備在這個(gè)時(shí)候都應(yīng)該強(qiáng)制被關(guān)閉,比如在音頻設(shè)備可以不依賴處理器來(lái)播放音樂時(shí),在系統(tǒng)休眠期間它的狀態(tài)就應(yīng)該交給電源管理器和應(yīng)用程序來(lái)處理。而如果這個(gè)音頻設(shè)備的播放需要處理器頻繁的工作,在系統(tǒng)進(jìn)入休眠狀態(tài)時(shí),驅(qū)動(dòng)程序應(yīng)該果斷的關(guān)閉設(shè)備的電源,即使該設(shè)備由于應(yīng)用程序的請(qǐng)求不處于D4狀態(tài)。另外,設(shè)備的D3狀態(tài)值得特殊考慮,因?yàn)檫@個(gè)狀態(tài)不僅僅與設(shè)備的功耗級(jí)別相關(guān),處于D3狀態(tài)的設(shè)備還被允許將系統(tǒng)從休眠狀態(tài)中喚醒。所以當(dāng)我們開發(fā)支持電源管理的設(shè)備驅(qū)動(dòng)時(shí)需要注意以下幾點(diǎn):
-
? ? ? 支持喚醒系統(tǒng)的設(shè)備不應(yīng)該主動(dòng)通過DevicePowerNotify請(qǐng)求進(jìn)入D3狀態(tài),因?yàn)橐话闱闆r下,只有當(dāng)系統(tǒng)打算進(jìn)入休眠狀態(tài)時(shí),電源管理器才將設(shè)備作為喚醒源啟用。從代碼的角度也應(yīng)該避免這一點(diǎn),因?yàn)轵?qū)動(dòng)程序無(wú)法區(qū)分來(lái)自IOCTL_POWER_SET中對(duì)D3狀態(tài)的請(qǐng)求是由它自己還是電源管理器發(fā)起的;
-
? 如果有必要,能喚醒系統(tǒng)的設(shè)備可以定義一樣的D2和D3狀態(tài),而只有D3具有啟動(dòng)喚醒的功能;
-
支持D3的設(shè)備不一定具有將系統(tǒng)從休眠狀態(tài)喚醒的功能,不能將系統(tǒng)喚醒的設(shè)備,但它又具有低功耗模式,是可以自己主動(dòng)請(qǐng)求進(jìn)入D3狀態(tài)的;???
-
如果不能喚醒系統(tǒng)的設(shè)備處于D3狀態(tài),在系統(tǒng)進(jìn)入休眠狀態(tài)時(shí),它應(yīng)該在XXX_PowerDown中將狀態(tài)轉(zhuǎn)換為D4,并且在XXX_PowerUp中恢復(fù)到D3狀態(tài);如果無(wú)法這么做,它就不應(yīng)該支持D3狀態(tài),而是在請(qǐng)求進(jìn)入D3時(shí)直接進(jìn)入D4狀態(tài);做到了以上幾點(diǎn),在系統(tǒng)進(jìn)入休眠狀態(tài)時(shí),OEM和應(yīng)用程序開發(fā)人員就可以請(qǐng)求將設(shè)備進(jìn)入D3狀態(tài),而不必關(guān)心這個(gè)設(shè)備是否支持喚醒系統(tǒng)。?3.?應(yīng)用程序的電源管理電源管理組件提供了一組接口供應(yīng)用程序參與到電源管理的活動(dòng)中,應(yīng)用程序可以通過RequestPowerNotifications函數(shù)請(qǐng)求電源管理器向其發(fā)送電源相關(guān)的通知,也可以通過SetPowerRequirement通知電源管理器將設(shè)備設(shè)置在特殊的電源狀態(tài)下。這樣,指定設(shè)備的電源狀態(tài)就不會(huì)隨系統(tǒng)電源狀態(tài)的改變而改變。3.1?電源通知機(jī)制電源相關(guān)的通知通過消息隊(duì)列傳遞給應(yīng)用程序,通常應(yīng)用程序新建一個(gè)消息隊(duì)列,并通過RequestPowerNotifications將這個(gè)消息隊(duì)列的句柄傳遞給電源管理器,同時(shí)創(chuàng)建一個(gè)線程偵聽來(lái)自這個(gè)隊(duì)列的消息。電源管理器定義了如下幾種通知:
-
PBT_RESUME:當(dāng)系統(tǒng)從休眠狀態(tài)被喚醒是產(chǎn)生;
-
?PBT_POWERSTATUSCHANGE:當(dāng)系統(tǒng)接入或者斷開外部電源時(shí)產(chǎn)生;
-
?PBT_TRANSITION:當(dāng)電源管理器執(zhí)行系統(tǒng)電源狀態(tài)轉(zhuǎn)換時(shí)發(fā)生;
-
PBT_POWERINFOCHANGE:當(dāng)電池信息更新時(shí)發(fā)生。3.2?電源請(qǐng)求機(jī)制電源請(qǐng)求機(jī)制為應(yīng)用程序提供了強(qiáng)大的能力控制電源管理器調(diào)整設(shè)備的電源等級(jí),與其他所有的電源設(shè)置相比,它具有很高的優(yōu)先級(jí)。舉例來(lái)說,假設(shè)有一個(gè)條形碼閱讀器連接在COM1端口,并且COM1只有在最高電源等級(jí)(D0)時(shí)才能驅(qū)動(dòng)這個(gè)條形碼閱讀器。為了使其正常工作,應(yīng)用程序?qū)⒄{(diào)用SetPowerRequirement把COM1指定D0狀態(tài)。假設(shè)之后串口驅(qū)動(dòng)自身決定降低一個(gè)電源等級(jí),驅(qū)動(dòng)調(diào)用DevicePowerNotify通知電源管理器它期望的設(shè)備電源狀態(tài),驅(qū)動(dòng)程序的這個(gè)請(qǐng)求將不起作用,直到應(yīng)用程序調(diào)用ReleasePowerRequirement為止。繼續(xù)這個(gè)例子,假設(shè)這時(shí)的系統(tǒng)電源狀態(tài)轉(zhuǎn)換為低能耗等級(jí),雖然與之相關(guān)的COM1電源等級(jí)為D3,由于應(yīng)用程序的電源請(qǐng)求,COM1將繼續(xù)維持在D0狀態(tài)。在調(diào)用SetPowerRequirement函數(shù)時(shí),指定POWER_FORCE標(biāo)志將強(qiáng)制設(shè)備不進(jìn)入休眠狀態(tài),即使這時(shí)系統(tǒng)已處于休眠狀態(tài)。3.3?設(shè)置系統(tǒng)電源狀態(tài)在某些應(yīng)用的場(chǎng)合下,應(yīng)用程序可能需要改變系統(tǒng)的電源狀態(tài)。OEM通過注冊(cè)表定義了系統(tǒng)支持的電源狀態(tài),?應(yīng)用程序可以通過GetSystemPowerState返回當(dāng)前系統(tǒng)電源狀態(tài)的名稱,也可以通過SetSystemPowerState改變系統(tǒng)的電源狀態(tài)本篇將以Windows Mobile為例介紹Windows CE電源管理的實(shí)現(xiàn),大體上,Windows Mobile分為Pocket PC和Smartphone兩種版本。這兩者之間的主要區(qū)別在于觸摸屏和電源模型,Smartphone采用的是“Always On”模型。為了說清楚它們的區(qū)別,我們就先從系統(tǒng)電源狀態(tài)說起吧(這里有些系統(tǒng)電源狀態(tài)是從WM5開始才有的)。1. Windows Mobile的系統(tǒng)電源狀態(tài)On:用戶與系統(tǒng)交互時(shí)的狀態(tài);BacklightOff:在一段時(shí)間內(nèi)(默認(rèn)15秒),如果一直沒有用戶操作(比如按下某個(gè)鍵或者觸摸屏幕),就關(guān)閉背光,這時(shí)其他的設(shè)備都沒變化。這個(gè)timeout值可以通過控制面板進(jìn)行設(shè)置;UserIdle:這個(gè)狀態(tài)只在Smartphone中被使用。經(jīng)過一段稍長(zhǎng)的時(shí)間,如果一直沒有用戶操作,就關(guān)閉背光和LCD。這個(gè)timeout值可以通過控制面板進(jìn)行設(shè)置;ScreenOff:一般由某些程序指定,才進(jìn)入這個(gè)狀態(tài)。比如音樂播放器程序,當(dāng)你聽音樂時(shí)按下某個(gè)鍵可以將屏幕關(guān)閉。PocketPC和Smartphone都使用這個(gè)狀態(tài),它與UserIdle的不同在于,ScreenOff意味著“用戶主動(dòng)關(guān)閉了顯示,只有當(dāng)他按下電源鍵時(shí)才重新顯示”,而UserIdle意味著“用戶有段時(shí)間沒操作了,那么我們可以關(guān)閉屏幕來(lái)省電”,所以在UserIdle時(shí),隨便按下Smartphone的哪個(gè)鍵都會(huì)啟動(dòng)顯示;Suspend:這是PocketPC的睡眠模式,幾乎所有設(shè)備都被關(guān)閉,直到某個(gè)硬件設(shè)備觸發(fā)中斷才將系統(tǒng)喚醒,這個(gè)timeout值可以通過控制面板進(jìn)行設(shè)置(默認(rèn)為3分鐘);Resuming:這是PocketPC被喚醒后的狀態(tài),這時(shí)屏幕是關(guān)閉的,并啟動(dòng)一個(gè)15秒的計(jì)時(shí)器,在這段時(shí)間內(nèi)決定接下來(lái)進(jìn)入哪個(gè)狀態(tài),如果計(jì)時(shí)器超時(shí)則重新回到睡眠狀態(tài);Unattended:這個(gè)狀態(tài)只在PocketPC中被使用,用戶對(duì)其不會(huì)有所察覺。有些程序,如ActiveSync每5分鐘會(huì)喚醒系統(tǒng)進(jìn)行同步,同步完成后再讓系統(tǒng)繼續(xù)睡眠,這段時(shí)間不希望打擾用戶,即程序在后臺(tái)執(zhí)行??梢酝ㄟ^注冊(cè)表查看系統(tǒng)電源狀態(tài)對(duì)應(yīng)的具體設(shè)備的電源狀態(tài),[HLM\\System\\CurrentControlSet\\Control\\Power\\State]。現(xiàn)在我們知道,Smartphone沒有真正的睡眠模式,即使它會(huì)在一段時(shí)間后關(guān)閉背光和屏幕,但它并沒有睡著,只是休息一下眼睛罷了,它的大腦和四肢仍在正常工作。PocketPC所采用的模型比Smartphone要復(fù)雜的多,你可以按下電源鍵讓系統(tǒng)睡眠,在必要時(shí),也可以喚醒系統(tǒng)做一些工作然后再繼續(xù)睡眠。如果你在Smartphone上運(yùn)行一個(gè)桌面精靈之類的程序,她為了引起你的注意,長(zhǎng)時(shí)間的蹦啊跳啊,不管白天還是黑夜,可想而知,你的待機(jī)時(shí)間將......你可能會(huì)覺得PocketPC的“Sleep”模型比Smartphone的“Always On”模型要省電,其實(shí)恰恰相反。因?yàn)樵谙到y(tǒng)睡眠的過程中,它需要通知所有的設(shè)備驅(qū)動(dòng),為了讓它們保存一些重要的信息并關(guān)閉相應(yīng)的硬件設(shè)備,在系統(tǒng)被喚醒時(shí)也需要通知它們恢復(fù)先前的工作。這個(gè)過程不僅耗時(shí)還可能會(huì)耗更多的電,因?yàn)橐恍┰O(shè)備在頻繁的狀態(tài)轉(zhuǎn)換過程中會(huì)消耗比較多的能量。這也就是為什么當(dāng)你收到一條短信時(shí),睡眠狀態(tài)的PocketPC要花3到6秒的時(shí)間來(lái)處理,而Smartphone只需要幾個(gè)微秒:)2. Windows Mobile的電源管理策略我們可以用系統(tǒng)電源狀態(tài)機(jī)來(lái)簡(jiǎn)單的描述Windows Mobile的電源管理策略,以PocketPC為例,系統(tǒng)電源狀態(tài)機(jī)如下圖所示:系統(tǒng)內(nèi)部的電源管理器負(fù)責(zé)協(xié)調(diào)電源狀態(tài)的轉(zhuǎn)換,電源狀態(tài)的轉(zhuǎn)換主要由一下幾種方式觸發(fā):計(jì)時(shí)器超時(shí):SuspendTimeout和ResumingSuspendTimeout,分別對(duì)應(yīng)于第一節(jié)介紹Suspend和Resuming狀態(tài)時(shí)所提到的計(jì)時(shí)器。細(xì)說起來(lái),它們每個(gè)又有兩個(gè)值,分別對(duì)應(yīng)著電源供電時(shí)和電池供電時(shí)的超時(shí)值,也就是注冊(cè)表[HLM\\System\\CurrentControlSet\\Control\\Power\\Timeout]中的ACSuspendTimeout、BattSuspendTimeout、ACResumingSuspendTimeout、BattResumingSuspendTimeout;系統(tǒng)調(diào)用:驅(qū)動(dòng)程序或應(yīng)用程序通過相應(yīng)的API,請(qǐng)求進(jìn)入某種電源狀態(tài)。這類API在前面的文章中已經(jīng)有所介紹,如SetSystemPowerState、SetPowerRequirement、DevicePowerNotify等;平臺(tái)相關(guān)的系統(tǒng)調(diào)用:通過PowerPolicyNotify通知電源管理器發(fā)生了某個(gè)事件,它的實(shí)現(xiàn)比較靈活,驅(qū)動(dòng)程序或應(yīng)用程序可以通過相應(yīng)的參數(shù)與電源管理器進(jìn)行交互,比如PPN_POWERCHANGE、PPN_SUSPENDKEYPRESSED、PPN_UNATTENDEDMODE等,參見"pmpolicy.h";直接訪問內(nèi)核對(duì)象:事件(Event)作為Windows CE系統(tǒng)的內(nèi)核對(duì)象,可以通過事件名稱在進(jìn)程間共享,因此我們可以訪問電源管理器中的兩個(gè)事件,它們的名字分別是_T("PowerManager/ReloadActivityTimeouts")、_T("PowerManager/SystemIdleTimerReset")。如果你的程序需要?jiǎng)討B(tài)修改那幾個(gè)計(jì)時(shí)器的時(shí)間長(zhǎng)度,可以通過第一個(gè)事件通知電源管理器重新讀取注冊(cè)表中計(jì)時(shí)器的值,而第二個(gè)事件與SystemIdleTimerReset功能一樣,可以阻止系統(tǒng)進(jìn)入睡眠狀態(tài)。3. Windows Mobile電源管理相關(guān)API的應(yīng)用最后,通過幾個(gè)應(yīng)用場(chǎng)景簡(jiǎn)單介紹一下常用的電源管理相關(guān)的API的使用:如果你在設(shè)計(jì)的是媒體播放器程序,不希望在播放電影時(shí),系統(tǒng)自動(dòng)轉(zhuǎn)入Suspend狀態(tài),這時(shí)可以每隔30秒調(diào)用一次SystemIdleTimerReset,它會(huì)幫你重置那個(gè)計(jì)時(shí)器;如果你還想同時(shí)保持背光,那么可以調(diào)用SetPowerRequirement(TEXT("BKL1:"), D0, POWER_NAME, NULL, 0);如果你提供一個(gè)按鈕允許用戶關(guān)閉屏幕,那么調(diào)用SetSystemPowerState(NULL, POWER_STATE_IDLE, 0);如果你在設(shè)計(jì)的是天氣預(yù)報(bào)程序,需要每天早上6點(diǎn)在線更新天氣信息,這時(shí)可以調(diào)用CeRunAppAtTime,系統(tǒng)到時(shí)會(huì)被RTC中斷喚醒,還記得前面提到的那個(gè)15秒的計(jì)時(shí)器嗎,這時(shí)你的程序應(yīng)該在15秒內(nèi)請(qǐng)求進(jìn)入U(xiǎn)nattended狀態(tài),否則系統(tǒng)將重新回到睡眠狀態(tài)。在處理更新的過程中,還是應(yīng)該每隔30秒調(diào)用一次SystemIdleTimerReset,在處理完更新后,應(yīng)該再次調(diào)用CeRunAppAtTime,并放棄Unattended狀態(tài)。請(qǐng)注意,在電源管理器的實(shí)現(xiàn)代碼中,用了一個(gè)引用計(jì)數(shù)的變量(gdwUnattendedModeRequests)統(tǒng)計(jì)所有對(duì)Unattended狀態(tài)的請(qǐng)求,所以PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);和PowerPolicyNotify(PPN_UNATTENDEDMODE, FALSE);要成對(duì)出現(xiàn),否則系統(tǒng)將無(wú)法回到睡眠狀態(tài)。如果你要開發(fā)一個(gè)監(jiān)控電池狀態(tài)的程序,首先應(yīng)該創(chuàng)建一個(gè)接收狀態(tài)通知的線程,在這個(gè)線程里調(diào)用RequestPowerNotifications,這個(gè)函數(shù)的第一個(gè)參數(shù)是一個(gè)消息隊(duì)列的句柄,所以必須先創(chuàng)建一個(gè)消息隊(duì)列(CreateMsgQueue),第二個(gè)參數(shù)是你希望得到的通知類型,這里要用到的是PBT_POWERSTATUSCHANGE|PBT_POWERINFOCHANGE,然后線程就可以等待通知了(WaitForSingleObject),一旦有通知到來(lái),線程通過ReadMsgQueue讀取消息的內(nèi)容,再做些更新UI的工作。
-
觸摸屏
+關(guān)注
關(guān)注
42文章
2387瀏覽量
118549 -
WINDOWS
+關(guān)注
關(guān)注
4文章
3614瀏覽量
91415 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3298瀏覽量
118955
發(fā)布評(píng)論請(qǐng)先 登錄
Windows CE操作系統(tǒng)的電源狀態(tài)轉(zhuǎn)換策略

嵌入式操作系統(tǒng)Windows CE研究
Windows Embedded 操作系統(tǒng)
基于Windows CE.Net操作系統(tǒng)的故障診斷專家系統(tǒng)
如何去設(shè)計(jì)嵌入式Windows CE多媒體操作系統(tǒng)的硬件平臺(tái)?
嵌入式操作系統(tǒng)Windows CE的研究
什么是Windows CE,LynxOS是什么操作系統(tǒng)
Windows CE的OAL層開發(fā)

Windows CENET操作系統(tǒng)的架構(gòu)
基于Windows CE的嵌入式操作系統(tǒng)實(shí)時(shí)性分析
Windows CE 電源管理解析
Windows CE操作系統(tǒng)在工業(yè)控制領(lǐng)域的應(yīng)用
基于S3C2410處理器對(duì)Windows CE 5.0操作系統(tǒng)實(shí)現(xiàn)BSP移植

基于Windows CE操作系統(tǒng)實(shí)現(xiàn)OAL層的功能和結(jié)構(gòu)應(yīng)用設(shè)計(jì)

Windows CE.net操作系統(tǒng)的內(nèi)核定制

評(píng)論