Linux内核中CPU主频和电压调整 -- (2)

从文章 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


玩事儿!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术在路上

帮助需要的人

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值