diff options
-rw-r--r-- | argparse.c | 13 | ||||
-rw-r--r-- | cputemp2maxfreq.c | 14 | ||||
-rw-r--r-- | cputemp2maxfreq.h | 3 | ||||
-rw-r--r-- | failsafe.c | 4 | ||||
-rwxr-xr-x | generate_debug_h.sh | 2 | ||||
-rw-r--r-- | logger.c | 66 | ||||
-rw-r--r-- | logger.h | 3 |
7 files changed, 100 insertions, 5 deletions
@@ -14,6 +14,9 @@ void printhelp() "Usage: %s <options>\n" "\n" "Options:\n" + "-c <file> Write CSV log for later analysis to file. Append data if the\n" + " file already exists\n" + "-C <file> Same as -c but overwrite existing file\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" @@ -56,11 +59,19 @@ void argparse(int argc, char **argv) memcpy(&userconfig,&config,sizeof(struct s_config)); // Parse options - while((opt=getopt(argc,argv,"f:g:hi:l:mp:s:t:"))!=-1) + while((opt=getopt(argc,argv,"c:C:f:g:hi:l:mp:s:t:"))!=-1) { DEBUG1_ARGPARSE("Argument: %c Value: %s\n",opt,optarg); switch(opt) { + case 'c': + strncpy(userconfig.csvlog,optarg,sizeof(userconfig.csvlog)); + userconfig.csvoverwrite=0; + break; + case 'C': + strncpy(userconfig.csvlog,optarg,sizeof(userconfig.csvlog)); + userconfig.csvoverwrite=1; + break; case 'f': userconfig.fallback_freq=strtoll(optarg,NULL,10); break; diff --git a/cputemp2maxfreq.c b/cputemp2maxfreq.c index 826655a..556e404 100644 --- a/cputemp2maxfreq.c +++ b/cputemp2maxfreq.c @@ -25,6 +25,9 @@ struct s_config config={ "stdout", // Logger name &logger_stdout, // Logger function 0, // Don't log measurement data + "", // CSV logfile + 0, // Don't overwrite CSV logfile + NULL, // File handler for CSV file }; struct s_cpudata cpudata; @@ -52,6 +55,13 @@ int main(int argc,char **argv) config.logger("Interval: %d",config.interval); config.logger("Logger: %s (%p)",config.logger_name,config.logger); config.logger("Log measurement data: %d",config.log_data); + if (config.csvlog[0]==0) + { + config.logger("CSV Log file: Disabled"); + } else { + config.logger("CSV Log file: %s",config.csvlog); + config.logger("Overwrite CSV log: %d",config.csvoverwrite); + } if ((config.max_temp<VALID_TEMP_MIN) || (config.max_temp>VALID_TEMP_MAX)) { @@ -114,6 +124,9 @@ int main(int argc,char **argv) } } +// Initialise CSV logging + if (config.csvlog[0]!=0) csvlog_init(); + // Set signal handlers signal(SIGTERM,signal_handler); signal(SIGINT,signal_handler); @@ -141,6 +154,7 @@ int main(int argc,char **argv) { config.logger("CPU Temperature: %ld, CPU Frequency: %ld",cpudata.cur_temp/1000,cpudata.cur_freq); } + if (config.csvfile!=NULL) csvlog_write(); // Check if we should increase if ((cpudata.cur_temp<config.max_temp) && (cpudata.scale_max<cpudata.max_freq)) diff --git a/cputemp2maxfreq.h b/cputemp2maxfreq.h index 6eb5726..984fabc 100644 --- a/cputemp2maxfreq.h +++ b/cputemp2maxfreq.h @@ -36,6 +36,9 @@ struct s_config { char logger_name[10]; // Name of the logging function void (*logger)(char *,...); // Pointer to the logging function char log_data; // Option to log measurement data + char csvlog[255]; // CSV logfile + char csvoverwrite; // Overwrite CSV file if it already exists + FILE *csvfile; // File handle for CSV file }; #endif @@ -4,12 +4,16 @@ #include <stdio.h> #include "cputemp2maxfreq.h" #include "cpufreq.h" +#include "logger.h" extern struct s_cpudata cpudata; extern struct s_config config; void failsafe(int code) { +// Close CSV log if used + if (config.csvfile!=NULL) csvlog_close(); + // First try to set the CPU to it's minimum frequency if (cpufreq_set_long_int("scaling_max_freq",cpudata.min_freq,100)>0) { diff --git a/generate_debug_h.sh b/generate_debug_h.sh index f32ac5c..209495c 100755 --- a/generate_debug_h.sh +++ b/generate_debug_h.sh @@ -5,7 +5,7 @@ # Configuration DEBUG_LEVELS=4 -DEBUG_PARTS="MAIN ARGPARSE SYSFS CPUFREQ" +DEBUG_PARTS="MAIN ARGPARSE SYSFS CPUFREQ LOG" 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` @@ -3,13 +3,16 @@ #include <syslog.h> #include <sys/time.h> #include <time.h> -#include "cputemp2maxfreq.h" #include <string.h> +#include <unistd.h> +#include "cputemp2maxfreq.h" +#include "debug.h" extern struct s_config config; +extern struct s_cpudata cpudata; -// These functions are not called directly. They are set by argparse in the -// config.logger function pointer. +// The logger_* functions are not called directly. They are set by argparse in +// the config.logger function pointer. // No logging at all void logger_none(char *format,...) { } @@ -69,3 +72,60 @@ void logger_kmsg(char *format,...) config.logger(buffer); } } + +// CSV logging fields: +// 1: Timestamp +// 2: CPU Minimum frequency +// 3: CPU Maximum frequency +// 4: CPU Current frequency +// 5: CPU Temperature +// 6: Target temperature +// 7: Scaling maximum frequency before increase/decrease +void csvlog_init() +{ + int exists; + + DEBUG1_LOG("Started\n"); + exists=access(config.csvlog,F_OK); + DEBUG1_LOG("File %s exists: %d\n",config.csvlog,exists); + + if ((exists!=0) || (config.csvoverwrite==1)) + { + DEBUG1_LOG("Creating/overwriting CSV file\n"); + config.csvfile=fopen(config.csvlog,"w"); + fputs("\"timestamp\"," + "\"CPU Minumum frequency\"," + "\"CPU Maximum frequency\"," + "\"CPU Current frequency\"," + "\"CPU Temperature\"," + "\"Target temperature\"," + "\"Scaling maximum frequency\"\n",config.csvfile); + } else { + DEBUG1_LOG("Appending to CSV file\n"); + config.csvfile=fopen(config.csvlog,"a"); + } +} + +// Write a single line of CSV data +void csvlog_write() +{ + struct timeval unixtime; + struct tm *time; + char timestring[255]; + + DEBUG1_LOG("Writing data series to CSV file\n"); + + gettimeofday(&unixtime,NULL); + time=localtime(&unixtime.tv_sec); + strftime(timestring,255,"%F %T",time); + + fprintf(config.csvfile,"\"%s\",\"%ld\",\"%ld\",\"%ld\",\"%ld\",\"%ld\",\"%ld\"\n",timestring,cpudata.min_freq,cpudata.max_freq,cpudata.cur_freq,cpudata.cur_temp/1000,config.max_temp/1000,cpudata.scale_max); +} + +// Close the CSV file +void csvlog_close() +{ + DEBUG1_LOG("Closing CSV file\n"); + fclose(config.csvfile); + config.csvfile=NULL; +} @@ -5,5 +5,8 @@ void logger_none(char *format,...); void logger_stdout(char *format,...); void logger_syslog(char *format,...); void logger_kmsg(char *format,...); +void csvlog_init(); +void csvlog_write(); +void csvlog_close(); #endif |