diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | argparse.c | 79 | ||||
-rw-r--r-- | argparse.h | 6 | ||||
-rw-r--r-- | cputemp2maxfreq.c | 50 | ||||
-rw-r--r-- | cputemp2maxfreq.h | 32 | ||||
-rwxr-xr-x | generate_debug_h.sh | 2 |
6 files changed, 152 insertions, 19 deletions
@@ -1,4 +1,4 @@ -cputemp2maxfreq: version.o debug.o sysfs.o cpufreq.o failsafe.o +cputemp2maxfreq: version.o debug.o sysfs.o cpufreq.o failsafe.o argparse.o version.h: generate_version_h.sh .git/index ./generate_version_h.sh > version.h diff --git a/argparse.c b/argparse.c new file mode 100644 index 0000000..01b6c57 --- /dev/null +++ b/argparse.c @@ -0,0 +1,79 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include "cputemp2maxfreq.h" +#include "debug.h" + +extern struct s_config config; + +void printhelp() +{ + printf( + "Usage: cputemp2maxfreq <options>\n" + "\n" + "Options:\n" + "-f <frequency> Fallback frequency in KHz, used when everything fails\n" + " Default: %ld\n" + "-g <governor> cpufreq governor to use, use \"keep\" to keep current governor\n" + " Default: %s\n" + "-h Display this help text\n" + "-i <file> Input for temperature readout, usually somewhere in sysfs\n" + " Default: %s\n" + "-p <time> Poll interval in seconds\n" + " Default: %d\n" + "-s <step> Step size in Khz when increasing/decreasing CPU speed\n" + " Default: %ld\n" + "-t <number> Temperature limit\n" + " Default: %ld\n", + config.fallback_freq,config.governor,config.temp_input,config.interval, + config.freq_step,config.max_temp/1000 + ); +} + +void argparse(int argc, char **argv) +{ + int opt; + struct s_config userconfig; + + DEBUG1_ARGPARSE("Started\n"); + +// Copy defaults + memcpy(&userconfig,&config,sizeof(struct s_config)); + +// Parse options + while((opt=getopt(argc,argv,"f:g:hi:p:s:t:"))!=-1) + { + DEBUG1_ARGPARSE("Argument: %c Value: %s\n",opt,optarg); + switch(opt) + { + case 'f': + userconfig.fallback_freq=strtoll(optarg,NULL,10); + break; + case 'g': + strncpy(userconfig.governor,optarg,sizeof(userconfig.governor)); + break; + case 'h': + printhelp(); + exit(1); + case 'i': + strncpy(userconfig.temp_input,optarg,sizeof(userconfig.temp_input)); + break; + case 'p': + userconfig.interval=strtoll(optarg,NULL,10); + break; + case 's': + userconfig.freq_step=strtoll(optarg,NULL,10); + break; + case 't': + userconfig.max_temp=strtoll(optarg,NULL,10)*1000; + break; + default: + printhelp(); + exit(1); + } + } + +// Copy modified config to global config + memcpy(&config,&userconfig,sizeof(struct s_config)); +} diff --git a/argparse.h b/argparse.h new file mode 100644 index 0000000..5d643c1 --- /dev/null +++ b/argparse.h @@ -0,0 +1,6 @@ +#ifndef HAVE_ARGPARSE_H +#define HAVE_ARGPARSE_H + +void argparse(int argc, char **argv); + +#endif diff --git a/cputemp2maxfreq.c b/cputemp2maxfreq.c index ebf5026..b023b79 100644 --- a/cputemp2maxfreq.c +++ b/cputemp2maxfreq.c @@ -10,17 +10,11 @@ #include "cputemp2maxfreq.h" #include "failsafe.h" #include "version.h" +#include "argparse.h" -// Valid frequencies are between 100MHz and 10GHz -#define VALID_FREQ_MIN 100000 -#define VALID_FREQ_MAX 10000000 - -// Valid temperatures are between 10 and 150 degrees -#define VALID_TEMP_MIN 10000 -#define VALID_TEMP_MAX 150000 - -struct s_cpudata cpudata; +// Set default config struct s_config config={"conservative",70000,"/sys/devices/virtual/thermal/thermal_zone0/temp",100000,2000000,10}; +struct s_cpudata cpudata; void signal_handler(int signum) { @@ -28,12 +22,13 @@ void signal_handler(int signum) failsafe(0); } -int main() +int main(int argc,char **argv) { long int diff; long int newfreq; printf("Version %s, buildtime %s %s\n",version(),__DATE__,__TIME__); + argparse(argc,argv); // Print configuration printf("Configuration:\n"); @@ -43,16 +38,37 @@ int main() printf("Frequency step: %ld\n",config.freq_step); printf("Fallback frquency: %ld\n",config.fallback_freq); printf("Interval: %d\n",config.interval); + printf("\n"); + + if ((config.max_temp<VALID_TEMP_MIN) || (config.max_temp>VALID_TEMP_MAX)) + { + printf("Invalid temperature, range is %d-%d\n",VALID_TEMP_MIN,VALID_TEMP_MAX); + exit(1); + } + + if ((config.freq_step<VALID_STEP_MIN) || (config.freq_step>VALID_STEP_MAX)) + { + printf("Invalid frequency step, range is %d-%d\n",VALID_STEP_MIN,VALID_STEP_MAX); + exit(1); + } + + if ((config.interval<VALID_INTERVAL_MIN) || (config.interval>VALID_INTERVAL_MAX)) + { + printf("Invalid poll interval, range is %d-%d\n",VALID_INTERVAL_MIN,VALID_INTERVAL_MAX); + exit(1); + + } // Get and validate CPU data cpudata.min_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq"); cpudata.max_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq"); cpudata.scale_max=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq"); - printf("\nCPU data:\n"); + printf("CPU data:\n"); printf("Minimum frequency: %ld\n",cpudata.min_freq); printf("Maximum frequency: %ld\n",cpudata.max_freq); printf("Scaling maximum frequency: %ld\n",cpudata.scale_max); + printf("\n"); if ((cpudata.min_freq<VALID_FREQ_MIN) || (cpudata.min_freq>VALID_FREQ_MAX) || (cpudata.max_freq<VALID_FREQ_MIN) || (cpudata.max_freq>VALID_FREQ_MAX) || @@ -63,6 +79,18 @@ int main() exit(1); } +// Modify fallback frequency is needed + if (config.fallback_freq<cpudata.min_freq) + { + printf("Fallback frequency is lower than CPU's minimum frequency, setting to %ld.\n",cpudata.min_freq); + config.fallback_freq=cpudata.min_freq; + } + if (config.fallback_freq>cpudata.max_freq) + { + printf("Fallback frequency is higher than CPU's maximum frequency, setting to %ld.\n",cpudata.max_freq); + config.fallback_freq=cpudata.max_freq; + } + // Set the governor if (cpufreq_set_str("scaling_governor",config.governor,0)<0) { diff --git a/cputemp2maxfreq.h b/cputemp2maxfreq.h index ef33fd5..39886fd 100644 --- a/cputemp2maxfreq.h +++ b/cputemp2maxfreq.h @@ -1,3 +1,22 @@ +#ifndef HAVE_CPUTEMP2MAXFREQ_H +#define HAVE_CPUTEMP2MAXFREQ_H + +// Valid frequencies are between 100MHz and 10GHz +#define VALID_FREQ_MIN 100000 +#define VALID_FREQ_MAX 10000000 + +// Valid frequency steps are between 1MHz and 1GHz +#define VALID_STEP_MIN 1000 +#define VALID_STEP_MAX 1000000 + +// Valid temperatures are between 10 and 150 degrees +#define VALID_TEMP_MIN 10000 +#define VALID_TEMP_MAX 150000 + +// Valid intervals are between 1 and 30 +#define VALID_INTERVAL_MIN 1 +#define VALID_INTERVAL_MAX 30 + struct s_cpudata { long int min_freq; // CPU's minimum frequency long int max_freq; // CPU's maximum frequency @@ -7,11 +26,12 @@ struct s_cpudata { }; struct s_config { - char *governor; // The governor to use - long int max_temp; // The target temperature - char *temp_input; // Input file to read the temperature - long int freq_step; // Step size to increase/decrease CPU frequency - long int fallback_freq; // CPU frquency to set if we fail to protect hardware - unsigned int interval; // Time interval to check CPU temperature + char governor[255]; // The governor to use + long int max_temp; // The target temperature + char temp_input[255]; // Input file to read the temperature + long int freq_step; // Step size to increase/decrease CPU frequency + long int fallback_freq; // CPU frquency to set if we fail to protect hardware + unsigned int interval; // Time interval to check CPU temperature }; +#endif diff --git a/generate_debug_h.sh b/generate_debug_h.sh index ee1f976..f32ac5c 100755 --- a/generate_debug_h.sh +++ b/generate_debug_h.sh @@ -5,7 +5,7 @@ # Configuration DEBUG_LEVELS=4 -DEBUG_PARTS="MAIN SYSFS CPUFREQ" +DEBUG_PARTS="MAIN ARGPARSE SYSFS CPUFREQ" DEBUG_HELPER_DEF=`grep -o "void .*()" debug.c | head -n 1` DEBUG_HELPER=${DEBUG_HELPER_DEF##* } HEXDUMP_HELPER_DEF=`grep -o "void .*(unsigned char \*data,int len)" debug.c` |