aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPA4WDH2024-07-28 14:45:59 +0200
committerPA4WDH2024-07-28 14:45:59 +0200
commit36162d6931aaaf56c60c2e1c77cd3cdc2eba8363 (patch)
tree6bb22ce09315d14a5b7fb4ba2e5178d1b5dd9450
parentFLush after writes to CSV file (diff)
downloadcputemp2maxfreq-36162d6931aaaf56c60c2e1c77cd3cdc2eba8363.tar.gz
cputemp2maxfreq-36162d6931aaaf56c60c2e1c77cd3cdc2eba8363.tar.bz2
cputemp2maxfreq-36162d6931aaaf56c60c2e1c77cd3cdc2eba8363.zip
Add autodetection for temperature input
-rw-r--r--Makefile2
-rw-r--r--argparse.c5
-rw-r--r--cputemp.c128
-rw-r--r--cputemp.h12
-rw-r--r--cputemp2maxfreq.c29
-rwxr-xr-xgenerate_debug_h.sh2
6 files changed, 173 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 77e77c6..e65cacf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-cputemp2maxfreq: version.o debug.o sysfs.o cpufreq.o failsafe.o argparse.o logger.o
+cputemp2maxfreq: version.o debug.o sysfs.o cpufreq.o failsafe.o argparse.o logger.o cputemp.o
version.h: generate_version_h.sh .git/index
./generate_version_h.sh > version.h
diff --git a/argparse.c b/argparse.c
index 124f3bc..1eae42b 100644
--- a/argparse.c
+++ b/argparse.c
@@ -20,7 +20,10 @@ void printhelp()
" Default: %ld\n"
"-g <governor> cpufreq governor to use, use \"keep\" to keep current governor\n"
" Default: %s\n"
- "-i <file> Input for temperature readout, usually somewhere in sysfs\n"
+ "-i <sensor> Input for temperature readout, this can be specified as:\n"
+ " A full path that starts with /, usually somewhere in sysfs\n"
+ " A sensor name, for example \"Core 0\"\n"
+ " The word \"auto\" autodetects a valid sensor\n"
" Default: %s\n"
"-p <time> Poll interval in seconds\n"
" Default: %d\n"
diff --git a/cputemp.c b/cputemp.c
new file mode 100644
index 0000000..559056f
--- /dev/null
+++ b/cputemp.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include "cputemp2maxfreq.h"
+#include "debug.h"
+#include "sysfs.h"
+#include "cputemp.h"
+
+extern struct s_config config;
+
+// Read a single hwmon directory and search for the requested sensor name
+void cputemp_read_hwmon(char *hwmon,char *sensor_name,struct s_sensor *sensor)
+{
+ DIR *hwmon_dir;
+ struct dirent *hwmon_dirent;
+ int count;
+ char buf[255];
+ int datalen;
+ char sysfs_file[255];
+ long int testdata;
+ int offset;
+
+ DEBUG1_CPUTEMP("Searching for sensors in %s\n",hwmon);
+
+ hwmon_dir=opendir(hwmon);
+ if (hwmon_dir==NULL)
+ {
+ DEBUG1_CPUTEMP("Failed to open hwmon dir\n");
+ return;
+ }
+
+ hwmon_dirent=readdir(hwmon_dir);
+ while((hwmon_dirent!=NULL) && (sensor->valid==0))
+ {
+ DEBUG3_CPUTEMP("%s\n",hwmon_dirent->d_name);
+
+// We are searching for files named "temp<number>_label"
+ if (strncmp(hwmon_dirent->d_name,"temp",4)==0)
+ {
+ DEBUG3_CPUTEMP("Found temp entry: %s\n",hwmon_dirent->d_name);
+ offset=0;
+ for(count=5;count<7;count++)
+ {
+ if (hwmon_dirent->d_name[count]=='_')
+ {
+ DEBUG3_CPUTEMP("Underscore at %d\n",count);
+ offset=count+1;
+ break;
+ }
+ }
+ if (strncmp(hwmon_dirent->d_name+offset,"label",5)==0)
+ {
+ DEBUG2_CPUTEMP("Found label %s\n",hwmon_dirent->d_name);
+ sprintf(sysfs_file,"%s/%s",hwmon,hwmon_dirent->d_name);
+
+// Read the label to see if it matches what we're looking for
+ datalen=sysfs_read_str(sysfs_file,buf,sizeof(buf));
+ if (datalen<0)
+ {
+ DEBUG2_CPUTEMP("Failed to read label\n");
+ } else {
+ DEBUG1_CPUTEMP("Label is: %s\n",buf);
+ if (strncasecmp(buf,sensor_name,255)==0)
+ {
+ DEBUG2_CPUTEMP("Label machtes our search criteria\n");
+ offset=strlen(sysfs_file)-5;
+ strncpy(sysfs_file+offset,"input",5);
+ DEBUG1_CPUTEMP("Input filename: %s\n",sysfs_file);
+
+// Validate the sensor by reading it
+ testdata=sysfs_read_long_int(sysfs_file);
+ DEBUG2_CPUTEMP("Input value: %ld\n",testdata);
+ if ((testdata>=VALID_TEMP_MIN) && (testdata<=VALID_TEMP_MAX))
+ {
+ DEBUG1_CPUTEMP("Input data is valid, marking sensor as valid\n");
+ sensor->valid=1;
+ strncpy(sensor->name,buf,sizeof(buf));
+ strncpy(sensor->filename,sysfs_file,sizeof(sysfs_file));
+ } else {
+ DEBUG1_CPUTEMP("Input data is invalid, ignoring sensor\n");
+ }
+ }
+ }
+ }
+ }
+ hwmon_dirent=readdir(hwmon_dir);
+ }
+ closedir(hwmon_dir);
+}
+
+// Find all entries under /sys/class/hwmon and check them with
+// cputemp_read_hwmon
+void cputemp_find_sensor(char *sensor_name,struct s_sensor *sensor)
+{
+ DIR *hwmon_dir;
+ struct dirent *hwmon_dirent;
+ char subdir[255];
+
+ DEBUG1_CPUTEMP("Searching for sensor %s\n",sensor_name);
+
+// Mark sensor data as invalid, it will be set valid if we find something
+ sensor->valid=0;
+
+ hwmon_dir=opendir("/sys/class/hwmon");
+ if (hwmon_dir==NULL)
+ {
+ DEBUG1_CPUTEMP("Failed to open /sys/class/hwmon, is sysfs mounted?\n");
+ return;
+ }
+
+ hwmon_dirent=readdir(hwmon_dir);
+ while((hwmon_dirent!=NULL) && (sensor->valid==0))
+ {
+ DEBUG3_CPUTEMP("Found file: %s\n",hwmon_dirent->d_name);
+
+// If the name starts with hwmon try to read it
+// Note that /sys/class/hwmon actually contains symlinks but we treat them like directories
+ if (strncmp(hwmon_dirent->d_name,"hwmon",5)==0)
+ {
+ sprintf(subdir,"/sys/class/hwmon/%s",hwmon_dirent->d_name);
+ DEBUG2_CPUTEMP("Found hwmon entry: %s\n",subdir);
+ cputemp_read_hwmon(subdir,sensor_name,sensor);
+ }
+ hwmon_dirent=readdir(hwmon_dir);
+ }
+ closedir(hwmon_dir);
+}
diff --git a/cputemp.h b/cputemp.h
new file mode 100644
index 0000000..8cd39d5
--- /dev/null
+++ b/cputemp.h
@@ -0,0 +1,12 @@
+#ifndef HAVE_CPUTEMP_H
+#define HAVE_CPUTEMP_H
+
+struct s_sensor {
+ char name[255];
+ char filename[255];
+ char valid;
+};
+
+void cputemp_find_sensor(char *sensor_name,struct s_sensor *sensor);
+
+#endif
diff --git a/cputemp2maxfreq.c b/cputemp2maxfreq.c
index 47b1f53..d3242b6 100644
--- a/cputemp2maxfreq.c
+++ b/cputemp2maxfreq.c
@@ -12,13 +12,14 @@
#include "version.h"
#include "argparse.h"
#include "logger.h"
+#include "cputemp.h"
// Set default config
struct s_config config={
"", // Name of this program, set by argparse
"conservative", // Governor
70000, // Temperature
- "/sys/devices/virtual/thermal/thermal_zone0/temp", // Temperature input
+ "auto", // Temperature input
100000, // Frequency step
2000000, // Fallback frequency
10, // Interval
@@ -49,7 +50,7 @@ int main(int argc,char **argv)
{
long int diff;
long int newfreq;
-
+ struct s_sensor sensor;
char *transition_latency_remark;
argparse(argc,argv);
@@ -98,6 +99,30 @@ int main(int argc,char **argv)
exit(1);
}
+// Autodetect temperature input if needed
+ if (config.temp_input[0]!='/')
+ {
+ if (strcmp(config.temp_input,"auto")==0)
+ {
+ DEBUG1_MAIN("Starting temperature sensor detection with name \"Package id 0\"\n");
+ cputemp_find_sensor("Package id 0",&sensor);
+ } else {
+ DEBUG1_MAIN("Starting temperature sensor detection with name \"%s\"\n",config.temp_input);
+ cputemp_find_sensor(config.temp_input,&sensor);
+ }
+ if (sensor.valid==1)
+ {
+ DEBUG1_MAIN("Found sensor \"%s\"\n",sensor.name);
+ DEBUG1_MAIN("Sensor file: %s\n",sensor.filename);
+ strncpy(config.temp_input,sensor.filename,sizeof(config.temp_input));
+ config.logger("Detection returned temperature input: %s",config.temp_input);
+ config.logger("Temperature input name: %s",sensor.name);
+ } else {
+ config.logger("Detection failed to return a valid sensor, set it using -i");
+ 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");
diff --git a/generate_debug_h.sh b/generate_debug_h.sh
index 209495c..4049af9 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 LOG"
+DEBUG_PARTS="MAIN ARGPARSE SYSFS CPUFREQ LOG CPUTEMP"
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`