Wince電源管理(四) ---- Windows CE設備驅動開發之電源管理

Windows CE設備驅動開發之電源管理 第四部分


4.7.4、設備電源管理指南

電源管理器對設備功耗、性能及響應時間並沒有進行嚴格的限制。只是在用戶角度而言D0及D1狀態下是可操作的,而更高編號的電源狀態比D0及D1消耗更少的電源。

本指南的目的是爲了使OEM廠商能更容易的定義有意義的系統電源狀態,而不用瞭解特定設備的詳細功耗要求。

4.7.4.1              設備電源自管理(Device Power Self-Management

一些設備自行管理其電源的過程可能比較複雜。當設備處於休止狀態時,驅動程序開發人員希望能降低它們的功耗。降低功耗一般會同時降低設備性能,所以當這些設備被使用時,也需要提升其性能等級。提升性能的同時也會增大設備功耗。

這些設備往往根據其被使用頻繁程度來動態的提升或降低其設備電源狀態。但電壓自管理的實際算法根據設備特性的不同而不同。

電源管理器的DevicePowerNotify API函數允許驅動開發人員請求電源管理器調整設備的電源狀態。如果所請求的設備電源狀態在允許的範圍內(即最大及最小值之間),電源管理器將允許對設備電源狀態的調整。最大值爲系統電源狀態要求的值,最小值由應用程序調用SetPowerRequirement API設定。

如果電源管理器設備請求的電源狀態調整,電源管理器將調用對應的設備API更新設備電源狀態,如:使用設備的IOCTL_POWER_SET函數。在調用DevicePowerNotify函數時,需要遵循以下要求:

l         當DevicePowerNotify調用成功後設備不能立即更新其電源狀態,直到IOCTL_POWER_SET被引發時才能更新。

l         驅動開發人員不能認爲DevicePowerNotify調用成功就意味着電源管理器一定會引發IOCTL_POWER_SET。

l         驅動開發人員不能認爲IOCTL_POWER_SET會被作爲DevicePowerNotify調用的結果而被立即引發。

l         當能夠喚醒系統的設備進入D3狀態後,不應再使用DevicePowerNotify來請求D3狀態。

一些設備能夠支持D0到D4設備電源狀態以外的其他電源等級。如果需要,驅動開發人員可以將此類設備的多個電源等級映射到電源管理器所能識別的某一設備電源狀態。設備可以不依賴電源管理器在每個設備電源狀態的允許範圍內自由的進行電源自管理。但是,設備仍然需要使用DevicePowerNotify進行設備電源狀態切換。

自管理示例

對於一個實現了所有五種電源狀態的設備,如果在一定的時間週期內無活動,需要動態的從D0降到D1狀態,或從D1降到D2狀態。這是因爲D2狀態的耗電量更少,而且設備很少需要響應。如果設備發覺需要活動,但其不在D0狀態,設備將嘗試進入D0狀態。

這樣一個設備的中斷服務線程可能與下面的示例代碼類似。

while(!fDone) {

    dwStatus = WaitForSingleObject(hInterruptEvent, dwTimeout);

    switch(dwStatus) {

    case WAIT_OBJECT_0: // device activity

        // service device

        ...

        if(deviceDx != D0 && !fBoostRequested) {

            fBoostRequested = TRUE;

            DevicePowerNotify(pszDeviceName, D0, POWER_DRIVER | POWER_NAME);

 

        }

        dwTimeout = INACTIVITY_TIMEOUT;

        break;

    case WAIT_TIMEOUT:  // device inactive

        if(deviceDx < D2 && !fReductionRequested) {

            fReductionRequested = TRUE;

            DevicePowerNotify(pszDeviceName, deviceDx + 1, POWER_DRIVER | POWER_NAME);

 

        }

        if(deviceDx >= D2) {

            dwTimeout = INFINITE;

        }

    default:            // error handling

        break;

    }

}

設備的DeviceIoControl處理程序可能包含下列示例代碼。

case IOCTL_POWER_SET:

    // update device registers

    ...

    deviceDx = *(PCEDEVICE_POWER_STATE) pOutBuf;

    fBoostRequested = FALSE;

    fReductionRequested = FALSE;

    break;

上面驅動程序代碼僅表明了是否請求了狀態切換,而不是是否已經切換。這一點非常重要,因爲設備可能在D2狀態時請求進入D0狀態,但是由於當前的電源情況,電源管理器可能僅將其設爲D1狀態。在下一次設備活動時,設備會再次請求進入D0狀態,而電源管理器可能只允許其運行在D1狀態。明白了狀態切換請求的過程,能夠避免在設備進入活動狀態前進行額外的電源管理API調用。同樣的處理邏輯也用於當設備非活動超時時電源狀態降低的過程。

設備的中斷服務程序在調用DevicePowerNotify函數前設置fBoostRequested和fReductionRequested標記。這是因爲DevicePowerNotify調用可能導致調用IOCTL_POWER_SET而在同一線程中再次進入驅動程序。DeviceIoControl調用會清除標記,從而使驅動程序在之後能進一步調整設備電源狀態。

4.7.4.2              如何爲驅動程序添加電源管理(How to Add Power Management to a Device Driver

開發者可以爲驅動程序添加電源管理支持,以便能夠降低目標設備的功耗。爲此,驅動程序必須導出流接口。如果已經實現了流接口,那麼可以開始添加電源管理支持。

硬件及軟件假定

你掌握瞭如何從命令行創建WinCE運行時鏡像。詳見Build Tool

4.7.4.3              電源可管理設備驅動(Power-Manageable Device Drivers

爲了創建一個支持電源管理的設備驅動程序,必須先定義一個non-COM-related設備接口。non-COM-related設備接口表示設備支持電源管理。可以使用以下方式定義這一設備接口:

l         可以在用於激活設備的註冊表鍵的IClass值中定義接口。

l         可以使用驅動程序的Init函數在活動註冊表中定義IClass值。

l         可以調用ActivateDeviceEx函數並使用REGINI參數來定義IClass值。

l         可以在驅動程序中顯式的調用AdvertiseInterface。

關於爲電源管理定義non-COM-related接口的更多信息,參見設備接口通知。可以通過調用RequestPowerNotifications函數爲電源管理通知註冊設備驅動程序,同時將句柄傳遞給電源管理通知專用的消息隊列。如果驅動程序需要響應電源通知並進行相關處理,就必須這麼做。通常情況下,一旦驅動程序實現了電源管理支持,那麼此驅動只需要處理電源管理器的DeviceIoControl調用。

電源管理器通過IOCTL碼與設備通訊。下表列出了電源管理器與設備通訊時使用的IOCTL碼:

你可以實現並使用可選的IOCTL_POWER_QUERY控制碼,以便在驅動程序還沒有準備好改變電源狀態時,延遲電源切換。你可以通過修改MDD層來支持IOCTL_POWER_QUERY,雖然這樣修改可能會導致MDD層與電源管理器的未來版本不兼容。

4.7.4.4              在驅動程序中實現電源管理(Power Management Implementation in Drivers

在配置驅動程序支持電源管理時,要確定驅動程序每個入口點的電源狀態。如果確定電源狀態正確無誤,那麼驅動程序會根據目標設備的當前電源狀態以適當的方式運行。

確保在XXX_PowerUp被調用時驅動程序不會給目標設備加電。而應該恢復電源管理器設置的電源狀態,很可能是D3或D4這樣的狀態值。同樣,在XXX_PowerDown被調用時不會關閉目標設備電源。

注意:如果在掛起前目標設備一直沒有加電,電源管理器也沒有向其發送請求。這種情況下,驅動程序沒有正確配置,所以要在驅動程序中重新配置。

4.7.4.5              在流接口驅動中實現電源管理(Power Management Implementation in Stream Interface Drivers

在驅動程序能夠支持電源管理之前,必須先導出一個流接口。導出的流接口會提供一組入口點以便實現標準文件I/O函數,這些函數會被kernel使用。

關於導出流接口的更多信息,見流接口驅動實現(Stream Interface Driver Implementation)。

除流接口函數外,驅動程序還必須支持IOCTL_POWER_CAPABILITIES和IOCTL_POWER_SET這兩個IOCTL。

關於IOCTL_POWER_SET的更多信息,見IOCTL_POWER_SET請求處理(IOCTL_POWER_SET Request Processing)。

關於IOCTL_POWER_CAPABILITIE的更多信息,見設備電源特性(Device Power Capabilities)。

一旦配置了流接口,就可以進一步配置驅動程序來支持電源管理。更多信息參見 4.4在驅動程序中實現電源管理。

4.7.4.6              設備類型名(Class-Qualified Device Names

自Windows CE .NET 4.10起,支持電源管理的設備可分屬於不同的設備類型。這些設備類型由預定義類型和自定義類型組成。電源管理器API函數可以接受設備名稱,也可以接受有效地設備類型名稱(class-qualified device names)。例如,下面列出的每一名稱都是有效的設備名稱:

l         COM1:

l         {A32942B7-920C-486b-B0E6-92A702A99B35}/COM1:

l         {98C5250D-C29A-4985-AE5F-AFE5367E5006}/CISCO1

l         {8DD679CE-8AB4-43c8-A14A-EA4963FAA715}/DSK1:

如果某個設備的類型無效,那麼此設備將被假定屬於默認設備類型。例如,上面COM1:和{A32942B7-920C-486b-B0E6-92A702A99B35}/COM1:是等效的。

4.7.4.7              設備初始化(Device Initialization Responsibilities

在初始化期間,設備驅動程序應將設備置爲D0狀態,同時在電源管理器通過IOCTL_POWER_CAPABILITIES詢問時應儘可能準確的彙報設備特性。

4.7.4.8              IOCTL_POWER_SET請求處理(IOCTL_POWER_SET Request Processing

電源管理器使用IOCTL_POWER_SET(設備的IOCTL碼)來調整設備的電源狀態。在實現此IOCTL碼時,驅動程序開發人員應瞭解下列內容:

l         設備並不一定需要支持所有五種設備電源狀態,但至少必須支持D0狀態;如果設備僅支持D0狀態,那麼它也不需要處理IOCTL_POWER_SET。

l         電源管理器可能會要求設備進入任何設備電源狀態,並不僅僅是設備聲明支持的幾個。

l         如果一個設備被要求進入一個它並不支持的電源狀態,它就會進入另一個它支持的更高功耗的狀態。例如,一個設備並不支持D2,它會被要求進入D1。

l         電源管理器可能會通過發出IOCTL_POWER_SET,使設備再次進入它已經處於的當前狀態。在這種情況下,設備驅動程序簡單的返回成功即可。

l         設備的電源狀態不一定與系統的電源狀態同步,因爲它可能受到應用程序需求的限制。

 

4.7.4.9              掛起及恢復處理(Suspend and Resume Handling

 

支持電源管理的流設備驅動程序通過XXX_PowerDown及XXX_PowerUp不斷接收系統掛起/恢復狀態通知。這些通知在內核調用OEMPowerOff之前的中斷處理中發出。PowerDown/PowerUp回調機制與電源管理器無關,----。

Power managed stream device drivers will continue to receive notifications of system suspend and resume states through their XXX_PowerDown (Device Manager) and XXX_PowerUp (Device Manager). These notifications are sent in an interrupt context just before the kernel calls OEMPowerOff. The PowerDown/PowerUp callback mechanism is independent of the Power Manager and allows legacy device drivers to function under Microsoft® Windows® CE .NET 4.0 and later.

驅動開發人員應該知道,當系統進入掛起狀態,處理器將不再運行。理論上,電源管理器會根據電源狀態映射,使設備進入對應的設備電源狀態。然而,掛起系統電源狀態或應用程序的設備電源需求可能不適合某些設備。例如,多媒體應用程序可能要求音頻設備保持運行在D0狀態。如果音頻芯片需要頻繁使用處理器設置DMA緩存,驅動開發人員可判定此設備在系統掛起狀態不適合運行於D0狀態,並關閉設備電源。

驅動開發者必須知道在系統處於掛起狀態時設備適合使用哪些電源狀態,從而依此實現其驅動程序。這一方法適合保守的驅動開發人員在系統掛起期間進行電源管理決策。但是,在系統掛起時並不是所有的設備都必須被關閉。例如,如果音頻設備可以不依賴處理器播放音樂,那麼它可以在系統掛起期間保持供電。

如果驅動開發人員在掛起期間改變了設備的電源狀態,就必須在系統恢復的同時恢復設備的電源狀態。在系統掛起期間,這些設備應儘量保證其實際行爲對電源管理器而言是透明的。

當支持電源管理的流設備通過ActivateDeviceEx被加載時,可以自動通知電源管理器。在註冊表HKEY_LOCAL_MACHINE/CurrentControlSet/Control/Power/Interfaces鍵值下的所有設備在加載時都需要通知電源管理器。如果這些設備的註冊表IClass鍵值(REG_MULTI_SZ類型)中包含類似"{A32942B7-920C-486b-B0E6-92A702A99B35}"的GUID,那麼在其被加載時電源管理器會收到通知。

設備在收到IOCTL_POWER_CAPABILITIES控制碼後,可以通過調用DevicePowerNotify函數管理其自身電源。在設備處理IOCTL期間,電源管理器允許設備自行管理電源。

如果OEM廠商選擇實現非流接口的設備API,就需要定製電源管理器,使其使用新的機制與設備通訊。

 

4.7.4.10          D3設備狀態和系統喚醒(Device State D3 and System Wakeup

D3設備電源狀態需要特殊考慮,因爲它並不是僅僅用於限定設備的功耗等級。設備可以運行與D3狀態,從而在掛起狀態時喚醒系統,但者並不是必須的。

下列指南說明了如何在驅動程序中添加D3狀態支持:

l         可以從掛起狀態喚醒系統的設備不應通過DevicePowerNotify請求進入D3狀態。這是因爲在系統進入掛起狀態前,不應存在喚醒源。----。

Devices that can wake the system from a suspend state should not request the D3 state through DevicePowerNotify. This is because enabling a device as a wake source is not always appropriate, unless the system is going to enter a suspend state. The driver cannot distinguish IOCTL_POWER_SET requests for D3 that it has initiated itself from those initiated by the Power Manager as part of a system power state transition.

l         可以將支持喚醒的設備的D2與D3狀態定義爲相同的電壓等級,當然D2狀態不支持喚醒功能。

l         不能從掛起狀態喚醒系統,但是具有一個能保持設備運行最低功耗模式的設備,在電源自管理過程中可以使用D3狀態。

l         如果一個非喚醒源設備運行在D3狀態,並且系統掛起,那麼它應在XXX_PowerDown處理過程切換到D4狀態;同時在XXX_PowerUp處理中恢復到D3狀態。如果做不到,就不能支持D3狀態,而應在請求進入D3狀態時直接切換到D4狀態。

l         上述指南隱含說明了支持D3狀態的設備不一定能在掛起狀態喚醒系統。

總之,OEM廠商設計系統電源狀態時,應用程序開發者調用SetPowerRequirement時都需要考慮系統掛起期間D3狀態的特殊性。上述指南同時描述了OEM廠商和應用程序開發者可以在掛起期間要求設備進入D3狀態,而不用考慮設備是否支持喚醒功能。

 

4.7.4.11          設備電源特性(Device Power Capabilities

IOCTL_POWER_CAPABILITIES在即插即用設備枚舉時從驅動程序中查詢設備的具體特性,包括潛伏週期(latency)、功耗、系統喚醒及啓動功率(Inrush)。在驅動程序響應此IOCTL時也同時彙報他所支持的設備電源狀態。電源管理器一般不會要求設備進入它所不支持的電源狀態。但是,驅動開發人員不能認爲這種情況不會產生。因爲設備製造商可以定製電源管理器,設備製造商可能會忽略POWER_CAPABILITIES結構的DeviceDx字段。


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Fenstein/archive/2009/01/10/3746375.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章