admin管理员组

文章数量:1658608

3.管理策略:

Linux内部共有五种对频率的管理策略userspace,conservative,ondemand,powersave和performance

performance:CPU会固定工作在其支持的最高运行频率上;

powersave:CPU会固定工作在其支持的最低运行频率上。因此这两种governors都属于静态governor,即在使用它们时CPU的运行频率不会根据系统运行时负载的变化动态作出调整。这两种governors对应的是两种极端的应用场景,使用performance governor体现的是对系统高性能的最大追求,而使用powersave governor则是对系统低功耗的最大追求。

Userspace:最早的cpufreq子系统通过userspace governor为用户提供了这种灵活性。系统将变频策略的决策权交给了用户态应用程序,并提供了相应的接口供用户态应用程序调节CPU运行频率使用。(可以使用Dominik等人开发了cpufrequtils工具包)

ondemand:userspace是内核态的检测,效率低。而ondemand正是人们长期以来希望看到的一个完全在内核态下工作并且能够以更加细粒度的时间间隔对系统负载情况进行采样分析的governor。

conservative:ondemand governor的最初实现是在可选的频率范围内调低至下一个可用频率。这种降频策略的主导思想是尽量减小对系统性能的负面影响,从而不会使得系统性能在短时间内迅速降低以影响用户体验。但是在ondemand governor的这种最初实现版本在社区发布后,大量用户的使用结果表明这种担心实际上是多余的,ondemand governor在降频时对于目标频率的选择完全可以更加激进。因此最新的ondemand governor在降频时会在所有可选频率中一次性选择出可以保证CPU工作在80%以上负荷的频率,当然如果没有任何一个可选频率满足要求的话则会选择CPU支持的最低运行频率。大量用户的测试结果表明这种新的算法可以在不影响系统性能的前提下做到更高效的节能。在算法改进后,ondemand governor的名字并没有改变,而ondemand governor最初的实现也保存了下来,并且由于其算法的保守性而得名conservative。

Ondemand降频更加激进,conservative降频比较缓慢保守,事实使用ondemand的效果也是比较好的。

4.Cpufreq在用户态所呈现的接口:

cpuinfo_max_freqcpuinfo_min_freq:分别给出了CPU硬件所支持的最高运行频率及最低运行频率,

cpuinfo_cur_freq则会从CPU硬件寄存器中读取CPU当前所处的运行频率。

Governor在选择合适的运行频率时只会在scaling_max_freq和scaling_min_freq所确定的频率范围内进行选择

scaling_cur_freq返回的是cpufreq模块缓存的CPU当前运行频率,而不会对CPU硬件寄存器进行检查。

scaling_available_governors会告诉用户当前有哪些governors可供用户使用

scaling_driver则会显示该CPU所使用的变频驱动程序

Scaling_governor则会显示当前的管理策略,往这个上echo其他类型会有相应的转变。

scaling_setspeed:需将governor类型切换为userspace,才会出现,往这个文件echo数值,会切换主频

以下是将governor切换为ondemand后生成的ondemand文件夹下出现的配置文件。(conservative就不说了,不准备使用)

sampling_rate:当前使用的采样间隔,单位:微秒

sampling_rate_min:允许使用的最短采样间隔

sampling_rate_max:允许使用的最长采样间隔

up_threshold:表明了系统负载超过什么百分比时ondemand governor会自动提高CPU的运行频率

ignore_nice_load:ignore_nice_load文件可以设置为0或1(0是默认设置)。当这个参数设置为1时,任何具有“nice”值的处理器不计入总处理器利用率。在设置为0时,所有处理器都计入利用率。

sampling_down_factor:

5.使用方法:

cd sys/devices/system/cpu/cpu0/cpufreq/目录

echo 32000 > scaling_min_freq设置最小工作频率(khz,32000~88000)

//若想使用userspace策略

# echo userspace > scaling_governor切换工作方式为userspace

echo 64000 > scaling_setspeed设置成想要的工作频率(khz)

//若想使用ondemand策略

# echo ondemand > scaling_governor切换工作方式为ondemand

三、如何实现?

首先需要干一些杂活,修改kconfig makefile把系统屏蔽的cpufreq打开,对于我们来说主要的核心有两部分:

系统相关:主要有cpu,timer(变了频率一定要更新系统timer,否则系统时间就不准了),sdram等。

主要就是实现下面这个结构体:

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",

};

代码还是很简陋,很多细节都没考虑,所以具体的暂时先不讲了,大家可以先参考pxa和sa1100的实现。

然后就是收频率影响的驱动:

简单的来说就是:系统在变化cpu主频的时候会调用cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);函数,响挂载在这个cpu上所有的驱动发出一个信号,驱动接收到这个信号则调用相应的处理函数。

这里把串口部分的实现简化,如下:

#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\n");

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\n");

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

四、效果

在sys下开启ondeman模式,串上电流表:

1.板级电流从220mA调至160mA(因为此时内核检测系统无负载,降频)

2.执行一个nandflash的拷贝命令,拷贝一个5M左右的文件到其他文件夹,

3.在拷贝执行时间在3秒时(我给内核设的扫描周期为2.5秒)系统发现有负载,升频,电流从160mA变为220mA(可见已是系统最高主频)

4.此后的拷贝的整个过程中电流保持为220mA

5.在拷贝结束后不久(2-3s内),系统电流又跳变至160mA。

本文标签: 内核电流电压机制Linux