aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPA4WDH2023-05-24 12:57:25 +0200
committerPA4WDH2023-05-24 12:57:25 +0200
commit16fb812a46d0e8cde432b58f7dbf6fce147eb89f (patch)
tree9e019f98e515cb21e6c38ff487a82fe375675991
parentDetect program name from argv[0] (diff)
downloadcputemp2maxfreq-16fb812a46d0e8cde432b58f7dbf6fce147eb89f.tar.gz
cputemp2maxfreq-16fb812a46d0e8cde432b58f7dbf6fce147eb89f.tar.bz2
cputemp2maxfreq-16fb812a46d0e8cde432b58f7dbf6fce147eb89f.zip
Add CSV logging
-rw-r--r--argparse.c13
-rw-r--r--cputemp2maxfreq.c14
-rw-r--r--cputemp2maxfreq.h3
-rw-r--r--failsafe.c4
-rwxr-xr-xgenerate_debug_h.sh2
-rw-r--r--logger.c66
-rw-r--r--logger.h3
7 files changed, 100 insertions, 5 deletions
diff --git a/argparse.c b/argparse.c
index 7df1239..75ca20d 100644
--- a/argparse.c
+++ b/argparse.c
@@ -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
diff --git a/failsafe.c b/failsafe.c
index f0c0b3e..59d9d15 100644
--- a/failsafe.c
+++ b/failsafe.c
@@ -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`
diff --git a/logger.c b/logger.c
index 83e92e1..143b62e 100644
--- a/logger.c
+++ b/logger.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;
+}
diff --git a/logger.h b/logger.h
index b9ee787..c8535f1 100644
--- a/logger.h
+++ b/logger.h
@@ -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