// SPDX-License-Identifier: GPL-2.0-or-later /* * tmon.c Thermal Monitor (TMON) main function and entry point * * Copyright (C) 2012 Intel Corporation. All rights reserved. * * Author: Jacob Pan <jacob.jun.pan@linux.intel.com>
*/
unsignedlong ticktime = 1; /* seconds */ unsignedlong no_control = 1; /* monitoring only or use cooling device for * temperature control.
*/ double time_elapsed = 0.0; unsignedlong target_temp_user = 65; /* can be select by tui later */ int dialogue_on; int tmon_exit; staticshort daemon_mode; staticint logging; /* for recording thermal data to a file */ staticint debug_on;
FILE *tmon_log; /*cooling device used for the PID controller */ char ctrl_cdev[CDEV_NAME_SIZE] = "None"; int target_thermal_zone; /* user selected target zone instance */ staticvoid start_daemon_mode(void);
pthread_t event_tid;
pthread_mutex_t input_lock; void usage(void)
{
printf("Usage: tmon [OPTION...]\n");
printf(" -c, --control cooling device in control\n");
printf(" -d, --daemon run as daemon, no TUI\n");
printf(" -g, --debug debug message in syslog\n");
printf(" -h, --help show this help message\n");
printf(" -l, --log log data to /var/tmp/tmon.log\n");
printf(" -t, --time-interval sampling time interval, > 1 sec.\n");
printf(" -T, --target-temp initial target temperature\n");
printf(" -v, --version show version\n");
printf(" -z, --zone target thermal zone id\n");
exit(0);
}
void version(void)
{
printf("TMON version %s\n", VERSION); exit(EXIT_SUCCESS);
}
staticvoid tmon_cleanup(void)
{
syslog(LOG_INFO, "TMON exit cleanup\n");
fflush(stdout);
refresh(); if (tmon_log)
fclose(tmon_log); if (event_tid) {
pthread_mutex_lock(&input_lock);
pthread_cancel(event_tid);
pthread_mutex_unlock(&input_lock);
pthread_mutex_destroy(&input_lock);
}
closelog(); /* relax control knobs, undo throttling */
set_ctrl_state(0);
staticvoid tmon_sig_handler(int sig)
{
syslog(LOG_INFO, "TMON caught signal %d\n", sig);
refresh(); switch (sig) { case SIGTERM:
printf("sigterm, exit and clean up\n");
fflush(stdout); break; case SIGKILL:
printf("sigkill, exit and clean up\n");
fflush(stdout); break; case SIGINT:
printf("ctrl-c, exit and clean up\n");
fflush(stdout); break; default: break;
}
tmon_exit = true;
}
staticvoid start_syslog(void)
{ if (debug_on)
setlogmask(LOG_UPTO(LOG_DEBUG)); else
setlogmask(LOG_UPTO(LOG_ERR));
openlog("tmon.log", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
syslog(LOG_NOTICE, "TMON started by User %d", getuid());
}
staticvoid prepare_logging(void)
{ int i; struct stat logstat;
if (!logging) return; /* open local data log file */
tmon_log = fopen(TMON_LOG_FILE, "w+"); if (!tmon_log) {
syslog(LOG_ERR, "failed to open log file %s\n", TMON_LOG_FILE); return;
}
if (lstat(TMON_LOG_FILE, &logstat) < 0) {
syslog(LOG_ERR, "Unable to stat log file %s\n", TMON_LOG_FILE);
fclose(tmon_log);
tmon_log = NULL; return;
}
/* The log file must be a regular file owned by us */ if (S_ISLNK(logstat.st_mode)) {
syslog(LOG_ERR, "Log file is a symlink. Will not log\n");
fclose(tmon_log);
tmon_log = NULL; return;
}
if (logstat.st_uid != getuid()) {
syslog(LOG_ERR, "We don't own the log file. Not logging\n");
fclose(tmon_log);
tmon_log = NULL; return;
}
fprintf(tmon_log, "#----------- THERMAL SYSTEM CONFIG -------------\n"); for (i = 0; i < ptdata.nr_tz_sensor; i++) { char binding_str[33]; /* size of long + 1 */ int j;
for (i = 0; i < ptdata.nr_cooling_dev; i++)
fprintf(tmon_log, "#cooling devices%02d: %s\n",
i, ptdata.cdi[i].type);
fprintf(tmon_log, "#---------- THERMAL DATA LOG STARTED -----------\n");
fprintf(tmon_log, "Samples TargetTemp "); for (i = 0; i < ptdata.nr_tz_sensor; i++) {
fprintf(tmon_log, "%s%d ", ptdata.tzi[i].type,
ptdata.tzi[i].instance);
} for (i = 0; i < ptdata.nr_cooling_dev; i++)
fprintf(tmon_log, "%s%d ", ptdata.cdi[i].type,
ptdata.cdi[i].instance);
/* validate range of user selected target zone, default to the first * instance if out of range
*/
target_tz_index = zone_instance_to_index(target_thermal_zone); if (target_tz_index < 0) {
target_thermal_zone = ptdata.tzi[0].instance;
syslog(LOG_ERR, "target zone is not found, default to %d\n",
target_thermal_zone);
} while (1) {
sleep(ticktime);
show_title_bar();
show_sensors_w();
update_thermal_data(); if (!dialogue_on) {
show_data_w();
show_cooling_device();
}
time_elapsed += ticktime;
controller_handler(trec[0].temp[target_tz_index] / 1000, &yk);
trec[0].pid_out_pct = yk; if (!dialogue_on)
show_control_w(); if (tmon_exit) break;
}
tmon_cleanup(); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.