Thermal engine 解析
Posted 我爱一次性
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thermal engine 解析相关的知识,希望对你有一定的参考价值。
本文所在的平台是安卓10
thermal engine是高通做的一个温度管理守护进程。在4.9后thermal engine不再被维护,推荐用于调试。从ktm+thermal engine 变成 thermal core来监控温度。可是市面上还是有很多手机继续沿用thermal engine去控制温度,而thermal core用于保守控制。可是,仍然有很多手机会继续使用thermal engine作为过温保护的工具。
目录
最后,希望可以帮到大家,如果有用的就收藏一下,白嫖的就点个赞。
一.thermal engine 框架
sensor:传感器,获取温度。
device:设备,一些调频的设备。比如当cpu sensor检测到温度过高时,会调用cpu device降频操作。通常就是对cpu的设备节点进行操作。(或者cpu 的cooling device)。
thermal_setting:控温的配置,根据soc型号获取,或者从thermal-engine.conf获取。如今,更多选择后者。作用是配置温控策略。记录温度阈值等。
算法:ss算法,pid算法,monitor等。
源码位置:/vendor/qcom/proprietary/thermal-engine
二. sensor 初始化
....
sensors_init(minimum_mode);/*传感器初始化*/
...
如果还是ktm + thermal engine管理模式(老kernel)会在init_sensor_alias添加好sensor。
int sensors_init(int minimum_mode)
int ret_val = 0;
min_mode = minimum_mode;
#ifdef ENABLE_BW_SENSOR
struct sensor_info *bw_sensor_list = NULL;
#endif /* ENABLE_BW_SENSOR */
if (!min_mode)
modem_ts_qmi_init();
//ktm+thermal engine管理模式则进入init_sensor_alias
init_sensor_alias();
parse_thermal_zones();
......
进入parse_thermal_zones
static void parse_thermal_zones(void)
DIR *tdir = NULL;
struct dirent *tdirent = NULL;
char name[MAX_PATH] = 0;
char cwd[MAX_PATH] = 0;
int cnt = 0, ret = 0;
if (!getcwd(cwd, sizeof(cwd)))
return;
if (sensor_cnt <= 0)
//如果没有ktm,进入init_space_sensors进行注册sensor
return init_user_space_sensors();
ret = chdir(THERMAL_SYSFS); /* Change dir to read the entries. Doesnt work
otherwise */
tdir = opendir(THERMAL_SYSFS);
if (!tdir || ret)
msg("%s: Unable to open %s\\n", __func__, THERMAL_SYSFS);
return;
while ((tdirent = readdir(tdir)))
char buf[MAX_PATH];
//获取每个sensor的数据。
......
获取sensor的路径:/sys/devices/virtual/thermal/
到这里为止,就知道能监听的sensor是在哪里。那么,配置thermal-engine.conf有哪些sensor就是从这里选取了。
最后,每个sensor会创建个线程进行持续监控温度:
pthread_create(&(sensor_mgr->monitor_thread), NULL,
sensor_monitor, sensor_mgr);
三. device初始化
设备初始化,通常就是通过修改设备节点来进行设备管控,保护有cpu,gpu,电池,背光等。
注册一个动作与设备相关联。比如thermal-engine.conf里面action里cpu的动作,就会与cpu设备节点关联。
...
devices_init(minimum_mode);
...
各种各样的设备进行初始化。
cooling devices属于thermal core的降频方法,也可以操作cooling devices。
可注册分为:普通设备,cooling devices ,热拔插
int devices_init(int minimum_mode)
int ret_val = 0;
min_mode = minimum_mode;
gpufreq_init();
cpufreq_init();
clusterfreq_init();
thermal_ioctl_init();
.......
/* Functions to execute post devices added to device manager */
hotplug_init();
vdd_dig_sw_mode_init();
vdd_rstr_init();
opt_curr_req_init();
profile_switch_init();
cpr_band_init();
lcd_device_init();
battery_mitigation_init();
/* Add all other kernel cooling devices */
cooling_devices_init();
return ret_val;
普通设备注册:
static struct tmd_generic_dev_info_t gen_dev_list[] =
.name = "wlan",
.num_of_lvls = MAX_WLAN_MITIGATION_LEVEL + 1,
.action = wlan_action,
,
.name = "profile_switch",
.num_of_lvls = MAX_PROFILE_LEVEL + 1,
.action = profile_switch_action,
.min_lvl = PERF_DEFAULT_PROFILE,
,
.name = BATTERY_DEV_NAME,
.num_of_lvls = MAX_BATTERY_MITIGATION_LEVEL + 1,
.action = battery_action,
,
.............
热拔插注册:
static struct tmd_generic_dev_info_t hotplug_dev_list[] =
.name = "hotplug_0",
.num_of_lvls = 2,
.action = hotplug_action,
.data = (void *)0,
,
.name = "hotplug_1",
.num_of_lvls = 2,
.action = hotplug_action,
.data = (void *)1,
,
.name = "hotplug_2",
.num_of_lvls = 2,
.action = hotplug_action,
.data = (void *)2,
,
......
cooling device注册:
static void init_cooling_device( struct devices_manager_dev *dev)
char cdev_name[DEVICES_MAX_NAME_LEN] = 0;
char path[DEVICES_MAX_PATH] = 0;
char freq_buf[DEVICES_MAX_PATH] = 0;
int cpu_idx = 0;
dev->dev_info.cooling_dev_id = -1;
if (!strncmp(dev->dev_info.name, LCD_DEV_NAME,
strlen(dev->dev_info.name)))
snprintf(cdev_name, sizeof(cdev_name),
LCD_COOLING_DEV_NAME);
dev->dev_info.cooling_dev_id = get_cdevn(cdev_name);
else if (!strncmp(dev->dev_info.name, BATTERY_DEV_NAME,
strlen(dev->dev_info.name)))
snprintf(cdev_name, sizeof(cdev_name),
BATTERY_COOLING_DEV_NAME);
dev->dev_info.cooling_dev_id = get_cdevn(cdev_name);
...........
四. thermal_settings配置
配置分为两种:一个是通过soc的id来寻找各个算法的配置,另一种就是读取thermal-engine.conf里填写的配置。
因为thermal engine已经在内核4.9后就不在维护了,那么新的芯片是没有soc的配置的,那就我们就通过thermal-engine.conf进行配置了。
1.soc的id寻找配置
...
pid_init_data(&thermal_settings);
thermal_monitor_init_data(&thermal_settings);
speaker_cal_init_data(&thermal_settings);
ss_init_data(&thermal_settings);
tb_init_data(&thermal_settings);
virtual_sensors_init_data(&thermal_settings);
2.读取thermal-engine.conf
load_config(&thermal_settings, config_file, LOAD_ALL_FLAG);
五. 持续监控
在thermal_settings配置完毕后,就会里面各个配置分到不同算法,并开启各个算法的线程去持续管控好被分配的配置。
pid_algo_init(&thermal_settings);/*pid算法配置,并开启线程监控*/
thermal_monitor(&thermal_settings);/*monitor算法配置,并开启线程监控*/
ss_algo_init(&thermal_settings);/*ss算法配置,并开启线程监控*/
还有speaker_cal和step_wise算法。
比如:
该配置的ss算法的,则在 ss_algo_init函数里,就会把该配置记录到ss的一个表里面。在开启ss算法的线程后,就会持续读这个配置,看是否需要执行ss算法的动作。
最后,希望可以帮到大家,如果有用的就收藏一下,白嫖的就点个赞。
以上是关于Thermal engine 解析的主要内容,如果未能解决你的问题,请参考以下文章
Event Recommendation Engine Challenge分步解析第三步