OS: ubuntu 20.04、主板:biostar z490 GTN、风扇IO芯片:it8613E
lmsensors 可以获取 温度传感器 与 风扇的转速,也可以自定义调整风扇速度。
1、运行sensors-detect显示it8613E无驱动(如图)
it8613E不是一个新的芯片,所以没有驱动linux很奇怪。
github上找到了https://github.com/a1wong/it87
2、按照readme安装it87报错 Device or resource busy
dmesg显示存在地址冲突
modprobe it87 ignore_resource_conflict=1 # 忽略冲突
发现在我的主板上不解决冲突也可以使用了、只是无法获取两个风扇口的转速。
如果想要解决这个地址冲突、需要修改dsdt。现在需要重新编译内核才可以修改dsdt。
编译内核太慢了,治好了我的强迫症。
3、执行pwmconfig选择该选的。之后就可以在sensors里面看到风扇了。
可以通过修改 /sys/class/hwmon/hwmon*/pwm*修改风扇pwm值。
如果不能修改 修改对应的enable文件:
echo 0 2>/dev/null > /sys/class/hwmon/hwmon*/pwm*_enable
4、我的小机箱是上下风道,风扇控制策略应该是:
使用max(cpu温度,gpu温度)控制上下的风扇。gpu风扇仍然由gpu的bios控制。主板及硬盘被动散热即可。
写了个脚本,主要逻辑就是获取cpu gpu温度,控温区间为50-85°,对应的pwm范围是70-255.
50°以下风扇处于最安静状态、82°就快达到降频温度了。pwm的70是因为以下转速不再变小,应该是bios的安全策略。
温度-pwm曲线 大概长下面这样
fan.sh & fan.py:
#!/bin/bash
echo "Hello FanS !"
sleep 20s
# 忽略硬件地址冲突
modprobe it87 ignore_resource_conflict=1
echo 0 2>/dev/null > /sys/class/hwmon/hwmon6/pwm5_enable
echo 0 2>/dev/null > /sys/class/hwmon/hwmon6/pwm2_enablewhile true;dogpu_msg=`nvidia-smi`cpu_msg=` sensors | grep 'Package id 0:'`pwm_val=`python3 /hxy/software/fan/fan.py "$cpu_msg" "$gpu_msg"`echo $pwm_val > /sys/class/hwmon/hwmon6/pwm2echo $pwm_val > /sys/class/hwmon/hwmon6/pwm5sleep 1s
done
import re
import sys
import logging
logging.basicConfig(filename=r'fan.err', level=logging.INFO)cpu_temp=100
gpu_temp=100
temp1,temp2=50,82
pwm1,pwm2=70,255
pattern1 = r'[+-]{0,1}[0-9]{1,3}[.]{0,1}[0-9]{0,3}[ ]{0,1}[°]{0,1}[c,C] ' # msg -> '+38.2 °C ' or '8C '
pattern2 = r'[0-9]{1,3}[.]{0,1}[0-9]{0,3}' # '+38.2°C ' -> '38.2'
fan1=r'/sys/class/hwmon/hwmon6/pwm2'
fan2=r'/sys/class/hwmon/hwmon6/pwm5'
pwm_res=pwm2
def my_log(*args):logging.error(str(args))if len(sys.argv) == 3:cpu_msg = sys.argv[1]gpu_msg = sys.argv[2]
else:my_log ('arg err',sys.argv)exit()def get_cpu_temp():cpu_res1=re.findall(pattern1,cpu_msg)if len(cpu_res1)>0:cpu_res2=re.findall(pattern2,cpu_res1[0])if len(cpu_res2)>0:cpu_temp=float(cpu_res2[0])if cpu_temp>-30 and cpu_temp<110:return cpu_tempmy_log ('cpu err',cpu_temp,cpu_msg)return temp2def get_gpu_temp():gpu_res1=re.findall(pattern1,gpu_msg)if len(gpu_res1)>0:gpu_res2=re.findall(pattern2,gpu_res1[0])if len(gpu_res2)>0:gpu_temp=float(gpu_res2[0])if gpu_temp>-30 and gpu_temp<110:return gpu_tempmy_log ('gpu err',gpu_temp,gpu_msg)return temp2def get_max_temp(): cpu_temp=get_cpu_temp()gpu_temp=get_gpu_temp()temp_max=max(cpu_temp,gpu_temp) return temp_maxdef temp2pwm(temp_max):pwm_val= int((min(temp2,max(temp1,temp_max))-temp1)/(temp2-temp1) * (pwm2-pwm1)+pwm1)if pwm_val>=pwm1 and pwm_val<=pwm2:return pwm_valelse:my_log('pwm_err',pwm_val,sys.argv)return pwm2try:temp_max = get_max_temp()pwm_res = temp2pwm(temp_max)print(pwm_res)except BaseException:my_log ('python exception',sys.argv)