4.3.14. Thermal 系统
4.3.14.1. Thermal 系统概述
Thermal 系统
4.3.14.2. Thermal 系统功能描述
Thermal 系统的典型应用
在
降频:通过
减少 CPU 或 GPU 频率 来 降低功耗,从而 减少 热量 的 产生。 风扇
加速:如果 设备 有 风扇,系统 可以 通过 调整 风扇 转速 来 加强 散热。 系统
关闭 或 重启:当 温度 过高且 无法 通过 降频 等 措施 控制 时,系统 可能 会 进行 自动 关闭 或 重启。
Thermal 系统功能原理
Thermal 系统
Thermal 系统

Thermal 系统工作方式
Thermal 系统
温度
采集 :通过硬件 温度传感器 获取 实时 温度 数据。这些 传感器 可以 是 内 建于 处理器 的 温度传感器,或者 是 外部 的 热电偶 或 热敏电阻。 阈值
设置 :内核或 用户 空间 应用 定义 温度 的 安全 范围 和 响应 措施。通常 包括 高温 阈值(Critical)、中等 温度 阈值(Warning)等。 响应
策略 :当温度 超出 预设 阈值 时,系统 会 启动 相应 的 策略。响应 可以 是: 降低
频率 增加
风扇 转速 关闭
不必要 的 硬件 或 服务 触发
热 保护(如 系统 关机)
温度
调整 :根据策略 调整 后,系统 会 继续 监测 温度 变化,并 重复 上述 过程。
4.3.14.3. Thermal 驱动代码
Thermal 相关代码路径
kernel/drivers/thermal/thermal_of.c
kernel/drivers/thermal/thermal_core.c
kernel/include/linux/thermal.h
Thermal 设备树配置
Thermal 系统arch/arm64/boot/dts/hobot/x5.dtsi 文件
thermal-zones {
thermal_cpu: thermal-cpu {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&pvt 2>;
trips {
cpu_alert0: cpu-alert0 {
temperature = <110000>;
hysteresis = <500>;
type = "passive";
};
cpu_alert1: cpu-alert1 {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
};
cpu_crit: cpu-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
cpu_map0: cpu-map0 {
trip = <&cpu_alert1>;
cooling-device =
<&cpu_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
cpu_map1: cpu-map1 {
trip = <&cpu_alert1>;
cooling-device = <&bpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
cpu_map2: cpu-map2 {
trip = <&cpu_alert1>;
cooling-device = <&gc8000 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
thermal_ddr: thermal-ddr {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&pvt 0>;
trips {
ddr_alert0: ddr-alert0 {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
};
};
cooling-maps {
ddr_map0: ddr-map0 {
trip = <&ddr_alert0>;
cooling-device = <&ddrc_freq THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
这
温度传感器:为
每个 热区 指定 了 相关 的 温度传感器 实例。 温度
阈值(trips) :定义了 不同 的 温度 阈值( cpu_alert0、cpu_alert1和cpu_crit等),每个阈值 在 达到 时 触发 不同 的 行为(如 被动 冷却 或 临界 保护)。 冷却
映射 :定义了 当 温度 阈值 触发 时,如何 启用 不同 的 冷却 设备(如 CPU 核心、BPU、GC8000、DDR 等)。
下面
thermal-zones
thermal-zones节点列出 了 所有 的 热区 配置。在 这个 文件 中,有 两个 热区:thermal_cpu(对应 CPU 的 温度 管理)和 thermal_ddr(对应 DDR 内存 的 温度 管理)。 thermal_cpu: thermal-cpu 这个
部分 定义 了 与 CPU 相关 的 热区,包含 了 以下 关键 配置: polling-delay-passive 和 polling-delay:这
两个 属性 设定 了 热区 的 轮询 延时,单位 是 毫秒。 polling-delay-passive是在 处于 被动模式 下 的 轮询 延时,而 polling-delay是在 正常 模式 下 的 轮询 延时。这里 它们 都 设置 为 1000 毫秒(即 1 秒)。 thermal-sensors:这个
属性 定义 了 与 此 热区 相关 的 温度传感器。在 此处, < &pvt 2 >表示与 CPU 温度 监控 相关 的 传感器,它 指向 一个 名为 pvt的传感器,并且 选择 了 其 第二个 实例。
trips (CPU)
trips描述了 不同 的 温度 阈值 和 行为(触发 条件),即 温度 达到 某个 水平 时 系统 如何 反应。在 这个 文件 中,有 三个 阈值: cpu_alert0:触发
温度 为 110,000 毫度(110°C),属于 被动 类型( passive)。这表示 当 CPU 温度 超过 110°C 时,采取 被动 散热 措施,减少 功耗 等。 cpu_alert1:触发
温度 为 95,000 毫度(95°C),也 是 被动 类型。低于 cpu_alert0,但仍会 采取 类似 的 被动 散热 措施。 cpu_crit:临界温度
为 110,000 毫度(110°C),触发 类型 为 临界( critical)。通常,临界温度会 触发 更强 的 热 保护措施,如 关闭 CPU 或 其他 硬件。
cooling-maps
cooling-maps描述了 在 特定 温度 触发 条件 下,如何 调节 冷却 设备。具体 有 三个 冷却 映射: cpu_map0:当
cpu_alert1温度阈值 被 触发 时,会 激活 以下 冷却 设备: 8 个 CPU 核心
的 冷却 设备(CPU 0 到 CPU 7)。这里 的 THERMAL_NO_LIMIT表示没有 具体 的 温度 限制。
cpu_map1:当
cpu_alert1温度阈值 被 触发 时,会 激活 名为 bpu的冷却 设备。 THERMAL_NO_LIMIT同样表示 没有 温度 限 制。 cpu_map2:当
cpu_alert1温度阈值 被 触发 时,会 激活 名为 gc8000的冷却 设备。
thermal_ddr: thermal-ddr 这个
部分 定义 了 与 DDR 内存 相关 的 热区。与 thermal_cpu类似,包含了 温度 轮询 和 传感器 的 设置,但 它 只 定义 了 一个 温度 阈值。 thermal-sensors:与 DDR 相关
的 温度传感器 为 < &pvt 0 >,它指向 名为 pvt的第一个 传感器 实例。
trips (DDR) DDR 热区
也 定义 了 一个 温度 阈值: ddr_alert0:触发
温度 为 95,000 毫度(95°C),类型 为 被动( passive)。当 DDR 温度超过 此 阈值 时,采取 被动 的 散热 措施。
cooling-maps
ddr_map0:当
ddr_alert0被触发 时,激活 名为 ddrc_freq的冷却 设备。同样, THERMAL_NO_LIMIT表示没有 具体 的 温度 限制。
这
Thermal 内核配置
Thermal 系统
--- Thermal drivers
[ ] Thermal netlink management
[ ] Thermal state transition statistics
(0) Emergency poweroff delay in milli-seconds
[*] Expose thermal sensors as hwmon device
[*] APIs to parse thermal data out of device tree
[*] Enable writable trip points
Default Thermal governor (step_wise) --->
[ ] Fair-share thermal governor
-*- Step_wise thermal governor
[ ] Bang Bang thermal governor
[*] User_space thermal governor
[*] Generic cpu cooling support
[*] CPU frequency cooling device
[*] Generic device cooling support
[ ] Thermal emulation mode support
< > Generic Thermal MMIO driver
< > Generic ADC based thermal sensor
以下
Expose thermal sensors as hwmon device
启用
该 选项 后,系统 的 热 传感器 将 作为 硬件 监控(hwmon)设备 暴露 给 用户 空间。通过 这个 功能,用户 可以 通过 /sys/class/hwmon/目录访问 温度传感器 数据。例如, lm_sensors等工具 可以 使用 这些 数据 来 监控 系统 的 温度 情况,便于 调试 和 优化 系统 的 热 管理。
APIs to parse thermal data out of device tree
启用
该 选项 后,内核 将 具备 解析 设备树 中热 管理 相关 数据 的 能力。设备树 是 描述 硬件 的 配置文件,通常 在 ARM 架构 的 系统 中 使用。通过 启用 这个 选项,内核 可以 从 设备树 中 读取 有关 温度传感器、热 阈值、冷却 设备 等 信息,并 据此 做出 相应 的 热 管理 操作。
Enable writable trip points
启用
该 选项 后,系统 允许 用户 在 运行 时 修改 热 管理 的 trip points(温度 阈值)。Trip points 是 预设 的 温度 阈值,超过 这些 阈值 时,系统 会 采取措施(如 降低 频率 或 启动 风扇)。启用 此 选项 后,用户 可以 通过 sysfs 接口 动态 修改 这些 阈值,以 更好 地 适应 不同 的 工作 负载 和 环境 条件。
Step_wise thermal governor
这是
系统 默认 的 热 管理 调度 器(thermal governor)。 step_wise调度器会 根据 温度 的 变化 逐步 调整 冷却 策略。例如,当 温度 逐渐 上升时,系统 会 采取 逐步 增加 冷却 措施 的 方式。相 较 于 简单 的 bang-bang或其他 策略, step_wise更加细致,能够 提供 平稳 的 温度控制。
User_space thermal governor
启用
该 选项 后,系统 允许 用户 空间 应用 程序控制 热 管理策略。这 意味着 用户 可以 通过 编写 自己 的 应用程序 来 动态 调整 温度控制 措施,例如 启动/停止 冷却 设备 或 修改 冷却 策略 等。这个 功能 适用 于 需要 自定义 热 管理 行为 的 系统,尤其 是 在 一些 嵌入式 或 高性能 应用 中,可以 根据 特定 需求 调节 冷却 方式。
Generic cpu cooling support
启用
该 选项 后,系统 将 支持 通用 的 CPU 冷却 机制,通常 通过 调整 CPU 的 频率、调整 功耗 或 启动/停止 冷却 设备 来 降低 温度。这项 功能 对于 需要 高效 管理 CPU 温度 的 系统 非常 重要,尤其 是 在 负载 较 高时,能够 通过 减少 功耗 来 避免 过热。
CPU frequency cooling device
启用
该 选项 后,系统 会 支持 基于 CPU 频率 调整 的 冷却 设备。这 意味着 当 温度 升高 时,系统 可以 动态 降低 CPU 的 频率,以 减少 功耗 和 热量,从而 帮助 系统 降低 温度。此 功能 通常 与 CPU 动态 频率 调节(DVFS)相关,能够 在 高温 情况 下 自动 降低 CPU 性能 来 保护 硬件。
Generic device cooling support
启用
该 选项 后,系统 将 支持 通用 的 设备 冷却 机制。这 包括 CPU 以外 的 设备(例如 GPU、内存 控制器、硬盘 等)的 冷却 措施。系统 会 根据 温度 变化 调整 相关 设备 的 功耗 或 启动 冷却 装置,以 提高 系统 的 整体 热 管理 能力。
4.3.14.4. Thermal 系统的功能和使用
Linux Thermal 是 Linux 系统
整个 Thermal 框架
Thermal Driver: 负责
将 获取 温度 设备,注册 成 struct thermal_zone_device,Thermal Zone Device 本质是 待 获取 温度 设备 的 抽象,本板 端系统 上 有 两个 thermal zone,分别 是 thermal_zone0和thermal_zone1。Thermal Governor: 则
负责 如何 控制 温度,注册 成 struct thermal_governor,比如 Step Wise、User space 等等。Thermal Governor 本质是 控制 温度 策略。 Thermal Cooling: 负责
将 控制 温度 设备,注册 成 struct thermal_cooling_device,实际就是 需要 降温 的 设备,在 板 端系统 上 一共 有 四个 cooling device: cooling_device0: cpu
cooling_device1: bpu
cooling_device2: gpu
cooling_device3: ddr 其中,cooling 设备 DDR 与
thermal_zone0关联,cooling 设备 CPU/BPU/GPU 与thermal_zone1关联。
Thermal Core: 负责
把 governor、cooling device、zone device 等 部分 关联 在 一起,同时 提供 了 用户 空间 sysfs 节点 等 通用 功能,Thermal Core 是 thermal的 核心。
以上/sys/class/thermal 目录
Thermal 的

加入

Thermal 驱动关键结构体说明
thermal_zone_device
struct thermal_zone_device {
int id;
char type[THERMAL_NAME_LENGTH];
struct device device;
struct attribute_group trips_attribute_group;
struct thermal_attr *trip_temp_attrs;
struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs;
enum thermal_device_mode mode;
void *devdata;
struct thermal_trip *trips;
int num_trips;
unsigned long trips_disabled; /* bitmap for disabled trips */
unsigned long passive_delay_jiffies;
unsigned long polling_delay_jiffies;
int temperature;
int last_temperature;
int emul_temperature;
int passive;
int prev_low_trip;
int prev_high_trip;
atomic_t need_update;
struct thermal_zone_device_ops *ops;
struct thermal_zone_params *tzp;
struct thermal_governor *governor;
void *governor_data;
struct list_head thermal_instances;
struct ida ida;
struct mutex lock;
struct list_head node;
struct delayed_work poll_queue;
enum thermal_notify_event notify_event;
};
struct thermal_zone_device 是
下面
id:类型:
int该字段
用于 为 每个 热区 分配 一个 唯一 的 标识符,用于 区分 不同 的 热区。
type:类型:
char[THERMAL_NAME_LENGTH]该字段
表示 热区 设备 的 类型 名称,通常 是 一个 字符串,指示 热区 设备 的 类型(例如 CPU 热区,GPU 热区 等)。
device:类型:
struct device该字段
表示 热区 设备 本身,它 是 一个 device结构体,允许 与 设备 模型 进行 交互,便于管理 热区 相关 的 硬件。
trips_attribute_group:类型:
struct attribute_group用于
管理 热区 的 属性 组(例如 通过 sysfs 访问)。 trips_attribute_group包含与 温度 阈值(trip points)相关 的 属性。
trip_temp_attrs,trip_type_attrs,trip_hyst_attrs:类型:
struct thermal_attr *这些
字 段 分别 指向 与 热区 温度 阈值 相关 的 属性: trip_temp_attrs:阈值温度 的 属性; trip_type_attrs:阈值类型 的 属性(如 高温、低温 等); trip_hyst_attrs:阈值滞后 的 属性,用于 控制 温度 上 下限 的 间隔。
mode:类型:
enum thermal_device_mode表示
当前 热区 的 工作 模式。热区 设备 的 模式 决定 了 它 如何 响应 温度 变化(如 工作、休眠、关机 等 模式)。
devdata:类型:
void *指向
与 热区 设备 相关 的 私有 数据,驱动程序 可以 使用 该字 段 来 存储 特定 的 设备 私有 数据。
trips:类型:
struct thermal_trip *该字
段 是 一个 指向 struct thermal_trip结构体 的 指针 数组,用于 存储 热区 的 各个 温度 阈值(trip points)。每个 阈值 定义 了 一个 温度 点,当 系统 温度 达到 这些 点 时会 触发 特定 的 操作(如 启用 风扇、降低 频率 等)。
num_trips:类型:
int表示
当前 热区 设备 支持 的 温度 阈值 的 数量。每个 阈值 可能 会 触发 不同 的 冷却 措施。
trips_disabled:类型:
unsigned long位
图,用于 表示 哪些 温度 阈值 已 被 禁用。如果 某个 阈值 被 禁用,则 不会 触发 与 该 阈值 相关 的 任何 事件。
passive_delay_jiffies:类型:
unsigned long当
系统 执行 被动 冷却 时,需要 等待 的 延迟时间,以 jiffies 为 单位。被动 冷却 通常 是 指 通过 降低 CPU 或 其他 设备 的 频率 来 降低 温度。
polling_delay_jiffies:类型:
unsigned long用于
检查 温度 是否 超出 某些 阈值 的 延迟时间,以 jiffies 为 单位。如果 系统 是 中断 驱动 的,这个 值 可能 为 0。
temperature:类型:
int当前
温度。这个 字 段 主要 供 核心 代码 使用,驱动程序 应该 使用 thermal_zone_get_temp()函数来 获取 当前 温度。
last_temperature:类型:
int上
一次 读取 的 温度 值。
emul_temperature:类型:
int如果
启用 了 CONFIG_THERMAL_EMULATION(热管理 仿真),则 这个 字 段 表示 模拟 的 温度 值。它 在 开发 或 测试 时 非常 有用,尤其 是 在 没有 真实 硬件 的 情况 下。
passive:类型:
int如果
设备 已经 通过 某个 被动 阈值,则 该 字 段 为 1;否则 为 0。被动 冷却 通常 是 通过 调整 设备 频率 来 降低 温度。
prev_low_trip,prev_high_trip:类型:
int这些
字 段 分别 存储 当 被动 冷却 阈值 被 触发 时 的 温度 范围。 prev_low_trip是上 一个 低温 阈值, prev_high_trip是上 一个 高温 阈值。
need_update:类型:
atomic_t用于
标记 热区 设备 是否 需要 更新。该字段 通常 由 核心 代码 设置 为 1,如果 设备 的 温度 或 状态 需要 更新,则 触发 更新。
ops:类型:
struct thermal_zone_device_ops *指向
热区 设备 操作 函数 集合 的 指针。这些 操作 函数 定义 了 热区 设备 的 行为,包括 如何 获取 温度、设置 模式、触发 阈值 等。
tzp:类型:
struct thermal_zone_params *指向
热区 参数 结构 体 的 指针。这个 结构 体 包含 了 与 热区 相关 的 其他 配置 参数。
governor:类型:
struct thermal_governor *指向
热区 管理器 的 指针。热区 管理器 负责 根据 当前 温度 和 热区 策略 决定 如何 调整 温度(例如 通过 改变 CPU 或 其他 硬件 的 频率 来 实现 冷却)。
governor_data:类型:
void *用于
存储 与 热区 管理器 相关 的 私有 数据。
thermal_instances:类型:
struct list_head热区
的 所有 实例 的 链表。每个 实例 表示 热区 设备 中 的 一个 具体 的 硬件 或 功能。
ida:类型:
struct idaIDA(ID allocator)结构体,用于 生成 唯一 的 ID,通常 用于 为 每个 热区 的 冷却 设备 分配 唯一 ID。
lock:类型:
struct mutex用于
保护 thermal_instances链表的 锁,防止 多线程 或 中断 竞争。
node:类型:
struct list_head用于
将 thermal_zone_device添加到 全局 热区 列表 中 的 节点。 thermal_tz_list是一个 包含 所有 热区 设备 的 链表。
poll_queue:类型:
struct delayed_work用于
延迟 工作 任务 的 队列,在 周期性 检查 温度 或 触发 阈值 时 使用。
notify_event:类型:
enum thermal_notify_event上
一个 通知 事件 的 类型,用于 指示 温度 触发 了 什么样 的 通知 事件(例如 温度 过 高等)。
上述ops 是governor 是thermal_instances 是
thermal_governor
struct thermal_governor {
char name[THERMAL_NAME_LENGTH];
int (*bind_to_tz)(struct thermal_zone_device *tz);
void (*unbind_from_tz)(struct thermal_zone_device *tz);
int (*throttle)(struct thermal_zone_device *tz, int trip);
struct list_head governor_list;
};
结构thermal_governor 用于thermal_zone_device)和
1) name (char name[THERMAL_NAME_LENGTH])
char name[THERMAL_NAME_LENGTH];
功能:存储
热 管制 器 的 名称。 THERMAL_NAME_LENGTH是名称 的 最大 长度。这个 名称 用于 标识 不同 的 热 管制 器(例如“用户 模式”或“硬件 控制”)。
2) bind_to_tz (int (*bind_to_tz)(struct thermal_zone_device *tz))
int (*bind_to_tz)(struct thermal_zone_device *tz);
功能:一个
回调 函数,用于 在 热 管制 器 与 热区 设备( thermal_zone_device)绑定时 调用。 参数:
tz:指向要 绑定 的 热区 设备 的 指针。
返回值:如果
返回 0,表示 绑定 成功;如果 返回 非零值,表示 绑定 失败。 说明:这个
回调 函数 是 热 管制 器 与 热区 设备 关联 的 过程。成功 绑定 后,热 管制 器 将 能够 控制 该 热区 设备 的 温度。
3) unbind_from_tz (void (*unbind_from_tz)(struct thermal_zone_device *tz))
void (*unbind_from_tz)(struct thermal_zone_device *tz);
功能:一个
回调 函数,用于 在 热 管制 器 与 热区 设备 解除 绑定 时 调用。 参数:
tz:指向已 解除 绑定 的 热区 设备 的 指针。
返回值:该
函数 没有 返回值。 说明:当热
管制 器 不再 需要 控制 某个 热区 设备 时,调用 此 函数 来 解除 绑定。
4) throttle (int (*throttle)(struct thermal_zone_device *tz, int trip))
int (*throttle)(struct thermal_zone_device *tz, int trip);
功能:一个
回调 函数,用于 在 温度 触发 某个 阈值 时(无论 温度 是否 已 达到 阈值),进行 热 管制 的 调节 操作。通常,这 用于 在 温度 接近 或 超过 某个 阈值 时,调节 系统 的 功率 或 性能。 参数:
tz:指向热区 设备 的 指针。 trip:热区设备 的 温度 阈值 索引,表示 当前 温度 是否 接近 或 已 超过 某个 阈值。
返回值:返回
一个 整数,通常 是 成功 或 错误码,0 表示 成功,其他 值 表示 失败。 说明:该
回调 函数 通过 给定 的 阈值( trip)调整系统 的 行为。例如,降低 CPU 频率、调整 风扇 速度 等。
5) governor_list (struct list_head governor_list)
struct list_head governor_list;
功能:一个
链表 节点,用于 将 不同 的 热 管制 器 添加 到 全局 的 热 管制 器 列表 中。 说明:该
结构 成员 是 list_head类型,它是 Linux 内核 中 实现 链表 的 数据结构,允许 热 管制 器 在 系统 中 作为 链表 元素 进行 管理 和 调度。
总的来说,struct thermal_governor 是bind_to_tz 和 unbind_from_tz 回调throttle 回调trip)对
thermal_bind_params(Cooling Device)
结构thermal_bind_params ,用于
struct thermal_bind_params {
struct thermal_cooling_device *cdev;
int weight;
int trip_mask;
unsigned long *binding_limits;
int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev);
};
1) cdev (struct thermal_cooling_device *cdev)
struct thermal_cooling_device *cdev;
类型:指向
thermal_cooling_device类型的 指针。 功能:指向
一个 冷却 设备(cooling device)。冷却 设备 是 用来 调节 热区 温度 的 硬件 组件 或 软件 控制 机制。通过 这个 指针,系统 可以 操作 冷却 设备,启动、停止 或者 调整 其 冷却 能力。
2) weight (int weight)
int weight;
类型:整数
类型。 功能:表示
冷却 设备 对 热区 的 冷却 效果 的 权重。权重 是 由 系统 特性 决定 的,表示 冷却 设备 的 冷却 能力。权重 越高,冷却 效果 越 好。例如,权重 为 某 冷却 设备 的 两倍 的 设备 将 比 权重 较 低 的 设备 更 有效 地 降低 温度。 说明:冷却
设备 的 weight是相对 的。如果 有 多个 冷却 设备,它们 的 权重 将 帮助 系统 决定 在 某些 温度 阈值 下 哪个 设备 应该 优先 激活。
3) trip_mask (int trip_mask)
int trip_mask;
类型:整数
类型。 功能:这是
一个 位 掩码(bitmask),用于 指定 冷却 设备 与 热区 之间 的 绑定 关系,特别 是 对于 特定 的 温度 阈值(trip point)。它 表明 在 某些 温度 阈值 下,哪些 冷却 设备 应该 启用 或者 激活。 说明:每个
trip_mask中的 每 一位 代表 一个 温度 阈值 对应 的 冷却 设备 状态。可以 通过 设置 位 掩码 来 确定 该 冷却 设备 在 不同 的 温度 范围 下 应该 如何 工作。
4) binding_limits (unsigned long *binding_limits)
unsigned long *binding_limits;
类型:指向
unsigned long类型的 指针。 功能:这是
一个 数组,表示 冷却 设备 与 热区 绑定 时 的 冷却 状态 限制。该 数组 的 大小 为 2 * thermal_zone.number_of_trip_points,即每个 温度 阈值 都 有 一个 对应 的 限制 范围。每个 温度 阈值 会 关联 一对 状态 限制(下限 和 上限)。例如,在 某个 温度 阈值 下,冷却 设备 的 工作 状态 可能 被 限制 在 一定 的 范围 内。 说明:如果
binding_limits为NULL,则表示 没有 对 冷却 设备 的 状态 进行 限制,所有 温度 阈值 上 的 冷却 设备 都 没有 任何 限制。
5) match (int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev))
int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev);
类型:一个
函数指针,指向 一个 匹配 函数。 功能:这是
一个 回调 函数,用于 匹配 冷却 设备 与 热区 设备 是否 适配。具体来说, match函数会 根据 当前 热区( tz)和冷却 设备( cdev)的特性,返回 一个整 数值,通常 是 0表示匹配 成功,非 0表示匹配 失败。 说明:这个
函数 使得 系统 能够 根据 冷却 设备 与 热区 设备 的 具体 特性,决定 是否 绑定 它们。
thermal_instance
struct thermal_instance {
int id;
char name[THERMAL_NAME_LENGTH];
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
bool initialized;
unsigned long upper; /* Highest cooling state for this trip point */
unsigned long lower; /* Lowest cooling state for this trip point */
unsigned long target; /* expected cooling state */
char attr_name[THERMAL_NAME_LENGTH];
struct device_attribute attr;
char weight_attr_name[THERMAL_NAME_LENGTH];
struct device_attribute weight_attr;
struct list_head tz_node; /* node in tz->thermal_instances */
struct list_head cdev_node; /* node in cdev->thermal_instances */
unsigned int weight; /* The weight of the cooling device */
};
结构thermal_instance,用于
1) id (int id)
int id;
类型:整数
类型。 功能:唯一
标识 一个 thermal_instance。它可以 用来 区分 不同 的 冷却 设备 实例,即使 它们 处在 同一个 热区 和 相同 的 温度 阈值 下。
2) name (char name[THERMAL_NAME_LENGTH])
char name[THERMAL_NAME_LENGTH];
类型:字符
数组,用来 存储 实例 的 名称。 功能:该
名称 用于 标识 当前 冷却 设备 实例。 THERMAL_NAME_LENGTH是一个 宏,定义 了 名称 的 最大 长度。名称 一般 用于 调试 或 日志 中,帮助 开发者 理解 当前 的 冷却 设备 实例。
3) tz (struct thermal_zone_device *tz)
struct thermal_zone_device *tz;
类型:指向
thermal_zone_device结构的 指针。 功能:指向
该 冷却 设备 所 绑定 的 热区(thermal zone)。热区 代表 一个 监控 和 控制 温度 的 区域,可能 是 一个 物理 区域 或 系统 中 的 某个 硬件 组件。这个 成员 表示 冷却 设备 在 某个 热区 的 行为。
4) cdev (struct thermal_cooling_device *cdev)
struct thermal_cooling_device *cdev;
类型:指向
thermal_cooling_device结构的 指针。 功能:指向
冷却 设备(cooling device)。冷却 设备 通常 是 硬件 组件(如 风扇、散热片 等)或 软件 控制 机制,用于 降低 热区 的 温度。
5) trip (int trip)
int trip;
类型:整数
类型。 功能:表示
与 该 冷却 设备 实例 关联 的 温度 阈值(trip point)的 索引。热区 通常 有 多个 温度 阈值,每个 阈值 对应 不同 的 冷却 策略。 trip用来指定 当前 实例 针对 哪个 阈值 的 冷却 行为。
6) initialized (bool initialized)
bool initialized;
类型:布尔
类型。 功能:表示
该 冷却 设备 实例 是否 已 被 初始化。如果 为 true,表示该 实例 已经 初始化 并 准备 使用。如果 为 false,则说明 该 实例 还 没有 初始化。
7) upper (unsigned long upper)
unsigned long upper;
类型:无
符号长 整型。 功能:表示
该 冷却 设备 在 指定 温度 阈值 下 的 最高 冷却 状态。冷却 状态 通常 表示 设备 的 工作 强度(例如,风扇 的 转速)。 upper表示该 冷却 设备 能 达到 的 最高 状态。
8) lower (unsigned long lower)
unsigned long lower;
类型:无
符号长 整型。 功能:表示
该 冷却 设备 在 指定 温度 阈值 下 的 最低 冷却 状态。与 upper相对,lower表示冷却 设备 在 该 温度 阈值 下 的 最小 工作 强度。
9) target (unsigned long target)
unsigned long target;
类型:无
符号长 整型。 功能:表示
当前 预期 的 冷却 状态。这个 状态 是 根据 温度 阈值 和 热区 的 需求 来 动态 计算 的,系统 会 尝试 使 冷却 设备 达到 该 目标 状态。
10) attr_name (char attr_name[THERMAL_NAME_LENGTH])
char attr_name[THERMAL_NAME_LENGTH];
类型:字符
数组。 功能:存储
与 该 冷却 设备 实例 相关 的 属性 名称。属性 名称 用于 在 系统 的 设备树 或 文件系统 中 创建 文件,使 用户 可以 访问 和 控制 冷却 设备 的 状态。
11) attr (struct device_attribute attr)
struct device_attribute attr;
类型:
device_attribute结构体。 功能:表示
与 冷却 设备 实例 相关 的 设备 属性。这 通常 用于 设备 的 sysfs 接口,允许 用户 空间 与 内核 空间 之间 交换 信息。例如,通过 attr用户可以 控制 冷却 设备 的 工作 状态。
12) weight_attr_name (char weight_attr_name[THERMAL_NAME_LENGTH])
char weight_attr_name[THERMAL_NAME_LENGTH];
类型:字符
数组。 功能:存储
冷却 设备 权重 属性 的 名称。冷却 设备 的 权重 通常 用于 决定 该 设备 在 热 管理 中 的 优先级 和 冷却 效果。
13) weight_attr (struct device_attribute weight_attr)
struct device_attribute weight_attr;
类型:
device_attribute结构体。 功能:表示
与 冷却 设备 权重 相关 的 设备 属性。这 通常 在 sysfs 中 作为 一个 接口 提供 给 用户 空间,让 用户 可以 调整 冷却 设备 的 权重,从而 影响 系统 的 热 管理策略。
14) tz_node (struct list_head tz_node)
struct list_head tz_node;
类型:
list_head结构。功能:该
节点 用于 将 当前 thermal_instance添加到 热区 设备( tz)的实例 链表 中。每个 热区 可以 包含 多个 冷却 设备 实例,这个 节点 帮助 组织 热区 下 所有 冷却 设备 实例 的 链表 结构。
15) cdev_node (struct list_head cdev_node)
struct list_head cdev_node;
类型:
list_head结构。功能:该
节点 用于 将 当前 thermal_instance添加到 冷却 设备( cdev)的实例 链表 中。每个 冷却 设备 可以 在 多个 热区 中 使用,这个 节点 帮助 组织 冷却 设备 下 所有 实例 的 链表 结构。
16) weight (unsigned int weight)
unsigned int weight;
类型:无
符号 整数。 功能:表示
该 冷却 设备 的 权重。权重 值 通常 用于 决策 热 管理 中 的 冷却 策略,较 高 的 权重 表示 冷却 效果 较强。它 影响 该 冷却 设备 在 热区 中 的 调度 和 优先级。
Thermal 关键函数接口说明
Thermal core 是 Thermal Zone、Thermal Cooling 和 Thermal Governor 之间
具体来说,Thermal core 通过
从 Thermal Zone 获取
温度 :首先,通过 Thermal Zone 设备获取 当前 的 温度 值。 选择
对应 :根据的 Thermal Governor 温度 值,选择 适当 的 Thermal Governor 来 管理 温控 策略。 控制 Thermal Cooling 设备:根据 Thermal Governor 的
设置,调整 Thermal Cooling 设备 的 状态,从而 达到 温度 调节 的 目的。
设备
注册 Thermal Zone 设备:通过
调用 thermal_zone_device_register(),注册 thermal zone 设备,并创建 一系列 sysfs 节点,同时 将 其 与 相应 的 governor 和 cooling 设备 进行 绑定。 注销 Thermal Zone 设备:
thermal_zone_device_unregister()函数执行 相反 的 操作,移除 thermal zone 设备,解除 与 cooling 设备 的 绑定,并 删除 相应 的 sysfs 节点。
Cooling 设备
注册 Cooling 设备:通过
thermal_cooling_device_register()创建 cooling 设备,将其 加入 到 thermal_cdev_list中,并为 cooling 设备 创建 相关 的 sysfs 节点。此时,cooling 设备 与 thermal zone 设备 进行 绑定。 注销 Cooling 设备:
thermal_cooling_device_unregister()执行相反 的 操作,解除 cooling 设备 与 thermal zone 的 绑定,并 移除 相关 的 sysfs 节点。
Governor 的
注册 Thermal Governor:
thermal_register_governor()首先会 检查 thermal_governor_list中是否 已有 同名 governor,如果 没有,则 将 其 添加 到 列表 中,并 更新 thermal_tz_list中未指定 governor 的 thermal zone。 注销 Thermal Governor:通过
thermal_unregister_governor(),将指定 的 governor 与其 绑定 的 thermal zone 解除 绑定,并 调用 unbind_from_tz()清空相关 数据,最后 从 thermal_go中移除 该 governor。
设备
绑定 Cooling 设备
到 Thermal Zone :thermal_zone_bind_cooling_device()通过创建 thermal_instances设备,将 Thermal Zone 与 Thermal Cooling 设备进行 绑定,从而 实现 基于 温度 的 Cooling 设备 控制。 解绑 Cooling 设备:
thermal_zone_unbind_cooling_device()将已 绑定 的 thermal_instances从两者 的 链表 中 移除,解除 绑定 关系。
温度
更新 Thermal Zone 的
温度 :thermal_zone_device_update()一般由 Thermal 驱动 触发,可能 是 通过 polling 或 中断 方式 更新 当前 的 温度 值,并 根据 温度 变化 通过 handle_thermal_trip()进行相应 的 处理。
监控
监控 Thermal Zone:
monitor_thermal_zone()根据 passive 或 polling 设置决定 是否 启动 thermal_zone_device->pool_queue这个延时 工作 项(delayed_work)。 Polling 流程:整个 polling 流程
由 thermal_zone_device_update()触发,具体流程 如下: 在
handle_thermal_trip()中启动 monitor_thermal_zone()。在
monitor_thermal_zone()中,调用mod_delayed_work()更新 poll_queue 的延时 值。如果 thermal zone 有 多个 trip,poll_queue 的 延时 值 可能 会 多次 更新。 poll_queue 被
放入 system_freezable_wq后,达到设定 时间 后,调用 thermal_zone_device_check(),进而调用 thermal_zone_device_update()完成周期性 更新 和 处理。
上述

