thermal 代码分析
thermal 代码分析
基础知识
1.thermal 的框架
使用场景:
当cpu 温度过高时,适当的进行降频,从而控制稳定cpu 温度。
代码分析:
从Makefile 开始
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for sensor chip drivers.
#obj-$(CONFIG_THERMAL) += thermal_sys.o
thermal_sys-y += thermal_core.o thermal_sysfs.o \thermal_helpers.o # 核心代码# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o # dts 解析# governors
thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o # governors 也是五种
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o# cpufreq cooling
thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o # cooling device# clock cooling
thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o # devfreq cooling
thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o# platform thermal drivers
obj-$(CONFIG_SUN8I_THS) += sun8i_ths.o # 平台相关代码,提供读取温度的接口
1.thermal 的初始化
static int __init thermal_init(void)
{int result;mutex_init(&poweroff_lock);result = thermal_register_governors(); // 1.注册五种governorsresult = class_register(&thermal_class); // 2.注册 /sys/class/thermal result = of_parse_thermal_zones(); // 3.解析dts 的"thermal-zones"节点,并注册// thermal_zone_deviceresult = register_pm_notifier(&thermal_pm_nb); // 4.notifier}
fs_initcall(thermal_init);
其中最重要的是 of_parse_thermal_zones
先看看 相关dts:
thermal-zones {cpu_thermal: cpu_thermal {polling-delay-passive = <330>;polling-delay = <1000>;thermal-sensors = <&ths 0>;trips {cpu_warm: cpu_warm {temperature = <65000>;hysteresis = <2000>;type = "passive";};cpu_hot: cpu_hot {temperature = <75000>;hysteresis = <2000>;type = "passive";};cpu_very_hot: cpu_very_hot {temperature = <90000>;hysteresis = <2000>;type = "passive";};cpu_crit: cpu_crit {temperature = <105000>;hysteresis = <2000>;type = "critical";};};cooling-maps {cpu_warm_limit_cpu {trip = <&cpu_warm>;cooling-device = <&cpu0 THERMAL_NO_LIMIT 1>;};cpu_hot_limit_cpu {trip = <&cpu_hot>;cooling-device = <&cpu0 2 3>;};cpu_very_hot_limit_cpu {trip = <&cpu_very_hot>;cooling-device = <&cpu0 5 THERMAL_NO_LIMIT>;};};};};
int __init of_parse_thermal_zones(void)
{ np = of_find_node_by_name(NULL, "thermal-zones"); // 查找 "thermal-zones" for_each_available_child_of_node(np, child) { // 遍历子节点tz = thermal_of_build_thermal_zone(child); // 解析关键词,填充tz 数据结构ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL);if (!ops)goto exit_free;tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); zone = thermal_zone_device_register(child->name, tz->ntrips,mask, tz,ops, tzp,tz->passive_delay,tz->polling_delay); // 注册一个 thermal_zone_device}
}
struct thermal_zone_device *
thermal_zone_device_register(const char *type, int trips, int mask,void *devdata, struct thermal_zone_device_ops *ops,struct thermal_zone_params *tzp, int passive_delay,int polling_delay)
{ dev_set_name(&tz->device, "thermal_zone%d", tz->id);result = device_register(&tz->device); // 注册设备result = thermal_set_governor(tz, governor); // set governorlist_add_tail(&tz->node, &thermal_tz_list); /* Bind cooling devices for this zone */bind_tz(tz); // 将thermal_cdev_list 中的所有cooling devices 与之绑定INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); // 初始化工作队列if (atomic_cmpxchg(&tz->need_update, 1, 0))thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
}
cpufreq cooling device 的注册,位于 cpufreq_driver -> reay 阶段,
static void cpufreq_ready(struct cpufreq_policy *policy)
{ if (of_find_property(np, "#cooling-cells", NULL)) { // 包含#cooling-cells 属性的priv->cdev = of_cpufreq_power_cooling_register(np,policy, power_coefficient, NULL); // register}
}
else {cooling_ops = &cpufreq_cooling_ops; }cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,cooling_ops);
list_add(&cdev->node, &thermal_cdev_list); // 就是添加到 thermal_cdev_list 中
需要关心的是 cpufreq_cooling_ops
static struct thermal_cooling_device_ops cpufreq_cooling_ops = {.get_max_state = cpufreq_get_max_state,.get_cur_state = cpufreq_get_cur_state,.set_cur_state = cpufreq_set_cur_state,
};
.set_cur_state 被 thermal governor 调用
static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,unsigned long state)
{clip_freq = cpufreq_cdev->freq_table[state].frequency; //根据state 设置新的频率cpufreq_cdev->cpufreq_state = state;cpufreq_cdev->clipped_freq = clip_freq; // cpufreq_update_policy(cpufreq_cdev->policy->cpu);return 0;
}
时序图:
thermal 代码分析相关推荐
- Android/Linux Thermal框架分析及其Governor对比
https://www.cnblogs.com/arnoldlu/p/6388151.html 图表 1 Thermal框架 随着SoC性能的快速提升,功耗也极大提高,带来的负面影响是SoC的温度提高 ...
- 20145236《网络攻防》Exp4 恶意代码分析
20145236<网络攻防>Exp4 恶意代码分析 一.基础问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些 ...
- C#中类的继承 override virtual new的作用以及代码分析
继承中override virtual new的作用 virtual 父类中需要注明允许重写的方法: override 子类中必须显示声明该方法是重写的父类中的方法: new 子类中忽略父类的已存在的 ...
- 2017.4.18 静态代码分析工具sonarqube+sonar-runner的安装配置及使用
配置成功后的代码分析页面: 可以看到对复杂度.语法使用.重复度等等都做了分析,具体到了每一个方法和每一句代码. 四种使用方式: sonarqube + sonar-runner sonarqube + ...
- lighttpd1.4.18代码分析
lighttpd1.4.18代码分析(八)--状态机(2)CON_STATE_READ状态 posted @ 2008-09-24 10:50 那谁 阅读(2225) | 评论 (1) 编辑 lig ...
- Device Tree(三):代码分析
2019独角兽企业重金招聘Python工程师标准>>> 一.前言 Device Tree总共有三篇,分别是: 1.为何要引入Device Tree,这个机制是用来解决什么问题的?(请 ...
- 使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!
大数据是计算领域的新高地,它有望提供一种方法来应对二十一世纪不断增长的数据生成.越来越多的大数据爱好者正在涌现,越来越多的公司正在采用各种大数据平台,并希望提出以客户为中心的解决方案,帮助他们在竞争激 ...
- 20145328 《网络对抗技术》恶意代码分析
20145328 <网络对抗技术>恶意代码分析 ------看到这句话说明还没写完-------- 实践内容: 使用schtasks指令监控系统运行 使用sysmon工具监控系统运行 使用 ...
- starGAN原理代码分析
下载: git clone https://github.com/yunjey/StarGAN.git 1 cd StarGAN/ 1 下载celebA训练数据: bash download.sh 1 ...
- tensorflow笔记:多层CNN代码分析
tensorflow笔记系列: (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代 ...
最新文章
- scrum敏捷开发的几款工具
- 全球及中国软磁镍合金行业供需前景与投资策略研究报告2022版
- 图像处理工具包ImagXpress中如何设置上下文菜单
- python系统下载-python
- java对rgb取反_颜色取反 rgb COLORREF | 学步园
- FileZilla Client 3.26.1 发布,FTP 解决方案
- Java学习教程,Java基础教程(从入门到精通)
- 新手上路,Python黑帽子学习笔记从此开篇
- 屏蔽全部统计代码(51.la cnzz 百度统计 谷歌分析师adsense、屏蔽淘宝客广告代码)的方法...
- 【第二章】Google Guava 之 Splitter 学习
- 前端vue3 tsx风格开发
- Ext.ux.form.SearchField 添加placeholder属性 2016年9月19日
- 记忆测试系统java代码_JAVA课程设计——记忆测试系统(附源程序).doc
- SuperMap BIM+GIS-Revit模型处理-背景
- latex里图片大小如何调整_怎样用latex修改插入图形的大小,使图形大小一致。...
- java cookie设置注意事项
- 实现表单form提交前进行确认提示 表单提交 确认对话框
- 全国所有城市人均GDP排名(包含县级市 611 )
- 破解版的cornerstore(mac版)
- oracle中部门工资降序排列,oracle面试题整理二(10级学员 乔宇整理)
热门文章
- 几个名词解释 TBB VPP KKK
- 通过Python计算经纬度点任意角度任意距离的经纬度点
- wince 百度地图懒人包_百度导航车载wince版下载
- 游戏娱乐型型计算机装机配置单,组装配置单-急求 I5 性能最好的 电脑配置的 各种大型游戏能完美流畅的玩 价钱 和配置什么的 求详细...
- 输出某年某月某日的c语言程序,输入某年某月某日,输出这是今年的第几天,C语言问题...
- Python 微信公众号文章爬取
- 动手学深度学习(六、卷积神经网络)
- GameFi 在宏观趋势上出现下滑,但个别项目却大放异彩| April Monthly Report
- android 游戏音效格式,Android基础 - Android Studio 添加游戏音效
- BSOJ 2927 -- 【模拟试题】保镖排队