linux thermal framework(1)_概述
原文来源:蜗窝科技linux thermal framework(1)_概述
1. 介绍
热能是电子器件在通电工作后散发能量的主要方式之一,电子器件(cpu、电源适配器等)中的电阻、晶体管、集成电路等元件在工作中,电流通过
导体,电子与原子碰撞,导致能量以热能形式散发。
在手持移动设备(手机、手表等)中,由于接触人体皮肤,保证设备的温度在人体可接受范围内是重要的一个研发方向,硬件上可以通过选择更低功耗的电子器件或者在设备内部添加散热材料,比方说导热凝胶、石墨片、金属散热片等,来降低温度,软件上一般可以通过温度监控和动态频率调节减少热量产生的方式来降温。
linux thermal framework是在kernel层面,通过监控器件温度,动态调节频率等方法管理设备温度。
本文简单介绍了linux thermal framework的主要功能和接口设计
2. 功能描述
thermal framework按照一定的频率循环查询设备温度,设备通常有电池、cpu、主板,同时根据一定的算法,通过将某些设备降低使用率或者增加散热来使设备降温,如果设备发热超过一定阈值,必要时会通过整机重启来防止设备过热损坏。
为了实现上述功能需求,thermal framework抽象出thermal sensor、thermal zone、cooling device、thermal governor等多个软件实体,通过和其他模块的交互使用可达到软件控温的功能,具体可看下述软件结构说明。
3. 软件结构
thermal framework的软件结构如下图所示:
thermal core是linux温控的统一框架,为了能在内核层面进行温控,thermal core的具体思路是实时监控一个平台上各个关键区域的温度,这些关键区域通常是几大热源:cpu/gpu/battery等,当这些关键区域的温度达到一定程度,会采取必要措施,一般这些措施有降频/限制器件工作速率等,具体应该限制多少程度,thermal core提供了一些算法(governors)来供选择。
thermal zone是被抽象出来描述平台上一块区域温度的数据结构,它并不是一个实际存在的设备,一般是通过平台上的温度传感器设备向thermal core注册的,它的主要功能是,通过传感器设备提供的温度获取函数,可以向thermal core提供不同器件的温度信息。
cooling device是被抽象出来描述平台上一个可以降温的数据结构,同样的,他也不是一个实际存在的设备,一般是其他模块向thermal core注册的,这些模块可以是cpufreq/devfreq/cpuidle,这些模块有共同的特点,即他们可以通过限制器件的工作状态来降温。
thermal governor可以根据thermal zone的温度信息,根据一定的算法,将cooling device设置为某一个状态来控温。
thermal core通过sysfs/debugfs向用户空间提供接口,sysfs的接口通常包括thermal zone/cooling device/governor的信息,上层应用可以通过sysfs接口来获取温度信息,使用的温控策略信息等等,另外用户可以通过sysfs接口来设置温控策略,切换不同的温控策略用来选择不同场景最合适的温控算法。
4. 软件模块的功能和API描述
我们在这个章节简单介绍thermal core对外提供的几个关键数据结构以及API。
4.1 struct thermal_zone_device
struct thermal_zone_device是被用来描述平台上一片区域温度的数据结构,定义如下:
kernel-6.6/include/linux/thermal.h
/**
* struct thermal_zone_device - 温控区域核心结构体
* 实现硬件温度监控与动态冷却策略的枢纽
*/
struct thermal_zone_device {
/*-------------------------------------------
* 标识与基础属性
*-----------------------------------------*/
//1)id,每个thermal zone都有一个id作为区分,每个id是在thermal zone向thermal core注册的时候通过ida被分配
int id;
//2)type,用来说明描述的哪一片区域的温度,每个thermal zone有唯一一个type,类型通常会有soc/gpu/battery/charger/board等等
char type[THERMAL_NAME_LENGTH]; // 如"soc"/"gpu"/"battery"
struct device device; // 对应的Linux设备对象
/*-------------------------------------------
* 触发点(Trip Points)管理
*-----------------------------------------*/
//4)trips,thermal zone使用trips作为温度的档位,具体来说,当一个thermal zone的温度达到了某一个trip表示的档位,就会触发相应的调整措施,
//通常会按照温度高低有不同的档位,thermal zone使用数组和链表来管理trips
struct attribute_group trips_attribute_group; // sysfs属性组
struct thermal_attr *trip_temp_attrs; // trip温度属性数组
struct thermal_attr *trip_type_attrs; // trip类型属性数组
struct thermal_attr *trip_hyst_attrs; // 滞后值属性数组
struct thermal_trip *trips; // 硬件触发点配置数组
int num_trips; // 有效触发点数量
unsigned long trips_disabled; // 禁用触发点的位图
/*-------------------------------------------
* 温度状态监控
*-----------------------------------------*/
//5)temperature,这个thermal zone的温度
int temperature; // 当前温度(毫摄氏度)
int last_temperature; // 上次记录温度
int emul_temperature; // 模拟温度(调试用)
enum thermal_device_mode mode; // 启用/禁用状态
atomic_t need_update; // 原子标记位,指示需要更新状态
/*-------------------------------------------
* 冷却策略控制
*-----------------------------------------*/
//7)governor,这个thermal zone使用的governor,governor是控温的算法,根据这个thermal zone的当前温度以及过往温度来判断用什么措施来控温
struct thermal_governor *governor; // 绑定的调控算法
void *governor_data; // 算法私有数据
int passive; // 被动冷却状态标志位
int prev_low_trip; // 被动冷却进入前的低温阈值
int prev_high_trip; // 被动冷却进入前的高温阈值
/*-------------------------------------------
* 时间控制参数
*-----------------------------------------*/
unsigned long passive_delay_jiffies; // 被动冷却轮询间隔
unsigned long polling_delay_jiffies; // 主动轮询间隔(0=中断驱动)
/*-------------------------------------------
* 操作回调与硬件交互
*-----------------------------------------*/
//6)ops,这个thermal zone的回调函数,一般都会有get_temp回调函数来获取温度
struct thermal_zone_device_ops *ops; // 硬件操作回调集
struct thermal_zone_params *tzp; // 平台特定参数
void *devdata; // 驱动私有数据指针
/*-------------------------------------------
* 冷却设备关联
*-----------------------------------------*/
struct list_head thermal_instances; // 关联的冷却设备实例链表
struct ida ida; // 冷却设备ID分配器
/*-------------------------------------------
* 并发控制
*-----------------------------------------*/
struct mutex lock; // 保护thermal_instances的互斥锁
/*-------------------------------------------
* 系统集成
*-----------------------------------------*/
struct list_head node; // 全局thermal_tz_list链表节点
//8)poll_queue,每个thermal zone都有一个work,被用来轮巡检测温度,必要时采取措施控制
struct delayed_work poll_queue; // 延迟工作项(温度轮询)
enum thermal_notify_event notify_event; // 最近通知事件
bool suspended; // 挂起状态标志
/*-------------------------------------------
* 安卓特定扩展
*-----------------------------------------*/
ANDROID_KABI_RESERVE(1); // 安卓内核ABI兼容保留字段
};
1)id,每个thermal zone都有一个id作为区分,每个id是在thermal zone向thermal core注册的时候通过ida被分配
2)type,用来说明描述的哪一片区域的温度,每个thermal zone有唯一一个type,类型通常会有soc/gpu/battery/charger/board等等
3)device,thermal zone也是一个抽象出来的设备,因此有一个device数据结构
4)trips,thermal zone使用trips作为温度的档位,具体来说,当一个thermal zone的温度达到了某一个trip表示的档位,就会触发相应的调整措施,通常会按照温度高低有不同的档位,thermal zone使用数组和链表来管理trips
5)temperature,这个thermal zone的温度
6)ops,这个thermal zone的回调函数,一般都会有get_temp回调函数来获取温度
7)governor,这个thermal zone使用的governor,governor是控温的算法,根据这个thermal zone的当前温度以及过往温度来判断用什么措施来控温
8)poll_queue,每个thermal zone都有一个work,被用来轮巡检测温度,必要时采取措施控制
有关struct thermal_zone_device的API主要包括注册和注销,以及获取温度信息等接口
kernel-6.6/include/linux/thermal.h
/*---------------------------------------------
* 设备树温控区域管理函数声明
* 这些函数通常在芯片thermal驱动初始化时调用
*-------------------------------------------*/
#ifdef CONFIG_THERMAL_OF // 仅在启用设备树温控配置时编译
/**
* devm_thermal_of_zone_register - 设备树温控区域注册函数(自动资源管理版本)
* @dev: 所属设备结构体指针(通常为&pdev->dev)
* @id: 温控区域标识符(传-1可自动分配)
* @data: 驱动私有数据指针(会存入tz->devdata)
* @ops: 温控操作集(必须实现get_temp/set_trips等回调)
*
* 典型调用场景:
* 在平台驱动probe()中注册,如:
* tz = devm_thermal_of_zone_register(&pdev->dev, 0, priv, &foo_thermal_ops);
*
* 返回值:成功返回thermal_zone_device指针,失败返回ERR_PTR
*/
struct thermal_zone_device *devm_thermal_of_zone_register(
struct device *dev, // 关联的父设备
int id, // 温控区域ID(设备树中的#thermal-sensor-cells决定)
void *data, // 驱动私有数据(如寄存器基地址)
const struct thermal_zone_device_ops *ops // 必须实现的操作回调
);
/**
* devm_thermal_of_zone_unregister - 自动管理的温控区域注销函数
* @dev: 与注册时相同的设备指针(用于资源管理)
* @tz: 要注销的thermal_zone_device指针
*
* 注意:通常不需要显式调用,devres机制会在设备detach时自动处理
*/
void devm_thermal_of_zone_unregister(
struct device *dev, // 关联的父设备
struct thermal_zone_device *tz // 要释放的温控区域
);
/*---------------------------------------------
* 内联工具函数(当CONFIG_THERMAL_OF未启用时的桩函数)
*-------------------------------------------*/
/**
* thermal_zone_get_zone_by_name - 通过名称查找温控区域(桩函数)
* @name: 温控区域类型名(如"soc-thermal")
*
* 注:此为桩函数,实际功能需启用CONFIG_THERMAL_OF
* 返回值:始终返回ENODEV错误指针
*/
static inline struct thermal_zone_device *thermal_zone_get_zone_by_name(
const char *name) // 要查找的温控区域类型名
{
return ERR_PTR(-ENODEV); // 直接返回"设备不存在"错误
}
/**
* thermal_zone_get_temp - 获取温控区域当前温度(桩函数)
* @tz: 温控区域指针
* @temp: 输出温度值(毫摄氏度)
*
* 返回值:始终返回ENODEV错误码
*/
static inline int thermal_zone_get_temp(
struct thermal_zone_device *tz, // 目标温控区域(实际未使用)
int *temp // 温度输出指针
) {
return -ENODEV; // 返回"设备不存在"错误码
}
#endif /* CONFIG_THERMAL_OF */
4.2 struct thermal_cooling_device
struct thermal_cooling_device是被用来描述平台上可降温设备的数据结构,定义如下:
kernel-6.6/include/linux/thermal.h
/**
* struct thermal_cooling_device - 冷却设备核心结构体
* 实现温度调控的执行单元(如风扇/降频等)
*/
struct thermal_cooling_device {
/*-------------------------------------------
* 标识与基础属性
*-----------------------------------------*/
//1)id,同样的,每个cooling device都有一个id作为区分,这个id也是在注册的时候通过ida分配
int id; // 唯一标识符,通过ida_alloc_range()分配
//2)type,用来说明描述的哪一种类型的cooling device,一般这个type会有cpufreq/devfreq等
char *type; // 冷却类型,常见值:
// "cpufreq" - CPU调频
// "devfreq" - 设备动态调频
// "fan" - 风扇控制
//3)max_state,cooling device会有若干个state,governor通过不断的调整这些state来控制温度
unsigned long max_state; // 最大冷却级别(从0开始计数)
// 例如:CPU可能有16个降频档位
//4)device,cooling device也是一个抽象出来的设备,因此有一个device数据结构
struct device device; // Linux设备模型基类
// 对应/sys/class/thermal/cooling_deviceX/
/*-------------------------------------------
* 设备树与数据存储
*-----------------------------------------*/
struct device_node *np; // 关联的设备树节点(可选)
void *devdata; // 驱动私有数据(如寄存器地址)
void *stats; // 统计信息存储(由框架管理)
/*-------------------------------------------
* 操作回调
*-----------------------------------------*/
//5)ops,这个cooling device的回调函数
const struct thermal_cooling_device_ops *ops; // 必须实现:
// get_max_state
// get_cur_state
// set_cur_state
/*-------------------------------------------
* 状态管理
*-----------------------------------------*/
bool updated; // 标记设备状态是否需要更新
// true表示状态已同步无需操作
/*-------------------------------------------
* 并发控制与关联关系
*-----------------------------------------*/
struct mutex lock; // 保护thermal_instances的互斥锁
struct list_head thermal_instances; // 关联的温控实例链表
// 每个实例对应一个thermal_zone绑定
struct list_head node; // 全局cooling_dev_list链表节点
/*-------------------------------------------
* 安卓特定扩展
*-----------------------------------------*/
ANDROID_KABI_RESERVE(1); // 安卓内核ABI兼容保留字段
};
1)id,同样的,每个cooling device都有一个id作为区分,这个id也是在注册的时候通过ida分配
2)type,用来说明描述的哪一种类型的cooling device,一般这个type会有cpufreq/devfreq等
3)device,cooling device也是一个抽象出来的设备,因此有一个device数据结构
4)max_state,cooling device会有若干个state,governor通过不断的调整这些state来控制温度
5)ops,这个cooling device的回调函数
有关struct thermal_cooling_device的API主要包括注册和注销:
struct thermal_cooling_device *
thermal_of_cooling_device_register(struct device_node *np, const char *, void *,
const struct thermal_cooling_device_ops *);
void thermal_cooling_device_unregister(struct thermal_cooling_device *);
4.3 struct thermal_governor
struct thermal_governor是被用来确定cooling device的state来控温的,定义如下:
kernel-6.6/include/linux/thermal.h
/**
* struct thermal_governor - 温控调控器核心结构体
* 实现温度调控算法的决策逻辑单元
*/
struct thermal_governor {
/*-------------------------------------------
* 基础标识
*-----------------------------------------*/
//1)name, 每个governor会有一个名字,在温控的governors中,常见的有power_allocator/userspace/step_wise
char name[THERMAL_NAME_LENGTH]; // 调控算法名称,对应:
// "step_wise" - 渐进式调节
// "power_allocator" - 动态功耗分配
// "user_space" - 用户空间控制
/*-------------------------------------------
* 生命周期回调
*-----------------------------------------*/
//2)bind_to_tz, governor绑定thermal_zone的回调函数
int (*bind_to_tz)(struct thermal_zone_device *tz); // 绑定时的初始化操作
// 返回0表示成功
//3)unbind_from_tz,governor和thermal_zone解绑的回调函数
void (*unbind_from_tz)(struct thermal_zone_device *tz); // 解绑时的资源释放
/*-------------------------------------------
* 核心调控逻辑
*-----------------------------------------*/
/**
* @throttle - 温度调控决策函数
* @tz: 关联的温控区域
* @trip: 触发的trip point索引
*
* 注意:即使当前温度低于trip point也会被调用,
* 用于实现滞后控制等高级策略
*/
int (*throttle)(struct thermal_zone_device *tz, int trip);
/*-------------------------------------------
* 系统管理
*-----------------------------------------*/
//4)governor_list,thermal core通过一个链表来管理所有的governors,这个是该governor在链表中的节点
struct list_head governor_list; // 全局调控器链表节点
// 通过thermal_register_governor()注册
/*-------------------------------------------
* 安卓特定扩展
*-----------------------------------------*/
ANDROID_KABI_RESERVE(1); // 安卓内核ABI兼容保留字段
};
1)name, 每个governor会有一个名字,在温控的governors中,常见的有power_allocator/userspace/step_wise
2)bind_to_tz, governor绑定thermal_zone的回调函数
3)unbind_from_tz,governor和thermal_zone解绑的回调函数
4)governor_list,thermal core通过一个链表来管理所有的governors,这个是该governor在链表中的节点