動態電源管理(DPM)是很一個廣泛的概念,很多系統實際上都采用了動態電源管理(DPM)方式。Linux很早就采用了動態電源管理,在driver目錄下有個cpufreq的驅動程序,它就是用來動態調整CPU頻率以降低能源消耗的。[1] 注:引文中說的不全對,cpufreq在平板中有采用,並不是不適用與嵌入式系統。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
static struct cpufreq_frequency_table XXX_freq_table[] = {
{ 0, 66000 },
{ 0, 133000 },
{ 1, 222000 },
{ 1, 266000 },
{ 2, 333000 },
{ 2, 400000 },
{ 2, 532000 },
{ 2, 533000 },
{ 3, 667000 },
{ 0, CPUFREQ_TABLE_END },
};//此定義對應s3c64xx_freq_table
int XXX_cpufreq_verify_speed(struct cpufreq_policy *policy)
{
cpufreq_frequency_table_verify(policy,XXX_freq_table);
}
int XXX_cpufreq_init(struct cpufreq_policy *policy)
{
//檢查XXX_freq_table的合法性或者根據配置生成XXX_freq_table,動態創建的話需要調用cpufreq_frequency_table_cpuinfo
//獲取當前的頻率賦給policy->cur
//初始化policy->cpuinfo.transition_latency
//調用cpufreq_frequency_table_get_attr
}
unsigned int XXX_getspeed(unsigned int cpu)
{
//獲取當前的頻率值
}
int XXX_target(struct cpufreq_policy *policy, unsigned target, unsigned relation)
{
//根據relation的值,重新計算合適的頻率
switch (relation) {
case CPUFREQ_RELATION_L:
/* Try to select a new_freq higher than or equal target_freq */
dvfs_tbl = find_freq_ceil(target_freq);
break;
case CPUFREQ_RELATION_H:
/* Try to select a new_freq lower than or equal target_freq */
dvfs_tbl = find_freq_floor(target_freq);
break;
default:
dvfs_tbl = NULL;
break;
}
//重新調整頻率【通知所有注冊的notifier,並且調整時鍾滴答jiffies】
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
//調整時鍾鎖相環的參數
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
}
struct cpufreq_driver XXX_cpufreq_driver
{
......
.verify = XXX_cpufreq_verify_speed;
.target = ;
.get = XXX_getspeed;
.init = XXX_cpufreq_init;
.exit = ;
.attr = ;
}
static int __init XXX_cpufreq_init( void )
{
cpufreq_register_driver(&XXX_cpufreq_driver);
}
module_init(XXX_cpufreq_init)
如果驅動需要響應cpu頻率調整的消息,需要在驅動中調用如下函數注冊notifier
cpufreq_register_notifier
參考文獻