Linux電源管理研究筆記 動態電源管理 DPM
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
Linux電源管理研究筆記—動態電源管理(DPM)
轉載時請註明出處和作者聯絡方式:http://blog.csdn.net/absurd
作者聯絡方式:Li XianJing <xianjimli at hotmail dot com>
在手持裝置設計中,電源管理歷來為重要的研究課題之一。我們日常所說的省電就屬於電源管理的範疇,這也是我們最關心的一個部分。通過掛起不必要的裝置、降低CPU的頻率或者其它方法,可以減少能量的消耗,達到省電的目的。電源管理實際上是一個系統工程,從應用程式到核心框架,再到裝置驅動和硬體裝置,都要參與進來,才能達到電源管理的最優化。本文介紹一下動態電源管理(DPM)。
所謂的動態電源管理(DPM)是一種電源管理機制,它允許在系統執行時動態的管理電源,這可能是相對於傳統的電源管理方式而言的,傳統的電源管理方式要求系統要麼掛起(
動態電源管理(DPM)是很一個廣泛的概念,很多系統實際上都採用了動態電源管理(DPM)方式,本文要談的是Linux下的動態電源管理(DPM)。Linux很早就採用了動態電源管理,在driver
不過cpufreq似乎不能用於嵌入式環境,主要原因是:在嵌入式系統中,與LCD顯示屏等外設相比,CPU已經不是能源消耗的大戶了,光調整CPU的頻率用處不大。而且cpufreq還依賴於像ACPI等PC環境,而嵌入式裝置一般都沒有BIOS,電源管理功能只能完全由作業系統實現。cpufreq的實現目前還不太清楚,我們會在後續的文章中繼續研究。
就目前掌握的資料來看,用嵌入式Linux系統的動態電源管理只有IBM奧斯汀實驗室和MontaVista聯合開發的動態電源管理(DPM)(http://dynamicpower.sourceforge.net/)。我們將對它的架構做簡要分析,下面提到動態電源管理(DPM)實際上是特指這個解決方案及其實現。
我們先介紹幾個重要概念:
1. operating point: 它實際上就是電源管理的一組配置資料,這組配置資料一旦確定,能源消耗率和系統性能也就確定了。比如:
上圖有三個operating point,第一個operating point的名稱為”33/33”,它的配置為:Core Voltage=1.0v、PLL VCO = 800MHz等如表格第二列裡的資料所示。
2. operating state: 它實際上就是系統的執行狀態,比如工作狀態和空閒狀態。不過在dynamicpower中,狀態可以有很多種。同是工作狀態,有高效能工作狀態、中等效能工作狀態和低效能工作狀態等,甚至更多,根據具體的情況而定。
3. policy: 它是電源管理的一個高階抽象。它負責把operating state對映到一個或者一組(class) operating point上。系統中可以有多個policy,但只一個policy處理啟用狀態。
4. class: 代表一組operating point,在狀態切換時,policy選取其中第一個滿足約束條件的operating point作為有效operating point。
5. constraint:它指裝置的約束條件,即只有在滿足約束條件下,裝置才能正常工作,比如LCD要一定匯流排頻率才能正常更新螢幕。在狀態切換時,如果下一狀態對應的operating point不滿足裝置的約束條件,有兩種選擇:要麼強制關閉裝置,要麼狀態切換失敗,根據設定而定。
dynamicpower可以認為是一種典型的按照機制與策略分開的模式設計的,它只實現了動態電源管理這種機制,而所有策略完全由使用者空間的應用程式去做實現。總的來說它分為三個層次:
1. API函式庫。這一部分主要是對核心提供的sysfs和proc檔案進行封裝,提供更好用的介面函式。它提供的函式如下:
int dpm_init(void); int dpm_terminate(void); int dpm_set_state(char *statename); int dpm_create_op(char *name, char *params); int dpm_set_op_param(char *op, char *param, int value); int dpm_get_op_param(char *opname, char *param, char *buf, size_t bufsiz); int dpm_create_class(char *name, char *params); int dpm_create_policy(char *name, char *params); int dpm_set_policy_state_map(char *policy, char *state, char *opclass); int dpm_get_policy_state_map(char *policy, char *state, char *buf, size_t bufsiz); int dpm_get_active_policy(char *name, size_t namemax); int dpm_set_active_policy(char *policy);
|
如果明白了policy、operating state和operating point等基本概念,上述函式不難理解:首先要建立一些operating point,即各種電源管理配置; 然後把這些operating point組合成class,接下來在operating state和class/operating point之間建立對映關係,這是初始化過程要做的。在系統執行過程中,dpm會自動選擇適當的模式,如果有多種policy,應用程式也可以啟用適當的policy。
2. 核心框架程式碼。它的主要功能包括對policy的管理,各種狀態的切換等平臺無關的操作,同時還提供了一些sysfs和proc檔案用來和使用者空間的應用程式互動。它一部分的程式碼主要分佈在下列檔案中:
drivers/base/core.c drivers/base/power/Makefile drivers/base/power/power-dpm.c drivers/base/power/resume.c drivers/base/power/suspend.c drivers/base/power/sysfs.c drivers/dpm/Kconfig drivers/dpm/Makefile drivers/dpm/dpm-idle.c drivers/dpm/dpm-ui.c drivers/dpm/dpm.c drivers/dpm/proc.c fs/proc/base.c include/linux/device.h include/linux/dpm-trace.h include/linux/dpm.h include/linux/init_task.h include/linux/pm.h include/linux/sched.h kernel/sched.c kernel/softirq.c kernel/workqueue.c |
其中drivers/dpm/dpm.c和dpm-idle.c是核心程式碼,dpm-ui.c和proc.c主要是用於與使用者空間應用程式互動的,其它程式碼則是用於與系統其它部分協調工作的。這一層程式碼不算太複雜,其中最重要的部分是狀態切換,其主要過程如下:
dpm_set_os: 切換到新狀態執行。 dpm_enter_state:把dpm_active_state置為新狀態。 dpm_resync:讓新狀態生效。 dpm_choose_opt:找到適當的operating point。 1.對於單個operating point:滿足裝置的約束(constraint)條件嗎?滿足則OK,否則再判斷是否要強制切換。如果是則OK,否則切換失敗。 2.對於一組operating point(class): 從列表中找到第一個滿足約束條件的operating point,找到了則OK。否則切換失敗。 dpm_set_opt: 讓operating point生效。 dpm_md.set_opt: 呼叫依賴於具體平臺的函式設定新的operating point。 |
3. 平臺相關程式碼。為了讓operating point真正生效,通常要修改某些特定的暫存器,這是平臺相關的。比如,在PXA27x上,要修改CCSR、CCCR和CLKCFG等暫存器。這一層要求實現下面幾個介面函式:
struct dpm_md { int (*init_opt)(struct dpm_opt *opt); int (*set_opt)(struct dpm_opt *cur, struct dpm_opt *new); int (*get_opt)(struct dpm_opt *opt); int (*check_constraint)(struct constraint_param *param, struct dpm_opt *opt); void (*idle)(void); void (*startup)(void); void (*cleanup)(void); }; |
要了解這一層的程式碼,先要熟讀平臺datasheet相關的章節,這裡不再多說。
~~end~~