Linux内核中CPU主频和电压调整 -- (2)
2014-02-12 18:04
399 查看
从文章 Linux内核中CPU主频和电压调整 -- (1) 中已经知道,在目录/sys/devices/system/cpu/cpu0/cpufreq/下可以设置cpu0的频率及其相关的信息。
于是我参考开源程序osdcpufreq,进一步做了修改,该开源程序的下载地址为http://sourceforge.net/projects/osdcpufreq/files/osdcpufreq/osdcpufreq-0.3/
主要膝盖的内容包括两点:
(1)将xosd图形显示的程序屏蔽掉了,在Ubuntu12.04系统下不知道为什么,装不上xosd
(2)可以采用命令行的形式,输入频率值等信息,从而更新/sys/devices/system/cpu/cpu0/cpufreq/下的值
详细的程序如下:
1,获取cpu信息,注意格式化的操作
void get_cpu_info(cpufreq_info_struct *cpufreq_info, char cpu_num) {
char file[54];
FILE *fp;
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpu_num);
fp = fopen (file, "r");
if (fp == NULL ) {
printf("Error reading scaling_cur_freq file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
fscanf (fp,"%i",&(cpufreq_info->cur_freq));
printf("scaling_cur_freq = %d\n", cpufreq_info->cur_freq);
fclose (fp);
}
2,设置cpu信息,本人添加的程序,修改了scaling_governor(模式)和scaling_setspeed(频率)的值
//set cpu infomation
void set_cpu_info(cpufreq_info_struct *cpufreq_info, char cpu_num)
{
char file[54];
FILE *fp;
char str[20];
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu_num);
fp = fopen (file, "w");
if (fp == NULL ) {
printf("Error reading scaling_governor file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
fprintf(fp,"%s",cpufreq_info->governor);
fclose (fp);
}
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpu_num);
fp = fopen (file, "w");
if (fp == NULL ) {
printf("Error reading scaling_setspeed file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
sprintf(str,"%d",cpufreq_info->set_speed);
fprintf(fp,"%s",str);
fclose (fp);
}
printf("exit set_cpu_info\n");
}
3,获取conf文件里面的初始化参数
void configure(config_struct *config) {
char line[256];
char value[64];
char *the_home;
char config_file[48];
int chars_number, i;
FILE *fp;
/* getting user home directory */
the_home =getenv("HOME");
sprintf(config_file, "%s/%s",the_home,FILE_CONF);
/* Load default values. If user doesn't set properly one or more values,
* or if no config file found, I use program default values */
config->cpu_num = 0;
config->align = 2;
config->vertical_offset = 5;
config->horizontal_offset = 5;
strncpy(config->font, "-misc-fixed-medium-r-semicondensed--*-*-*-*-c-*-*-*", 63);
strncpy(config->colour, "green", 63);
config->shadow_offset = 1;
strncpy(config->shadow_colour, "black", 63);
config->bar_length = 52;
config->on_time = 3;
config->refresh = 1;
fp = fopen(config_file,"r");
if (fp == NULL) {
printf("WARNING: no config file found at %s, using default settings.\n\n", config_file);
}
else {
while (!feof(fp)) {
/* get a line of the config file */
if (fgets(line, 256, fp) == NULL) {
fclose(fp);
break;
}
/* Delete ' ' chars at the start of a line */
while (*line==' ') {
chars_number=strlen(line);
for (i=0;i<=chars_number;i++)
*(line+i)=*(line+i+1);
}
/* set config values from the config file */
if (*line!='#') { //uncommented lines
if (sscanf(line, "display cpu = %s", value) != errno)
config->cpu_num = atoi(value);
if (sscanf(line, "align = %s", value) != errno)
config->align = atoi(value);
if (sscanf(line, "vertical offset = %s", value) != errno)
config->vertical_offset = atoi(value);
if (sscanf(line, "horizontal offset = %s", value) != errno)
config->horizontal_offset = atoi(value);
if (sscanf(line, "font = %s", value) != errno)
strcpy(config->font, value);
if (sscanf(line, "colour = %s", value) != errno)
strcpy(config->colour, value);
if (sscanf(line, "shadow offset = %s", value) != errno)
config->shadow_offset = atoi(value);
if (sscanf(line, "shadow colour = %s", value) != errno)
strcpy(config->shadow_colour, value);
if (sscanf(line, "bar length = %s", value) != errno)
config->bar_length = atoi(value);
if (sscanf(line, "on time = %s", value) != errno)
config->on_time = atoi(value);
if (sscanf(line, "refresh = %s", value) != errno)
config->refresh = atoi(value);
// printf("%s",line); //Debug info: show cleared config file
}
}
}
}
4,帮助文件,键入指令之前需要参考的内容
//command lines help
void help(void)
{
printf("-g scaling_governor: conservative ondemand userspace powersave performance\n");
printf("-s scaling_set_speed: uint KHZ\n");
printf("example:./osdcpufreq -g userspace -s 3300000\n");
printf("example:./osdcpufreq -g performance\n");
}
5,主函数
int main (int argc, char *argv[] ) {
cpufreq_info_struct *cpufreq_info;
cpufreq_info_struct *cpufreq_next_info;// from command lines
config_struct *config;
char freq_perc;
/* OSD drawing vars */
//xosd *osd = NULL;
char *string;
/* Parse configuration (file or default values) */
config=malloc(sizeof(config_struct));
if (config == NULL) {
printf("Error: malloc failed. Can't allocate dinamic memory for config.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
configure(config);
/* Allocate dinamic memory for cpufreq_next_info */
cpufreq_next_info=malloc(sizeof(cpufreq_info_struct));
if (cpufreq_next_info==NULL) {
printf ("Error: malloc failed. Can't allocate dinamic memory for cpufreq_next_info.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
/* Allocate dinamic memory for cpufreq_info */
cpufreq_info=malloc(sizeof(cpufreq_info_struct));
if (cpufreq_info==NULL) {
printf ("Error: malloc failed. Can't allocate dinamic memory for cpufreq_info.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
//get current cpu infomation
printf ("/------cpu current infomation------------------------------------------/\n");
get_cpu_info(cpufreq_info,config->cpu_num);
//see current cpu infomation, compare the next set infomation
getchar();
//Parse the command lines,set cpu
printf ("/------set cpu infomation-----------------------------------------------/\n");
int opt = 0;
opt = getopt( argc, argv, "hg:s:");
while( opt != -1 )
{
switch( opt )
{
case 'h':
printf("help\n");
help();
break;
case 'g':
strcpy(cpufreq_next_info->governor,optarg);
printf("cpufreq_next_info->governor:%s\n",cpufreq_next_info->governor);
break;
case 's':
cpufreq_next_info->set_speed = atoi (optarg);
printf("cpufreq_next_info->set_speed:%d\n",cpufreq_next_info->set_speed);
break;
default:
printf("def\n");
break;
}
opt = getopt( argc, argv, "hg:s:");
}
set_cpu_info(cpufreq_next_info, config->cpu_num);
//set completed, then again get current cpu infomation
printf ("/------cpu current infomation------------------------------------------/\n");
get_cpu_info(cpufreq_info,config->cpu_num);
/* create OSD object
osd = xosd_create(3);
if (osd == NULL) {
printf("Error creating xosd object.\n");
printf ("%s", XOSD_ERROR);
printf ("%s", CONTACT_ERROR);
exit(1);
}*/
/*
xosd_set_font(osd, config->font);
xosd_set_align (osd, config->align);
xosd_set_vertical_offset (osd, config->vertical_offset);
xosd_set_horizontal_offset (osd, config->horizontal_offset);
xosd_set_bar_length(osd, config->bar_length);;
xosd_set_colour(osd, config->colour);
xosd_set_shadow_colour(osd, config->shadow_colour);
xosd_set_shadow_offset(osd, config->shadow_offset);
*/
string=(char *)malloc(64);
do {
/* getting cpu info */
//get_cpu_info(cpufreq_info,config->cpu_num);
freq_perc=(((cpufreq_info->cur_freq)-(cpufreq_info->min_freq)))*100/((cpufreq_info->max_freq)-(cpufreq_info->min_freq));
/* Display CPU Current freq */
sprintf(string, "CPU current frequency: %dMHz", cpufreq_info->cur_freq/1000);
//xosd_display (osd, 0, XOSD_string, string);
/* Display CPU freq percent bar */
//xosd_display (osd, 1, XOSD_percentage, freq_perc);
/* Display CPU general info */
strup(cpufreq_info->driver);
strup(cpufreq_info->governor);
sprintf(string, "driver: %s governor: %s", cpufreq_info->driver, cpufreq_info->governor);
//xosd_display (osd, 2, XOSD_string, string);
/* Wait */
switch (config->on_time) {
case 0: sleep(config->refresh); //always on top
break;
default: sleep(config->on_time);
break;
}
//xosd_hide(osd);
} while (config->on_time==0); /* Always on top? */
/* Clear memory */
free (string);
free (config);
free (cpufreq_info);
return (0); //Bye ;-)
}
6,测试结果
键入make之后,编译出osdcpufreq可执行文件
root@via-OptiPlex-3010:/home/via/2_OsdCpuFreqs/OsdCpuFreqs# ./osdcpufreq -g userspace -s 3300000
/------cpu current infomation------------------------------------------/
scaling_cur_freq = 1600000
cpuinfo_max_freq = 3300000
cpuinfo_min_freq = 1600000
scaling_driver = acpi-cpufreq
scaling_governor = ondemand
/------set cpu infomation-----------------------------------------------/
cpufreq_next_info->governor:userspace
cpufreq_next_info->set_speed:3300000
exit set_cpu_info
/------cpu current infomation------------------------------------------/
scaling_cur_freq = 3300000
cpuinfo_max_freq = 3300000
cpuinfo_min_freq = 1600000
scaling_driver = acpi-cpufreq
scaling_governor = userspace
通过红色的字符,可以看出已经成功修改了cpu的模式和频率,想确保真正修改成功成功,可以使用一下指令验证
root@via-OptiPlex-3010:/# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
userspace
玩事儿!
于是我参考开源程序osdcpufreq,进一步做了修改,该开源程序的下载地址为http://sourceforge.net/projects/osdcpufreq/files/osdcpufreq/osdcpufreq-0.3/
主要膝盖的内容包括两点:
(1)将xosd图形显示的程序屏蔽掉了,在Ubuntu12.04系统下不知道为什么,装不上xosd
(2)可以采用命令行的形式,输入频率值等信息,从而更新/sys/devices/system/cpu/cpu0/cpufreq/下的值
详细的程序如下:
1,获取cpu信息,注意格式化的操作
void get_cpu_info(cpufreq_info_struct *cpufreq_info, char cpu_num) {
char file[54];
FILE *fp;
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpu_num);
fp = fopen (file, "r");
if (fp == NULL ) {
printf("Error reading scaling_cur_freq file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
fscanf (fp,"%i",&(cpufreq_info->cur_freq));
printf("scaling_cur_freq = %d\n", cpufreq_info->cur_freq);
fclose (fp);
}
2,设置cpu信息,本人添加的程序,修改了scaling_governor(模式)和scaling_setspeed(频率)的值
//set cpu infomation
void set_cpu_info(cpufreq_info_struct *cpufreq_info, char cpu_num)
{
char file[54];
FILE *fp;
char str[20];
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpu_num);
fp = fopen (file, "w");
if (fp == NULL ) {
printf("Error reading scaling_governor file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
fprintf(fp,"%s",cpufreq_info->governor);
fclose (fp);
}
sprintf(file, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpu_num);
fp = fopen (file, "w");
if (fp == NULL ) {
printf("Error reading scaling_setspeed file. ");
printf("%s",CPUFREQD_ERROR);
printf("%s",CONTACT_ERROR);
exit(1);
} else {
sprintf(str,"%d",cpufreq_info->set_speed);
fprintf(fp,"%s",str);
fclose (fp);
}
printf("exit set_cpu_info\n");
}
3,获取conf文件里面的初始化参数
void configure(config_struct *config) {
char line[256];
char value[64];
char *the_home;
char config_file[48];
int chars_number, i;
FILE *fp;
/* getting user home directory */
the_home =getenv("HOME");
sprintf(config_file, "%s/%s",the_home,FILE_CONF);
/* Load default values. If user doesn't set properly one or more values,
* or if no config file found, I use program default values */
config->cpu_num = 0;
config->align = 2;
config->vertical_offset = 5;
config->horizontal_offset = 5;
strncpy(config->font, "-misc-fixed-medium-r-semicondensed--*-*-*-*-c-*-*-*", 63);
strncpy(config->colour, "green", 63);
config->shadow_offset = 1;
strncpy(config->shadow_colour, "black", 63);
config->bar_length = 52;
config->on_time = 3;
config->refresh = 1;
fp = fopen(config_file,"r");
if (fp == NULL) {
printf("WARNING: no config file found at %s, using default settings.\n\n", config_file);
}
else {
while (!feof(fp)) {
/* get a line of the config file */
if (fgets(line, 256, fp) == NULL) {
fclose(fp);
break;
}
/* Delete ' ' chars at the start of a line */
while (*line==' ') {
chars_number=strlen(line);
for (i=0;i<=chars_number;i++)
*(line+i)=*(line+i+1);
}
/* set config values from the config file */
if (*line!='#') { //uncommented lines
if (sscanf(line, "display cpu = %s", value) != errno)
config->cpu_num = atoi(value);
if (sscanf(line, "align = %s", value) != errno)
config->align = atoi(value);
if (sscanf(line, "vertical offset = %s", value) != errno)
config->vertical_offset = atoi(value);
if (sscanf(line, "horizontal offset = %s", value) != errno)
config->horizontal_offset = atoi(value);
if (sscanf(line, "font = %s", value) != errno)
strcpy(config->font, value);
if (sscanf(line, "colour = %s", value) != errno)
strcpy(config->colour, value);
if (sscanf(line, "shadow offset = %s", value) != errno)
config->shadow_offset = atoi(value);
if (sscanf(line, "shadow colour = %s", value) != errno)
strcpy(config->shadow_colour, value);
if (sscanf(line, "bar length = %s", value) != errno)
config->bar_length = atoi(value);
if (sscanf(line, "on time = %s", value) != errno)
config->on_time = atoi(value);
if (sscanf(line, "refresh = %s", value) != errno)
config->refresh = atoi(value);
// printf("%s",line); //Debug info: show cleared config file
}
}
}
}
4,帮助文件,键入指令之前需要参考的内容
//command lines help
void help(void)
{
printf("-g scaling_governor: conservative ondemand userspace powersave performance\n");
printf("-s scaling_set_speed: uint KHZ\n");
printf("example:./osdcpufreq -g userspace -s 3300000\n");
printf("example:./osdcpufreq -g performance\n");
}
5,主函数
int main (int argc, char *argv[] ) {
cpufreq_info_struct *cpufreq_info;
cpufreq_info_struct *cpufreq_next_info;// from command lines
config_struct *config;
char freq_perc;
/* OSD drawing vars */
//xosd *osd = NULL;
char *string;
/* Parse configuration (file or default values) */
config=malloc(sizeof(config_struct));
if (config == NULL) {
printf("Error: malloc failed. Can't allocate dinamic memory for config.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
configure(config);
/* Allocate dinamic memory for cpufreq_next_info */
cpufreq_next_info=malloc(sizeof(cpufreq_info_struct));
if (cpufreq_next_info==NULL) {
printf ("Error: malloc failed. Can't allocate dinamic memory for cpufreq_next_info.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
/* Allocate dinamic memory for cpufreq_info */
cpufreq_info=malloc(sizeof(cpufreq_info_struct));
if (cpufreq_info==NULL) {
printf ("Error: malloc failed. Can't allocate dinamic memory for cpufreq_info.\n");
printf ("%s", CONTACT_ERROR);
exit(1);
}
//get current cpu infomation
printf ("/------cpu current infomation------------------------------------------/\n");
get_cpu_info(cpufreq_info,config->cpu_num);
//see current cpu infomation, compare the next set infomation
getchar();
//Parse the command lines,set cpu
printf ("/------set cpu infomation-----------------------------------------------/\n");
int opt = 0;
opt = getopt( argc, argv, "hg:s:");
while( opt != -1 )
{
switch( opt )
{
case 'h':
printf("help\n");
help();
break;
case 'g':
strcpy(cpufreq_next_info->governor,optarg);
printf("cpufreq_next_info->governor:%s\n",cpufreq_next_info->governor);
break;
case 's':
cpufreq_next_info->set_speed = atoi (optarg);
printf("cpufreq_next_info->set_speed:%d\n",cpufreq_next_info->set_speed);
break;
default:
printf("def\n");
break;
}
opt = getopt( argc, argv, "hg:s:");
}
set_cpu_info(cpufreq_next_info, config->cpu_num);
//set completed, then again get current cpu infomation
printf ("/------cpu current infomation------------------------------------------/\n");
get_cpu_info(cpufreq_info,config->cpu_num);
/* create OSD object
osd = xosd_create(3);
if (osd == NULL) {
printf("Error creating xosd object.\n");
printf ("%s", XOSD_ERROR);
printf ("%s", CONTACT_ERROR);
exit(1);
}*/
/*
xosd_set_font(osd, config->font);
xosd_set_align (osd, config->align);
xosd_set_vertical_offset (osd, config->vertical_offset);
xosd_set_horizontal_offset (osd, config->horizontal_offset);
xosd_set_bar_length(osd, config->bar_length);;
xosd_set_colour(osd, config->colour);
xosd_set_shadow_colour(osd, config->shadow_colour);
xosd_set_shadow_offset(osd, config->shadow_offset);
*/
string=(char *)malloc(64);
do {
/* getting cpu info */
//get_cpu_info(cpufreq_info,config->cpu_num);
freq_perc=(((cpufreq_info->cur_freq)-(cpufreq_info->min_freq)))*100/((cpufreq_info->max_freq)-(cpufreq_info->min_freq));
/* Display CPU Current freq */
sprintf(string, "CPU current frequency: %dMHz", cpufreq_info->cur_freq/1000);
//xosd_display (osd, 0, XOSD_string, string);
/* Display CPU freq percent bar */
//xosd_display (osd, 1, XOSD_percentage, freq_perc);
/* Display CPU general info */
strup(cpufreq_info->driver);
strup(cpufreq_info->governor);
sprintf(string, "driver: %s governor: %s", cpufreq_info->driver, cpufreq_info->governor);
//xosd_display (osd, 2, XOSD_string, string);
/* Wait */
switch (config->on_time) {
case 0: sleep(config->refresh); //always on top
break;
default: sleep(config->on_time);
break;
}
//xosd_hide(osd);
} while (config->on_time==0); /* Always on top? */
/* Clear memory */
free (string);
free (config);
free (cpufreq_info);
return (0); //Bye ;-)
}
6,测试结果
键入make之后,编译出osdcpufreq可执行文件
root@via-OptiPlex-3010:/home/via/2_OsdCpuFreqs/OsdCpuFreqs# ./osdcpufreq -g userspace -s 3300000
/------cpu current infomation------------------------------------------/
scaling_cur_freq = 1600000
cpuinfo_max_freq = 3300000
cpuinfo_min_freq = 1600000
scaling_driver = acpi-cpufreq
scaling_governor = ondemand
/------set cpu infomation-----------------------------------------------/
cpufreq_next_info->governor:userspace
cpufreq_next_info->set_speed:3300000
exit set_cpu_info
/------cpu current infomation------------------------------------------/
scaling_cur_freq = 3300000
cpuinfo_max_freq = 3300000
cpuinfo_min_freq = 1600000
scaling_driver = acpi-cpufreq
scaling_governor = userspace
通过红色的字符,可以看出已经成功修改了cpu的模式和频率,想确保真正修改成功成功,可以使用一下指令验证
root@via-OptiPlex-3010:/# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
userspace
玩事儿!
相关文章推荐
- Linux内核中CPU主频和电压调整 (三)
- Linux内核中CPU主频和电压调整 (四)
- Linux内核中CPU主频和电压调整 (一)
- Linux内核中CPU主频和电压调整 (一)
- Linux内核中CPU主频和电压调整 (二)
- Linux内核中CPU主频和电压调整 -- (1)
- 用sysctl调整linux内核选项
- 迅为iTOP-4412核心板调整电压
- 调整Linux内核启动中的驱动初始化顺序
- 20121022 用sysctl调整linux内核选项
- 通过调整linux内核参数,支持百万级并发
- 如何调整Linux内核启动中的驱动初始化顺序
- 重编译LINUX内核调整SCTP参数的方法
- Linux内核调整和内核参数详解
- 通过调整linux内核参数,支持百万级并发
- 如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级
- Linux内核驱动程序初始化顺序的调整
- 如何调整Linux内核启动中的驱动初始化顺序
- 调整Linux内核解决C500k问题
- 如何调整Linux内核启动中的驱动初始化顺序