針對(duì)sep4020的linux低功耗研究也有一段時(shí)間了,基本把低功耗的實(shí)現(xiàn)方式想清楚了(主要分成機(jī)制和策略),這段時(shí)間的工作主要在機(jī)制上。暫時(shí)想實(shí)現(xiàn)的主要的機(jī)制有:cpu級(jí),設(shè)備驅(qū)動(dòng)級(jí),系統(tǒng)平臺(tái)級(jí)。管理顆粒度不斷遞增,形成三駕馬車齊驅(qū)的形勢(shì)。
cpu級(jí):主要實(shí)現(xiàn)比較容易的在系統(tǒng)處于目標(biāo)在于頻繁發(fā)生、更高粒度的電源狀態(tài)改變,主要的實(shí)現(xiàn)方式為idle,包括今天的主要想講的動(dòng)態(tài)主頻。
設(shè)備驅(qū)動(dòng)級(jí):主要實(shí)現(xiàn)對(duì)單個(gè)設(shè)備驅(qū)動(dòng)的管理(suspend,resume等),通過(guò)系統(tǒng)監(jiān)測(cè)將閑置的設(shè)備,通過(guò)從用戶態(tài)對(duì)sys文件目錄動(dòng)態(tài)進(jìn)行單個(gè)驅(qū)動(dòng)設(shè)備的管理
,置于省電模式。
系統(tǒng)平臺(tái)級(jí):目標(biāo)在于管理較大的、非常見的重大電源狀態(tài)改變,用于減少產(chǎn)品設(shè)備在長(zhǎng)時(shí)間的空閑之后,減少電源消耗。主要實(shí)現(xiàn)方式是依托l(wèi)inux內(nèi)核所支持的apm技術(shù),實(shí)現(xiàn)整個(gè)系統(tǒng)的睡眠/恢復(fù)(sleep)
這幾個(gè)層次其實(shí)并不是相互獨(dú)立的,都是相互交叉的,比如系統(tǒng)平臺(tái)級(jí)的睡眠不可避免會(huì)涉及到cpu的sleep模式和設(shè)備驅(qū)動(dòng)的掛起,而動(dòng)態(tài)主頻的實(shí)現(xiàn)除了cpu本身的支持也需要外圍驅(qū)動(dòng)隨著主頻變化做出相應(yīng)的適應(yīng)活動(dòng)。因此這里的分級(jí)只是一種粗范圍的,邏輯上的分層。
前段時(shí)間還調(diào)研了一下IBM和Monta Vista搞得那套DPM(Dynamic Power Management)機(jī)制,看了不少論文和觀點(diǎn),總的感覺就是太過(guò)復(fù)雜而且也不是很實(shí)用,感覺噱頭大過(guò)實(shí)際功效,(因此這套機(jī)制始終還不能進(jìn)入內(nèi)核的mainline),言歸正傳,還是重點(diǎn)講述下cpufreq技術(shù)。
1.為什么要cpufreq?
關(guān)于要不要實(shí)現(xiàn)cpufreq技術(shù),我也糾結(jié)過(guò),一個(gè)原因是:當(dāng)時(shí)對(duì)內(nèi)核如何提供這么一套動(dòng)態(tài)變頻的機(jī)制還不了解,只覺得應(yīng)該非常麻煩,因?yàn)樯婕暗酵鈬?qū)動(dòng)的參數(shù)更新,另外一個(gè)原因是:在SEP4020這種體量的處理器上跑linux,即使運(yùn)行在最高頻率時(shí)的處理能力可能也不是很富余,我再給它降頻還有沒(méi)有意義?掙扎之后還是覺得要實(shí)現(xiàn)它,我也給自己列了這么幾條原因:
n????? 雖然cpu在板級(jí)中已不是主要的耗電源,但是仍然占著舉足輕重的位置,功耗機(jī)制到最后就是幾毫安幾毫安的扣了,降頻肯定能在一定程序上節(jié)約功耗那我為什么不采用?
n????? 細(xì)化功耗管理的顆粒度,為應(yīng)用程序提供更多的功耗節(jié)省機(jī)制
n????? 對(duì)普通的應(yīng)用,系統(tǒng)可以運(yùn)行在維持平臺(tái)運(yùn)作的最低頻率,在有處理任務(wù)時(shí),變頻機(jī)制會(huì)自動(dòng)切換到合適的高主頻,并且在任務(wù)結(jié)束時(shí)重回省電的低主頻,這樣就解決了我之前的第二個(gè)疑惑。
?????????SEP4020在運(yùn)行在88M時(shí)板級(jí)功耗為:222mA
?????????SEP4020在運(yùn)行在56M時(shí)板級(jí)功耗為:190mA,降低14%
?????????SEP4020在運(yùn)行在32M時(shí)板級(jí)功耗為:160mA,降低28%
n????? 實(shí)現(xiàn)的一些工作是我們一直需要去做但是一直沒(méi)有動(dòng)力做的
???????? 變頻會(huì)涉及到大量模塊的參數(shù)的重新配置,作為cpu原廠,我們需要把這些參數(shù)徹底掌握
???????? 對(duì)這些參數(shù)的充分理解,能對(duì)現(xiàn)有系統(tǒng)進(jìn)行優(yōu)化,提升整體系統(tǒng)的效率,比如使用發(fā)現(xiàn)一些參數(shù)還是太過(guò)保守(sdram,nand),我們的通用配置在系統(tǒng)降為32M時(shí)仍能正常工作。
n????? 可行性論證沒(méi)有問(wèn)題:偶然看到armkiller同志提供的nand驅(qū)動(dòng)代碼中有變頻的實(shí)現(xiàn)(這里非常感謝armkiller),網(wǎng)上這方面的文章很少,于是翻閱了linux內(nèi)核源碼中自帶的/documentation/cpufreq后,對(duì)這種機(jī)制大概有一定的了解(linux中的documentation是個(gè)好東東),也看到了一些處理器廠商為自己的cpu已經(jīng)實(shí)現(xiàn)了的代碼,如sa1100,pxa系列。
2.?內(nèi)核所提供的這種cpufreq技術(shù)的機(jī)制
n????? 目的:
變頻技術(shù)是指CPU硬件本身支持在不同的頻率下運(yùn)行,系統(tǒng)在運(yùn)行過(guò)程中可以根據(jù)隨時(shí)可能發(fā)生變化的系統(tǒng)負(fù)載情況動(dòng)態(tài)在這些不同的運(yùn)行頻率之間進(jìn)行切換,從而達(dá)到對(duì)性能和功耗做到二者兼顧的目的。
n????? 來(lái)源:
雖然多個(gè)處理器生產(chǎn)廠家都提供了對(duì)變頻技術(shù)的支持,但是其硬件實(shí)現(xiàn)和使用方法必然存在著細(xì)微甚至巨大的差別。這就使得每個(gè)處理器生產(chǎn)廠家都需要按照其特殊的硬件實(shí)現(xiàn)和使用方法向內(nèi)核中添加代碼,從而讓自己產(chǎn)品中的變頻技術(shù)在Linux
中得到支持和使用。然而,這種內(nèi)核開發(fā)模式所導(dǎo)致的后果是各個(gè)廠家的實(shí)現(xiàn)代碼散落在?Linux
內(nèi)核代碼樹的各個(gè)角落里,各種不同的實(shí)現(xiàn)之間沒(méi)有任何代碼是共享的,這給內(nèi)核的維護(hù)以及將來(lái)添加對(duì)新的產(chǎn)品的支持都帶來(lái)了巨大的開銷,并直接導(dǎo)致了?cpufreq
內(nèi)核子系統(tǒng)的誕生。
n????? 管理策略:
Linux內(nèi)部共有五種對(duì)頻率的管理策略u(píng)serspace,conservative,ondemand,powersave
和?performance
??????????1.performance?:CPU會(huì)固定工作在其支持的最高運(yùn)行頻率上;
??????????2.powersave?:CPU會(huì)固定工作在其支持的最低運(yùn)行頻率上。因此這兩種?governors
都屬于靜態(tài)?governor?,即在使用它們時(shí)?CPU
的運(yùn)行頻率不會(huì)根據(jù)系統(tǒng)運(yùn)行時(shí)負(fù)載的變化動(dòng)態(tài)作出調(diào)整。這兩種?governors
對(duì)應(yīng)的是兩種極端的應(yīng)用場(chǎng)景,使用?performance governor
體現(xiàn)的是對(duì)系統(tǒng)高性能的最大追求,而使用?powersave governor
則是對(duì)系統(tǒng)低功耗的最大追求。
?????????3.Userspace:最早的?cpufreq
子系統(tǒng)通過(guò)?userspace governor?
為用戶提供了這種靈活性。系統(tǒng)將變頻策略的決策權(quán)交給了用戶態(tài)應(yīng)用程序,并提供了相應(yīng)的接口供用戶態(tài)應(yīng)用程序調(diào)節(jié)CPU
運(yùn)行頻率使用。(可以使用Dominik?等人開發(fā)了?cpufrequtils
工具包)
?????????4.ondemand?:userspace是內(nèi)核態(tài)的檢測(cè),效率低。而ondemand正是人們長(zhǎng)期以來(lái)希望看到的一個(gè)完全在內(nèi)核態(tài)下工作并且能夠以更加細(xì)粒度的時(shí)間間隔對(duì)系統(tǒng)負(fù)載情況進(jìn)行采樣分析的
governor。
?????????5.conservative?:?ondemand governor
的最初實(shí)現(xiàn)是在可選的頻率范圍內(nèi)調(diào)低至下一個(gè)可用頻率。這種降頻策略的主導(dǎo)思想是盡量減小對(duì)系統(tǒng)性能的負(fù)面影響,從而不會(huì)使得系統(tǒng)性能在短時(shí)間內(nèi)迅速降低以影響用戶體驗(yàn)。但是在?ondemand governor
的這種最初實(shí)現(xiàn)版本在社區(qū)發(fā)布后,大量用戶的使用結(jié)果表明這種擔(dān)心實(shí)際上是多余的,?ondemand governor
在降頻時(shí)對(duì)于目標(biāo)頻率的選擇完全可以更加激進(jìn)。因此最新的?ondemand governor
在降頻時(shí)會(huì)在所有可選頻率中一次性選擇出可以保證?CPU?
工作在?80%?以上負(fù)荷的頻率,當(dāng)然如果沒(méi)有任何一個(gè)可選頻率滿足要求的話則會(huì)選擇?CPU
支持的最低運(yùn)行頻率。大量用戶的測(cè)試結(jié)果表明這種新的算法可以在不影響系統(tǒng)性能的前提下做到更高效的節(jié)能。在算法改進(jìn)后,?ondemand governor
的名字并沒(méi)有改變,而?ondemand governor?
最初的實(shí)現(xiàn)也保存了下來(lái),并且由于其算法的保守性而得名?conservative
。
Ondemand降頻更加激進(jìn),conservative降頻比較緩慢保守,事實(shí)使用ondemand的效果也是比較好的。
n??????Cpufreq在用戶態(tài)所呈現(xiàn)的接口:
?????????cpuinfo_max_freq? cpuinfo_min_freq:分別給出了?CPU
硬件所支持的最高運(yùn)行頻率及最低運(yùn)行頻率,
?????????cpuinfo_cur_freq?則會(huì)從?CPU
硬件寄存器中讀取?CPU?當(dāng)前所處的運(yùn)行頻率。
?????????Governor在選擇合適的運(yùn)行頻率時(shí)只會(huì)在?scaling_max_freq
和?scaling_min_freq?所確定的頻率范圍內(nèi)進(jìn)行選擇
?????????scaling_cur_freq?返回的是?cpufreq
模塊緩存的?CPU?當(dāng)前運(yùn)行頻率,而不會(huì)對(duì)?CPU
硬件寄存器進(jìn)行檢查。
?????????scaling_available_governors
會(huì)告訴用戶當(dāng)前有哪些?governors?可供用戶使用
??????????scaling_driver?則會(huì)顯示該?CPU
所使用的變頻驅(qū)動(dòng)程序
?????????Scaling_governor?則會(huì)顯示當(dāng)前的管理策略,往這個(gè)上echo其他類型會(huì)有相應(yīng)的轉(zhuǎn)變。
?????????scaling_setspeed:需將governor類型切換為userspace,才會(huì)出現(xiàn),往這個(gè)文件echo數(shù)值,會(huì)切換主頻
以下是將governor切換為ondemand后生成的ondemand文件夾下出現(xiàn)的配置文件。(conservative就不說(shuō)了,不準(zhǔn)備使用)
?????????sampling_rate:當(dāng)前使用的采樣間隔,單位:微秒
?????????sampling_rate_min:允許使用的最短采樣間隔
?????????sampling_rate_max:允許使用的最長(zhǎng)采樣間隔
?????????up_threshold?:表明了系統(tǒng)負(fù)載超過(guò)什么百分比時(shí)?ondemand governor
會(huì)自動(dòng)提高?CPU?的運(yùn)行頻率
?????????ignore_nice_load:ignore_nice_load
文件可以設(shè)置為?0?或?1(0
是默認(rèn)設(shè)置)。當(dāng)這個(gè)參數(shù)設(shè)置為?1?時(shí),任何具有?“nice”
值的處理器不計(jì)入總處理器利用率。在設(shè)置為?0?時(shí),所有處理器都計(jì)入利用率。
?????????sampling_down_factor:
n????? 使用方法:
?????????cd sys/devices/system/cpu/cpu0/cpufreq/目錄
echo 32000 > scaling_min_freq?
設(shè)置最小工作頻率(khz,32000~88000)
//若想使用userspace策略
# echo userspace > scaling_governor切換工作方式為userspace
echo 64000 > scaling_setspeed??
設(shè)置成想要的工作頻率(khz)
//若想使用ondemand策略
# echo ondemand > scaling_governor切換工作方式為ondemand
3.如何實(shí)現(xiàn)?
首先需要干一些雜活,修改kconfig makefile把系統(tǒng)屏蔽的cpufreq打開,對(duì)于我們來(lái)說(shuō)主要的核心有兩部分:
系統(tǒng)相關(guān):主要有cpu,timer(變了頻率一定要更新系統(tǒng)timer,否則系統(tǒng)時(shí)間就不準(zhǔn)了),sdram等。
主要就是實(shí)現(xiàn)下面這個(gè)結(jié)構(gòu)體:
static struct cpufreq_driver sep4020_driver =
{
.flags????? = CPUFREQ_STICKY,
.verify???? = sep4020_verify_speed,
.target???? = sep4020_target,
.get???????? = sep4020_getspeed,
.init???????? = sep4020_cpu_init,
.name??????????? = "SEP4020 Freq",
};
代碼還是很簡(jiǎn)陋,很多細(xì)節(jié)都沒(méi)考慮,所以具體的暫時(shí)先不講了,大家可以先參考pxa和sa1100的實(shí)現(xiàn)。
然后就是收頻率影響的驅(qū)動(dòng):
簡(jiǎn)單的來(lái)說(shuō)就是:系統(tǒng)在變化cpu主頻的時(shí)候會(huì)調(diào)用cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);函數(shù),響掛載在這個(gè)cpu上所有的驅(qū)動(dòng)發(fā)出一個(gè)信號(hào),驅(qū)動(dòng)接收到這個(gè)信號(hào)則調(diào)用相應(yīng)的處理函數(shù)。
這里把串口部分的實(shí)現(xiàn)簡(jiǎn)化,如下:
#ifdef CONFIG_CPU_FREQ
static int sep4020_serial_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data)
{
//????? printk("in the serial cpufreq_transition ");
int pmcr_pre;
unsigned long cpu_clk,baud,baudh,baudl;
pmcr_pre = *(volatile unsigned long*)PMU_PMCR_V;
if(pmcr_pre > 0x4000)
cpu_clk = (pmcr_pre-0x4000)*8000000;
else
cpu_clk = (pmcr_pre)*4000000;
baud = cpu_clk/16/115200;??????
baudh = baud >>8;
baudl = baud&0xff;????
*(volatile unsigned char*)UART0_LCR_V |= (0x80);
*(volatile unsigned char*)UART0_DLBL_V?? = baudl;
*(volatile unsigned char*)UART0_DLBH_V?? = baudh;
*(volatile unsigned char*)UART0_LCR_V &= ~(0x80);
printk("in the serial cpufreq_transition ");
return 0;
}
static inline int sep4020_serial_cpufreq_register(void)
{
sep4020_serial_freq_transition.notifier_call = sep4020_serial_cpufreq_transition;
return cpufreq_register_notifier(&sep4020_serial_freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
}
static inline void sep4020_serial_cpufreq_deregister(void)
{
cpufreq_unregister_notifier(&sep4020_serial_freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
}
#else
#endif
4.效果
在sys下開啟ondeman模式,串上電流表:
1.??????板級(jí)電流從220mA調(diào)至160mA(因?yàn)榇藭r(shí)內(nèi)核檢測(cè)系統(tǒng)無(wú)負(fù)載,降頻)
2.??????執(zhí)行一個(gè)nandflash的拷貝命令,拷貝一個(gè)5M左右的文件到其他文件夾,
3.??????在拷貝執(zhí)行時(shí)間在3秒時(shí)(我給內(nèi)核設(shè)的掃描周期為2.5秒)系統(tǒng)發(fā)現(xiàn)有負(fù)載,升頻,電流從160mA變?yōu)?20mA(可見已是系統(tǒng)最高主頻)
4.??????此后的拷貝的整個(gè)過(guò)程中電流保持為220mA
5.??????在拷貝結(jié)束后不久(2-3s內(nèi)),系統(tǒng)電流又跳變至160mA。
?
評(píng)論
查看更多