下面
thermal_set_governor 函数
功能:
切换
函数
static int thermal_set_governor(struct thermal_zone_device *tz,
struct thermal_governor *new_gov)
参数:
tz: 指向热区 设备 的 指针。 new_gov: 新的 热 政策。
逻辑:
如果
当前 热区 已有 绑定 的 热 政策,先 调用 其 unbind_from_tz方法解除 绑定。 如果
新热 政策 存在 且 有 bind_to_tz方法,尝试绑定 到 热区。 如果
绑定 失败,尝试 恢复 到 之前 的 热 政策。 最后,更新
热区 的 热 政策 指针。
返回值:
成功
时 返回0,绑定 新热 政策 失败 时 返回 错误码。
thermal_register_governor 函数
功能:
注册
函数
int thermal_register_governor(struct thermal_governor *governor)
参数:
governor: 要注册 的 热 政策。
逻辑:
检查
热 政策 是否 已 存在。 如果
不 存在,将 其 添加 到 热 政策 列表,并 设置 默认 热 政策(如果 匹配)。 遍历
所有 热区,尝试 将 新 热 政策 应用 到 每个 热区。
返回值:
成功
时 返回0,失败 时 返回 错误码。
thermal_unregister_governor 函数
功能:
注销
函数
void thermal_unregister_governor(struct thermal_governor *governor)
参数:
governor: 要注销 的 热 政策。
逻辑:
从
热 政策 列表 中 移除 指定 的 热 政策。 遍历
所有 热区,将 使用 该 热 政策 的 热区 恢复 到 默认 热 政策。
update_temperature 函数
功能:
更新
函数
static void update_temperature(struct thermal_zone_device *tz)
参数:
tz: 指向热区 设备 的 指针。
逻辑:
调用
thermal_zone_get_temp函数读取 温度。 更新
热区 设备 的 温度 值。 如果
温度 有效,触发 相应 的 通知。
thermal_zone_device_update 函数
功能:
更新
函数
void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
参数:
tz: 指向热区 设备 的 指针。 event: 触发更新 的 事件 类型。
逻辑:
检查
系统 是否 挂 起,如果 是 则 直接 返回。 更新
温度。 处理
所有 的 温度 阈值(trip points)。 根据
需要 调整 轮询 频率。
thermal_zone_device_check 函数
功能:
作为
函数
static void thermal_zone_device_check(struct work_struct *work)
参数:
work: 工作队列 的 结构 体 指针。
逻辑:
调用
thermal_zone_device_update函数更新 热区 设备 的 状态。
thermal_zone_bind_cooling_device 函数
功能:
将
函数
int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
int trip,
struct thermal_cooling_device *cdev,
unsigned long upper, unsigned long lower,
unsigned int weight)
参数:
tz: 热区设备。 trip: 温度阈值 索引。 cdev: 冷却设备。 upper: 最高冷却 状态。 lower: 最低冷却 状态。 weight: 冷却设备 权重。
逻辑:
检查
参数 有效性。 创建
一个 新 的 thermal_instance结构体,表示 冷却 设备 与 热区 的 绑定。 更新 sysfs 接口
以 反映 新 的 绑定 关系。
返回值:
成功
时 返回0,失败 时 返回 错误码。
thermal_zone_unbind_cooling_device 函数
功能:
从
函数
int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip,
struct thermal_cooling_device *cdev)
参数:
tz: 热区设备。 trip: 温度阈值 索引。 cdev: 冷却设备。
逻辑:
找到
对应 的 thermal_instance结构体,并 从 列表 中 移除。 更新 sysfs 接口
以 反映 解绑 关系。
返回值:
成功
时 返回0,失败 时 返回 错误码。
thermal_cooling_device_unregister 函数
功能:
注销
函数
void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
参数:
cdev: 要注销 的 冷却 设备。
逻辑:
从
冷却 设备 列表 中 移除 指定 的 冷却 设备。 解绑
所有 与 该 冷却 设备 关联 的 热区。
bind_tz 函数
功能:
将
函数
static void bind_tz(struct thermal_zone_device *tz)
参数:
tz: 热区设备。
逻辑:
遍历
所有 冷却 设备,尝试 将 每个 冷却 设备 绑定 到 热区。
thermal_zone_device_register_with_trips 函数
功能:
创建
函数
struct thermal_zone_device *
thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask,
void *devdata, struct thermal_zone_device_ops *ops,
struct thermal_zone_params *tzp, int passive_delay,
int polling_delay)
参数:
type: 热区名称。 trips: 温度阈值 数组。 num_trips: 温度阈值 数量。 mask: 温度阈值 掩码。 devdata: 私有数据。 ops: 热区操作 接口。 tzp: 热区参数。 passive_delay: 被动冷却 延迟。 polling_delay: 轮询延迟。
逻辑:
初始化
热区 设备。 注册
设备 到 sysfs。 绑定
冷却 设备。 设置
轮询 和 延迟。
返回值:
成功
时 返回 热区 设备 指针,失败 时 返回 错误 指针。
thermal_zone_device_unregister 函数
功能:
注销
函数
void thermal_zone_device_unregister(struct thermal_zone_device *tz)
参数:
tz: 热区设备。
逻辑:
从
热区 列表 中 移除 热区。 解绑
所有 冷却 设备。 注销
设备。
thermal_init 函数
功能:
初始化
函数
static int __init thermal_init(void)
逻辑:
注册
热 政策。 注册
热类(thermal class)。 注册 PM 通知
器。
返回值:
成功
时 返回0,失败 时 返回 错误码。
4.3.14.5. 驱动平台 thermal 系统调试说明
在/sys/class/hwmon/hwmon0 目录temp1_input 是 DDR 的temp2_input 是 BPU 的temp3_input 是 CPU 的
root@buildroot:~# ls /sys/class/hwmon/hwmon0/ | grep temp
temp1_input
temp2_input
temp3_input
温度
cat /sys/class/hwmon/hwmon0/temp1_input
46643
上述
注意:BPU 的
目前
cat /sys/class/thermal/thermal_zone0/policy
step_wise
通过
cat /sys/class/thermal/thermal_zone0/available_policies
user_space step_wise
user_space 是
通过 uevent 将 温区 当前 温度,温控 触发 点 等 信息 上报 到 用户 空间,由 用户 空间 软件 制定 温控 的 策略。 step_wise 是
每个 轮询 周期 逐级 提高 冷却 状态,是 一种 相对 温和 的 温控 策略
具体
echo user_space > /sys/class/thermal/thermal_zone0/policy
在 thermal_zone0 中有1个 trip_point,用于
可
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
若想
echo 85000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
在 thermal_zone1中有3个 trip_point,其中:
trip_point_0_temp 为
预留 作用。 trip_point_1_temp 是
该 thermal zone 的 调频 温度,可 控制 CPU/BPU/GPU 的 频率,当前 设置 为95度。 trip_point_2_temp 为
关机 温度,当前 设置 为105度。
例如
echo 85000 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp
如果
echo 105000 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_2_temp
ps:以上
4.3.14.6. thermal参考文档
以下
./Documentation/devicetree/bindings/thermal
./Documentation/driver-api/thermal