forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools/thermal: Introduce tmon, a tool for thermal subsystem
Increasingly, Linux is running on thermally constrained devices. The simple thermal relationship between processor and fan has become past for modern computers. As hardware vendors cope with the thermal constraints on their products, more sensors are added, new cooling capabilities are introduced. The complexity of the thermal relationship can grow exponentially among cooling devices, zones, sensors, and trip points. They can also change dynamically. To expose such relationship to the userspace, Linux generic thermal layer introduced sysfs entry at /sys/class/thermal with a matrix of symbolic links, trip point bindings, and device instances. To traverse such matrix by hand is not a trivial task. Testing is also difficult in that thermal conditions are often exception cases that hard to reach in normal operations. TMON is conceived as a tool to help visualize, tune, and test the complex thermal subsystem. Signed-off-by: Jacob Pan <[email protected]> Signed-off-by: Zhang Rui <[email protected]>
- Loading branch information
Showing
9 changed files
with
2,173 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
VERSION = 1.0 | ||
|
||
BINDIR=usr/bin | ||
WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int | ||
CFLAGS= -O1 ${WARNFLAGS} -fstack-protector | ||
CC=gcc | ||
|
||
CFLAGS+=-D VERSION=\"$(VERSION)\" | ||
LDFLAGS+= | ||
TARGET=tmon | ||
|
||
INSTALL_PROGRAM=install -m 755 -p | ||
DEL_FILE=rm -f | ||
|
||
INSTALL_CONFIGFILE=install -m 644 -p | ||
CONFIG_FILE= | ||
CONFIG_PATH= | ||
|
||
|
||
OBJS = tmon.o tui.o sysfs.o pid.o | ||
OBJS += | ||
|
||
tmon: $(OBJS) Makefile tmon.h | ||
$(CC) ${CFLAGS} $(LDFLAGS) $(OBJS) -o $(TARGET) -lm -lpanel -lncursesw -lpthread | ||
|
||
valgrind: tmon | ||
sudo valgrind -v --track-origins=yes --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./$(TARGET) 1> /dev/null | ||
|
||
install: | ||
- mkdir -p $(INSTALL_ROOT)/$(BINDIR) | ||
- $(INSTALL_PROGRAM) "$(TARGET)" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)" | ||
- mkdir -p $(INSTALL_ROOT)/$(CONFIG_PATH) | ||
- $(INSTALL_CONFIGFILE) "$(CONFIG_FILE)" "$(INSTALL_ROOT)/$(CONFIG_PATH)" | ||
|
||
uninstall: | ||
$(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)" | ||
$(CONFIG_FILE) "$(CONFIG_PATH)" | ||
|
||
|
||
clean: | ||
find . -name "*.o" | xargs $(DEL_FILE) | ||
rm -f $(TARGET) | ||
|
||
dist: | ||
git tag v$(VERSION) | ||
git archive --format=tar --prefix="$(TARGET)-$(VERSION)/" v$(VERSION) | \ | ||
gzip > $(TARGET)-$(VERSION).tar.gz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
TMON - A Monitoring and Testing Tool for Linux kernel thermal subsystem | ||
|
||
Why TMON? | ||
========== | ||
Increasingly, Linux is running on thermally constrained devices. The simple | ||
thermal relationship between processor and fan has become past for modern | ||
computers. | ||
|
||
As hardware vendors cope with the thermal constraints on their products, more | ||
and more sensors are added, new cooling capabilities are introduced. The | ||
complexity of the thermal relationship can grow exponentially among cooling | ||
devices, zones, sensors, and trip points. They can also change dynamically. | ||
|
||
To expose such relationship to the userspace, Linux generic thermal layer | ||
introduced sysfs entry at /sys/class/thermal with a matrix of symbolic | ||
links, trip point bindings, and device instances. To traverse such | ||
matrix by hand is not a trivial task. Testing is also difficult in that | ||
thermal conditions are often exception cases that hard to reach in | ||
normal operations. | ||
|
||
TMON is conceived as a tool to help visualize, tune, and test the | ||
complex thermal subsystem. | ||
|
||
Files | ||
===== | ||
tmon.c : main function for set up and configurations. | ||
tui.c : handles ncurses based user interface | ||
sysfs.c : access to the generic thermal sysfs | ||
pid.c : a proportional-integral-derivative (PID) controller | ||
that can be used for thermal relationship training. | ||
|
||
Requirements | ||
============ | ||
Depends on ncurses | ||
|
||
Build | ||
========= | ||
$ make | ||
$ sudo ./tmon -h | ||
Usage: tmon [OPTION...] | ||
-c, --control cooling device in control | ||
-d, --daemon run as daemon, no TUI | ||
-l, --log log data to /var/tmp/tmon.log | ||
-h, --help show this help message | ||
-t, --time-interval set time interval for sampling | ||
-v, --version show version | ||
-g, --debug debug message in syslog | ||
|
||
1. For monitoring only: | ||
$ sudo ./tmon |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* pid.c PID controller for testing cooling devices | ||
* | ||
* | ||
* | ||
* Copyright (C) 2012 Intel Corporation. All rights reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License version | ||
* 2 or later as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* Author Name Jacob Pan <[email protected]> | ||
* | ||
*/ | ||
|
||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <stdint.h> | ||
#include <sys/types.h> | ||
#include <dirent.h> | ||
#include <libintl.h> | ||
#include <ctype.h> | ||
#include <assert.h> | ||
#include <time.h> | ||
#include <limits.h> | ||
#include <math.h> | ||
#include <sys/stat.h> | ||
#include <syslog.h> | ||
|
||
#include "tmon.h" | ||
|
||
/************************************************************************** | ||
* PID (Proportional-Integral-Derivative) controller is commonly used in | ||
* linear control system, consider the the process. | ||
* G(s) = U(s)/E(s) | ||
* kp = proportional gain | ||
* ki = integral gain | ||
* kd = derivative gain | ||
* Ts | ||
* We use type C Alan Bradley equation which takes set point off the | ||
* output dependency in P and D term. | ||
* | ||
* y[k] = y[k-1] - kp*(x[k] - x[k-1]) + Ki*Ts*e[k] - Kd*(x[k] | ||
* - 2*x[k-1]+x[k-2])/Ts | ||
* | ||
* | ||
***********************************************************************/ | ||
struct pid_params p_param; | ||
/* cached data from previous loop */ | ||
static double xk_1, xk_2; /* input temperature x[k-#] */ | ||
|
||
/* | ||
* TODO: make PID parameters tuned automatically, | ||
* 1. use CPU burn to produce open loop unit step response | ||
* 2. calculate PID based on Ziegler-Nichols rule | ||
* | ||
* add a flag for tuning PID | ||
*/ | ||
int init_thermal_controller(void) | ||
{ | ||
int ret = 0; | ||
|
||
/* init pid params */ | ||
p_param.ts = ticktime; | ||
/* TODO: get it from TUI tuning tab */ | ||
p_param.kp = .36; | ||
p_param.ki = 5.0; | ||
p_param.kd = 0.19; | ||
|
||
p_param.t_target = target_temp_user; | ||
|
||
return ret; | ||
} | ||
|
||
void controller_reset(void) | ||
{ | ||
/* TODO: relax control data when not over thermal limit */ | ||
syslog(LOG_DEBUG, "TC inactive, relax p-state\n"); | ||
p_param.y_k = 0.0; | ||
xk_1 = 0.0; | ||
xk_2 = 0.0; | ||
set_ctrl_state(0); | ||
} | ||
|
||
/* To be called at time interval Ts. Type C PID controller. | ||
* y[k] = y[k-1] - kp*(x[k] - x[k-1]) + Ki*Ts*e[k] - Kd*(x[k] | ||
* - 2*x[k-1]+x[k-2])/Ts | ||
* TODO: add low pass filter for D term | ||
*/ | ||
#define GUARD_BAND (2) | ||
void controller_handler(const double xk, double *yk) | ||
{ | ||
double ek; | ||
double p_term, i_term, d_term; | ||
|
||
ek = p_param.t_target - xk; /* error */ | ||
if (ek >= 3.0) { | ||
syslog(LOG_DEBUG, "PID: %3.1f Below set point %3.1f, stop\n", | ||
xk, p_param.t_target); | ||
controller_reset(); | ||
*yk = 0.0; | ||
return; | ||
} | ||
/* compute intermediate PID terms */ | ||
p_term = -p_param.kp * (xk - xk_1); | ||
i_term = p_param.kp * p_param.ki * p_param.ts * ek; | ||
d_term = -p_param.kp * p_param.kd * (xk - 2 * xk_1 + xk_2) / p_param.ts; | ||
/* compute output */ | ||
*yk += p_term + i_term + d_term; | ||
/* update sample data */ | ||
xk_1 = xk; | ||
xk_2 = xk_1; | ||
|
||
/* clamp output adjustment range */ | ||
if (*yk < -LIMIT_HIGH) | ||
*yk = -LIMIT_HIGH; | ||
else if (*yk > -LIMIT_LOW) | ||
*yk = -LIMIT_LOW; | ||
|
||
p_param.y_k = *yk; | ||
|
||
set_ctrl_state(lround(fabs(p_param.y_k))); | ||
|
||
} |
Oops, something went wrong.