diff options
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | output.c | 42 | ||||
-rw-r--r-- | powerdebug.c | 255 | ||||
-rw-r--r-- | powerdebug.h | 30 | ||||
-rw-r--r-- | sensor.c | 91 | ||||
-rw-r--r-- | sensor.h | 9 |
6 files changed, 441 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0226e34 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int +CFLAGS?=-O1 -g ${WARNFLAGS} +CC?=gcc + +OBJS = powerdebug.o output.o sensor.o + + +powerdebug: $(OBJS) powerdebug.h + $(CC) ${CFLAGS} $(OBJS) -o powerdebug + +All: powerdebug + +clean: + rm -f powerdebug *.o diff --git a/output.c b/output.c new file mode 100644 index 0000000..ba53c30 --- /dev/null +++ b/output.c @@ -0,0 +1,42 @@ +#include "powerdebug.h" + +void usage(char **argv) +{ + printf("Usage: %s [OPTIONS]\n", argv[0]); + printf(" -r Show regulator information\n"); + printf(" -s Show sensor information\n"); + printf(" -v Verbose\n"); + printf(" -h Help\n"); + + exit(0); +} + + +void print_regulator_info(int verbose) +{ + int i; + + for (i=0; i<numregulators; i++) { + printf("Regulator # %d\n", i+1); + printf("\tname=%s\n", regulators_info[i].name); + if (strcmp(regulators_info[i].status, "")) + printf("\tstatus=%s\n", regulators_info[i].status); + if (strcmp(regulators_info[i].state, "")) + printf("\tstate=%s\n", regulators_info[i].state); + + if (!verbose) + continue; + + if (strcmp(regulators_info[i].type, "")) + printf("\ttype=%s\n", regulators_info[i].type); + if (strcmp(regulators_info[i].opmode, "")) + printf("\topmode=%s\n", regulators_info[i].opmode); + if (regulators_info[i].microvolts) + printf("\tmicrovolts=%d\n", regulators_info[i].microvolts); + if (regulators_info[i].microamps) + printf("\tmicroamps=%d\n", regulators_info[i].microamps); + if (regulators_info[i].num_users) + printf("\tnum_users=%d\n", regulators_info[i].num_users); + printf("\n"); + } +} diff --git a/powerdebug.c b/powerdebug.c new file mode 100644 index 0000000..dcf1a59 --- /dev/null +++ b/powerdebug.c @@ -0,0 +1,255 @@ +#include <getopt.h> + +#include "powerdebug.h" + + +int numregulators; + +int init_regulator_ds(void) +{ + DIR *regdir; + struct dirent *item; + + regdir = opendir("/sys/class/regulator"); + if (!regdir) + return(1); + while((item = readdir(regdir))) { + if (strncmp(item->d_name, "regulator", 9)) + continue; + + numregulators++; + } + closedir(regdir); + + regulators_info = (struct regulator_info *)malloc(numregulators* + sizeof(struct regulator_info)); + if (!regulators_info) { + fprintf(stderr, "init_regulator_ds: Not enough memory to read information for %d regulators!\n", + numregulators); + return(1); + } + + return(0); +} + +int read_and_print_sensor_info(int verbose) +{ + DIR *dir, *subdir; + int len; + char filename[PATH_MAX], devpath[PATH_MAX]; + char device[PATH_MAX]; + struct dirent *item, *subitem; + +/* + 1. readdir /sys/class/hwmon + 2. foreach subdir in above, do following + a) check if its virtual or physical (check for device) + b) for each *type* (in, temp, pwm, fan, curr, power, energy) + i> search for "_" (strrchr... check for last) + ii> check the *item* depending on type + i.e for "in" type items=min, max, input, label + for "fan" type items=min,max,input,div,target,label + for "pwm" type items=enable, mode, freq + for "temp" type items=type, max, min,input,crit,offset,label,lowest,highest, + for "curr" type items=max,min,input + for "power" type items=average,average_interval,average_min/max, average_highest/lowest, input, input_highest/lowest, accuracy,alarm, cap, cap_min/max + for "energy" type items=input + for "intrusion" type items=alarm,beep +*/ + + sprintf(filename, "%s", "/sys/class/hwmon"); + + dir = opendir(filename); + if (!dir) + return errno; + + while ((item = readdir(dir))) { + if (item->d_name[0] == '.') /* skip the hidden files */ + continue; + + sprintf(filename, "/sys/class/hwmon/%s", item->d_name); + sprintf(devpath, "%s/device", filename); + + len = readlink(devpath, device, PATH_MAX - 1); + + if (len < 0) + strcpy(devpath, filename); + else + device[len] = '\0'; + + subdir = opendir(devpath); + + printf("\nSensor Information for %s :\n", item->d_name); + fflush(stdin); + while ((subitem = readdir(subdir))) { + if (subitem->d_name[0] == '.') /* skip hidden files */ + continue; + + if(!strncmp(subitem->d_name, "in", 2)) + get_sensor_info(devpath, subitem->d_name, "in", + verbose); + else if (!strncmp(subitem->d_name, "temp", 4)) + get_sensor_info(devpath, subitem->d_name, + "temp", verbose); + else if (!strncmp(subitem->d_name, "fan", 4)) + get_sensor_info(devpath, subitem->d_name, + "fan", verbose); + else if (!strncmp(subitem->d_name, "pwm", 4)) + get_sensor_info(devpath, subitem->d_name, + "pwm", verbose); + + } + + closedir(subdir); + } + closedir(dir); + + return 0; +} + + +int read_regulator_info(int verbose) +{ + FILE *file = NULL; + DIR *regdir, *dir; + int len, count = 0, ret = 0; + char line[1024], filename[1024], *fptr; + struct dirent *item, *ritem; + + regdir = opendir("/sys/class/regulator"); + if (!regdir) + return(1); + while((item = readdir(regdir))) { + if (strlen(item->d_name) < 3) + continue; + + if (strncmp(item->d_name, "regulator", 9)) + continue; + + len = sprintf(filename, "/sys/class/regulator/%s",item->d_name); + + dir = opendir(filename); + if (!dir) { + ret = 1; + goto exit2; + } + + count++; + if (count > numregulators) { + ret = 1; + goto exit1; + } + + while((ritem = readdir(dir))) { + strcpy(regulators_info[count-1].name, item->d_name); + if (strlen(ritem->d_name) < 3) + continue; + + sprintf(filename + len, "/%s", ritem->d_name); + // printf("Inside %s directory. Opening file %s!\n", item->d_name, ritem->d_name); + + file = fopen(filename, "r"); + if (!file) + continue; + + memset(line, 0, 1024); + fptr = fgets(line, 1024, file); + fclose(file); + if (!fptr) { + ret = 1; + goto exit1; + } + // printf("Read file %s, data=%s, count = %d\n", filename, fptr, count); + + if (!strcmp(ritem->d_name, "name")) + strcpy(regulators_info[count-1].name, fptr); + if (!strcmp(ritem->d_name, "state")) + strcpy(regulators_info[count-1].state, fptr); + if (!strcmp(ritem->d_name, "status")) + strcpy(regulators_info[count-1].status, fptr); + + /* Read following _only_ if verbose option specified */ + if(!verbose) + continue; + + if (!strcmp(ritem->d_name, "type")) + strcpy(regulators_info[count-1].type, fptr); + if (!strcmp(ritem->d_name, "opmode")) + strcpy(regulators_info[count-1].opmode, fptr); + + if (!strcmp(ritem->d_name, "microvolts")) + regulators_info[count-1].microvolts = atoi(fptr); + if (!strcmp(ritem->d_name, "microamps")) + regulators_info[count-1].microamps = atoi(fptr); + if (!strcmp(ritem->d_name, "num_users")) + regulators_info[count-1].num_users = atoi(fptr); + + } +exit1: + closedir(dir); + if (ret) + break; + } +exit2: + closedir(regdir); + + return ret; +} + + +int main(int argc, char **argv) +{ + int c; + int regulators = 0, sensors = 0, verbose = 0; + + /* Options: + * -r : regulator + * -s : sensors + * -v : verbose + * no option / default : all + */ + + while ((c = getopt (argc, argv, "rsvh")) != -1) + switch (c) + { + case 'r': + regulators = 1; + break; + case 's': + sensors = 1; + break; + case 'v': + verbose = 1; + break; + case 'h': + usage (argv); + case '?': + fprintf (stderr, "Unknown option %c'.\n", optopt); + return 1; + default: + usage(argv); + } + + /* By default print both regulator and sensor information */ + if (!regulators && !sensors) { + /* What should be the default behavior ? + regulators = 1; + sensors = 1; + */ + usage(argv); + } + + init_regulator_ds(); + + if (regulators) { + read_regulator_info(verbose); + print_regulator_info(verbose); + } + + if (sensors) { + read_and_print_sensor_info(verbose); + } + + return 0; + +} diff --git a/powerdebug.h b/powerdebug.h new file mode 100644 index 0000000..b8aee35 --- /dev/null +++ b/powerdebug.h @@ -0,0 +1,30 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <dirent.h> +#include <getopt.h> +#include <errno.h> + +//#define PATH_MAX 1024 +//#define NAME_MAX 128 +#define VALUE_MAX 16 + +struct regulator_info { + char name[NAME_MAX]; + char state[VALUE_MAX]; + char status[VALUE_MAX]; + char type[VALUE_MAX]; + char opmode[VALUE_MAX]; + int microvolts; + int microamps; + int num_users; +} *regulators_info; + +extern int numregulators; + +extern void usage(char **argv); +extern void print_regulator_info(int verbose); +extern void get_sensor_info(char *path, char *name, char *sensor, int verbose); + + diff --git a/sensor.c b/sensor.c new file mode 100644 index 0000000..333eb7f --- /dev/null +++ b/sensor.c @@ -0,0 +1,91 @@ +#include "powerdebug.h" +#include "sensor.h" + +char *get_num(char *fname, char *sensor) +{ + char tmpstr[NAME_MAX]; + char *str; + + strcpy(tmpstr, (fname+strlen(sensor))); + + str = strrchr(tmpstr, '_'); + str[0] = '\0'; + + str = strdup(tmpstr); + return str; +} + + +void get_sensor_info(char *path, char *fname, char *sensor, int verbose) +{ + FILE *filep; + char filename[PATH_MAX]; + char **items = NULL, **suffix = NULL; + char *item, result[NAME_MAX], *num; + int ret, count = 0; + + (void)verbose; // get rid of warning + + sprintf(filename, "%s/%s", path, fname); + + if(!strcmp(sensor, "in")) { + items = (char **)items_in; + suffix = (char **)suffix_in; + } + + if(!strcmp(sensor, "temp")) { + items = (char **)items_temp; + suffix = (char **)suffix_temp; + } + + if(!strcmp(sensor, "fan")) { + items = (char **)items_fan; + suffix = (char **)suffix_fan; + } + if(!strcmp(sensor, "pwm")) { + items = (char **)items_pwm; + suffix = (char **)suffix_pwm; + } + + + if (!items || !suffix) + return; + + item = strrchr(fname, '_'); + if(!item) + return; + + if(item) + item++; + + if(item > (fname + strlen(fname))) + return; + + num = get_num(fname, sensor); +// strncpy(num, fname, item - fname -1); + + filep = fopen(filename, "r"); + + if(!filep) + goto exit; + + ret = fscanf(filep, "%s", result); + + fclose(filep); + if(ret != 1) + goto exit; + + while(strcmp(items[count], "")) { + if(!strcmp(items[count], item)) + printf("\'temp\' %s sensor %s\t\t%d%s\n", + num, items[count], atoi(result)/1000, + suffix[count]); + count++; + } + +exit: + free(num); + return; +} + + diff --git a/sensor.h b/sensor.h new file mode 100644 index 0000000..fe2f5d8 --- /dev/null +++ b/sensor.h @@ -0,0 +1,9 @@ +char *items_temp[32] = {"min", "max", "input", "label", ""}; +char *suffix_temp[32] = {"°C", "°C", "°C", "", ""}; +char *items_in[32] = {"min", "max", "input", "label", ""}; +char *suffix_in[32] = {"Volts", "Volts", "Volts", "", ""}; +char *items_fan[32] = {"min", "max", "input", "label", "div", "target", ""}; +char *suffix_fan[32] = {"RPM", "RPM", "RPM", "", "", "RPM", ""}; +char *items_pwm[32] = {"freq", "enable", "mode", ""}; +char *suffix_pwm[32] = {"Hz", "", "", ""}; + |