您的位置:首页 > 运维架构 > Linux

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

玩事儿!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: