[linux thermal] power_supply_core和thermal_core的关系

本文解析了Linux内核中power_supply_core与thermal_core模块之间的交互机制。详细介绍了power_supply_core.c提供的电源管理接口及thermal_core.c提供的热管理接口,并通过实例展示了两者如何协同工作实现电池充电设备的热管理。

power_supply_core和thermal_core的关系

源代码版本k5.15

1、power_supply_core.c提供power supply的相关接口,比如:

struct power_supply *__must_check power_supply_register(struct device *parent,
		const struct power_supply_desc *desc,
		const struct power_supply_config *cfg)

2、thermal_core.c提供thermal相关的接口,比如:

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)
struct thermal_cooling_device *
thermal_cooling_device_register(const char *type, void *devdata,
				const struct thermal_cooling_device_ops *ops)

3、两者之间的关系

struct power_supply *__must_check power_supply_register() {
	//......
	rc = psy_register_thermal(psy);//-----> thermal_zone_device_register() 
	if (rc)
		goto register_thermal_failed;

	rc = psy_register_cooler(psy);//-----> thermal_cooling_device_register()
	if (rc)
		goto register_cooler_failed;
	//......
}

4、应用示例

charger-manager
电池充电设备驱动的热管理需要注册thermal zone device和thermal cooling device,在驱动注册时probe函数会调用
power_supply_register()来注册

static int charger_manager_probe(struct platform_device *pdev)
{
	struct charger_desc *desc = cm_get_drv_data(pdev);
	struct charger_manager *cm;
	
	//.........cm数据结构初始化
	cm->charger_psy = power_supply_register(&pdev->dev,
						&cm->charger_psy_desc,
						&psy_cfg);
	if (IS_ERR(cm->charger_psy)) {
		dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n",
			cm->charger_psy_desc.name);
		return PTR_ERR(cm->charger_psy);
	}
	//............
}

所以,在编码时需要注意其他模块对thermal的依赖。

5、参考链接

https://elixir.bootlin.com/linux/v5.15/source/drivers/thermal/thermal_core.c
https://elixir.bootlin.com/linux/v5.15/source/drivers/power/supply/power_supply_core.c
https://elixir.bootlin.com/linux/v5.15/source/drivers/power/supply/charger-manager.c

<think> 我们正在解决的问题:执行从sysfs读取系统参数的bash脚本时,显示“温度传感器未找到”。 根据引用内容,特别是引用[3]提到“RK3399-linux5.10系统温度控制CPU/GPU性能调节测试脚本”,我们可以推测用户可能是在类似RK3399的嵌入式Linux系统上运行脚本,并且脚本需要读取温度传感器。 可能的原因及解决办法: 1. sysfs路径不正确:温度传感器在sysfs中的路径可能因内核版本、驱动加载情况或硬件差异而不同。需要确认正确的路径。 2. 驱动未加载:温度传感器驱动可能未加载,导致sysfs中不存在相应的设备节点。 3. 权限问题:执行脚本的用户可能没有读取sysfs节点的权限。 4. 硬件不存在:可能是硬件上没有该传感器,或者硬件故障。 步骤: 1. 确认温度传感器的sysfs路径: 通常,温度传感器位于`/sys/class/thermal/thermal_zoneX/temp`(X为数字)。我们可以通过以下命令列出所有thermal_zone: ls /sys/class/thermal/ 然后进入每个thermal_zone目录,查看type文件以确定传感器类型(如cpu、gpu等),并读取temp文件的值(注意:temp文件的值通常是毫摄氏度,即需要除以1000得到摄氏度)。 2. 检查驱动加载情况: 使用`dmesg | grep thermal`或`dmesg | grep temperature`查看内核日志,是否有温度传感器相关的驱动加载信息或错误信息。 3. 检查权限: 确保运行脚本的用户对sysfs中的温度文件有读取权限。通常需要root权限,或者在非root用户下通过udev规则设置权限。 4. 如果确认路径正确,但脚本仍然报错,可以尝试手动读取文件,看是否返回错误。 5. 如果以上步骤都无法解决,考虑硬件问题或内核配置问题。 根据引用[3]中提到的脚本,我们也可以参考其读取温度的方法。但是,如果系统没有相同的传感器(比如不是RK3399),则路径可能不同。 因此,我们可以编写一个更通用的脚本,先检测存在的thermal_zone,然后再读取。 示例脚本片段: ```bash #!/bin/bash # 查找所有thermal_zone zones=$(ls /sys/class/thermal/ | grep thermal_zone) found=0 for zone in $zones; do type=$(cat /sys/class/thermal/$zone/type) # 这里我们假设我们要找的是CPU温度传感器,常见的类型有"cpu"、"x86_pkg_temp"等,具体根据实际平台而定 if [ "$type" == "cpu" ]; then temp=$(cat /sys/class/thermal/$zone/temp) echo "CPU温度: $(($temp/1000))°C" found=1 fi done if [ $found -eq 0 ]; then echo "温度传感器未找到" exit 1 fi ``` 注意:上面的脚本只查找类型为"cpu"的温度传感器。实际中,传感器的类型名称可能不同,例如可能是"x86_pkg_temp"、"soc_thermal"、"rk3399-thermal"等。因此,需要根据实际系统调整。 另外,如果系统中存在多个温度传感器,也可以考虑全部列出,或者根据需求选择特定的传感器。 如果用户是在RK3399平台,我们可以参考引用[3]中的脚本,可能使用特定的路径。但为了通用性,建议使用上述方法。 如果问题仍然存在,可能需要检查内核配置是否支持温度传感器(CONFIG_THERMAL等),或者硬件是否存在问题。 此外,引用[2]提到bash的配置文件,虽然与温度读取无直接关系,但如果在用户登录环境方面有问题(比如PATH设置等),也可能影响脚本执行。但本问题中,错误信息直接是“温度传感器未找到”,所以主要问题应该在硬件或驱动层面。 最后,如果用户需要,我们可以生成一个更健壮的脚本来读取温度,并处理多种情况。 根据引用[4]关于shell变量名的提醒,在编写脚本时注意变量名的合法性。 因此,针对用户的问题,我们建议: 1. 使用手动方式检查sysfs路径是否存在。 2. 根据实际平台调整脚本中的传感器类型字符串。 3. 确保以root权限运行脚本,或者设置sysfs文件的权限。 如果用户没有root权限,可以尝试在/etc/udev/rules.d/下添加规则,例如: SUBSYSTEM=="thermal", MODE="0444" 然后重新加载udev规则或重启。 如果上述方法都不能解决,可能需要进一步的内核调试或硬件检查。 考虑到引用[1]提到initramfs阶段的不同shell提示,但与本问题关联不大,故不展开。 生成相关问题: 1. 如何在内核中启用温度传感器支持? 2. 如何为sysfs文件设置非root用户的读取权限? 3. 如何编写一个健壮的读取系统温度参数的bash脚本? 4. 嵌入式Linux系统中常见的温度传感器类型有哪些? 5. 如何通过dmesg诊断硬件驱动问题? </think> ### 解决执行sysfs读取脚本显示"温度传感器未找到"的问题 根据引用[3]提到的嵌入式系统温度控制原理引用[4]的Shell脚本编写规范,以下是系统化的解决方案: #### 1. **验证sysfs温度接口路径**(核心步骤) ```bash # 检查系统可用的温度传感器接口 ls -l /sys/class/thermal/thermal_zone*/type # 验证具体温度值读取(示例) cat /sys/class/thermal/thermal_zone0/temp ``` - 如果返回"No such file",说明内核未暴露温度接口[^3] - 正常情况应显示包含"cpu"、"gpu"等标识的路径(如`thermal_zone0`对应CPU) #### 2. **内核驱动检查** ```bash # 检查温度驱动模块加载 lsmod | grep -iE 'thermal|coretemp|k10temp' # 查看内核日志中的传感器检测记录 dmesg | grep -i thermal ``` - 若无输出,需加载对应驱动(例如Intel CPU:`modprobe coretemp`)[^3] - RK3399平台需确保`rockchip-thermal`驱动已启用[^3] #### 3. **脚本调试方案** ```bash #!/bin/bash # 引用[4]规范的变量命名 sensor_path="/sys/class/thermal" for zone in $(ls $sensor_path | grep thermal_zone); do sensor_type=$(cat "$sensor_path/$zone/type") temp_file="$sensor_path/$zone/temp" if [ -f "$temp_file" ]; then temp_val=$(cat "$temp_file") echo "发现传感器: $sensor_type | 温度: $(($temp_val/1000))°C" else echo "警告: $sensor_type 的温度接口不存在" >&2 fi done ``` - **权限处理**:添加`sudo`或配置udev规则(引用[2]的权限继承机制) - **错误处理**:`>/dev/null 2>&1`屏蔽冗余错误 #### 4. **硬件兼容性处理** - ARM设备(如RK3399)需在设备树启用传感器: ```dts &tsadc { status = "okay"; rockchip,hw-tshut-mode = <1>; /* 硬件关机模式 */ }; ``` - x86设备需在BIOS启用"ACPI Thermal Monitoring"[^3] #### 5. **替代数据源方案** 当sysfs不可用时: ```bash # 使用lm-sensors工具包 sudo apt install lm-sensors sensors | grep -i core # 读取IPMI数据(服务器适用) ipmitool sdr type temperature ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值