1. 项目初衷与目标
1.1 背景
本项目旨在为Raspberry Pi CM4/Seeed路由器设备实现完全基于 Device Tree Source (DTS) 的PWM风扇温控系统。相比于用户空间脚本方案,DTS方案具有以下优势:
- 内核级别的温度控制:响应速度快,延迟低
- 系统集成度高:与Linux thermal框架完美集成
- 配置简洁:一次配置,系统自动管理
- 硬件抽象:标准化的hwmon和thermal接口
1.2 技术目标
- PWM风扇硬件控制:通过GPIO12输出25kHz PWM信号控制风扇转速
- 转速反馈:通过GPIO17读取风扇转速信号(tachometer)
- 温度感知:集成CPU温度传感器
- 自动调速:根据CPU温度自动调节风扇转速
- 多级控制:实现4个温度阈值的分级冷却策略
2. Linux Thermal子系统深度解析
2.1 Thermal框架架构
Linux Thermal子系统采用经典的生产者-消费者模式:
┌─────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  Thermal Sensor │───▶│   Thermal Zone   │───▶│  Cooling Device  │
│   (温度传感器)   │    │   (热管理区域)    │    │   (冷却设备)      │
└─────────────────┘    └──────────────────┘    └──────────────────┘
│                        │                        │
▼                        ▼                        ▼
bcm2711_thermal         cpu-thermal zone           pwm-fan
(硬件温度传感器)         (温度管理策略)             (PWM风扇)
2.2 核心组件详解
2.2.1 Thermal Sensor (温度传感器)
- 功能:提供温度数据源
- 实现:BCM2711 SoC内置温度传感器
- 接口:通过thermal_zone0暴露温度值
2.2.2 Thermal Zone (热管理区域)
- 功能:定义温度管理策略和控制逻辑
- 组件:
- Trip Points:温度阈值点,定义何时触发冷却动作
- Cooling Maps:将trip points映射到具体的冷却设备动作
- Governor:热管理算法(如step_wise, power_allocator等)
 
2.2.3 Cooling Device (冷却设备)
- 功能:执行实际的冷却动作
- 状态:具有多个冷却级别(0-4),对应不同的冷却强度
- 实现:PWM风扇,通过调节占空比控制转速
2.3 Thermal Governors (热管理算法)
Thermal Governor是thermal子系统的核心算法,负责根据温度变化决定如何调整cooling device。不同的governor适用于不同的应用场景。
2.3.1 主要Governor类型
step_wise (阶梯式控制) - 推荐
温度变化趋势:    ↗️ ↗️ ↗️ ↘️ ↘️ ↘️
Cooling级别:    0→1→2→3→2→1→0
特点:逐级调整,平滑过渡
- 策略:根据温度阶梯式调整cooling device状态
- 算法逻辑:
- 温度上升超过trip point → cooling级别+1
- 温度下降低于(trip_point - hysteresis) → cooling级别-1
- 每次最多调整一个级别
 
- 适用场景:通用场景,特别适合PWM风扇控制
- 优点:稳定可靠,无振荡,适中的响应速度
- 缺点:在极端温度变化时响应相对较慢
power_allocator (功率分配算法)
系统状态:   [CPU: 70°C] [GPU: 65°C] [目标: 60°C]
功率预算:   总预算1000mW → CPU风扇:600mW, GPU风扇:400mW
特点:PID控制,精确分配
- 策略:基于PID控制器的功率预算分配
- 算法逻辑:
- 使用PID控制器计算所需总冷却功率
- 根据各cooling device的效率和权重分配功率
- 动态调整以维持目标温度
 
- 适用场景:复杂SoC系统,多热源多cooling device
- 优点:最优化控制,能耗效率高
- 缺点:配置复杂,需要精确的功率模型
bang_bang (开关式控制)
温度:      45°C → 65°C → 55°C → 45°C
风扇状态:   OFF → MAX → OFF → OFF
特点:简单粗暴,要么全开要么全关
- 策略:简单的开/关控制
- 算法逻辑:
- 温度 > trip_point → 最大冷却
- 温度 < (trip_point - hysteresis) → 停止冷却
 
- 适用场景:简单的开关式冷却设备
- 优点:实现简单,响应迅速
- 缺点:容易振荡,噪音大,寿命影响
user_space (用户空间控制)
- 策略:内核不做任何自动调整,完全由用户程序控制
- 适用场景:需要复杂自定义逻辑的专业应用
- 优点:完全可定制,支持复杂算法
- 缺点:需要额外的用户空间守护进程
fair_share (公平分享)
- 策略:在多个cooling device间公平分配冷却任务
- 适用场景:多风扇或多种冷却方式的系统
- 优点:资源利用均衡,避免单点过载
- 缺点:可能不是能效最优解
2.3.2 Governor选择指南
| 应用场景 | 推荐Governor | 理由 | 
|---|---|---|
| 单风扇PWM系统 | step_wise | 稳定可靠,适合渐进式调速 | 
| 服务器/高性能计算 | power_allocator | 精确控制,最优能效 | 
| 简单风扇开关 | bang_bang | 实现简单,响应快速 | 
| 自定义控制逻辑 | user_space | 完全可控,支持复杂算法 | 
| 多cooling device | fair_share | 均衡分配,避免单点过载 | 
2.3.3 Governor配置示例
# 查看可用的governors
cat /sys/class/thermal/thermal_zone0/available_policies
# 切换到step_wise (推荐)
echo "step_wise" > /sys/class/thermal/thermal_zone0/policy
# 切换到power_allocator (高级用户)
echo "power_allocator" > /sys/class/thermal/thermal_zone0/policy
# 查看当前governor
cat /sys/class/thermal/thermal_zone0/policy
2.3.4 power_allocator高级配置
如果使用power_allocator,需要额外配置:
thermal-zones {
    cpu-thermal {
        sustainable_power = <1000>;  /* 1W可持续功率 */
        trips {
            cpu_control: cpu-control {
                temperature = <65000>;  /* 65°C开始功率控制 */
                hysteresis = <2000>;
                type = "passive";      /* 被动控制类型 */
            };
        };
        cooling-maps {
            map0 {
                trip = <&cpu_control>;
                cooling-device = <&pwm_fan 0 4>;
                contribution = <1024>;  /* 功率权重 */
            };
        };
    };
};
2.4 工作流程
3. 系统架构与组件关系
3.1 硬件连接图
Raspberry Pi CM4
┌─────────────────────────────────────┐
│  GPIO12 (PWM0) ◄────────────────────┼─── PWM信号 ───► 风扇控制线
│  GPIO17 (Input) ◄───────────────────┼─── 转速信号 ◄── 风扇转速计
│  BCM2711 Thermal Sensor            │
└─────────────────────────────────────┘
3.2 软件架构层次
┌──────────────────────────────────────────────────────────────┐
│                    用户空间接口                                 │
├─────────────────────┬────────────────────┬───────────────────┤
│ /sys/class/thermal/ │ /sys/class/hwmon/  │ /sys/class/pwm/   │
│ thermal_zone0/      │ hwmon1/            │ pwmchip0/         │
└─────────────────────┴────────────────────┴───────────────────┘
┌──────────────────────────────────────────────────────────────┐
│                     内核驱动层                                  │
├─────────────────────┬────────────────────┬───────────────────┤
│  thermal_zone       │   pwm-fan          │   bcm2835-pwm    │
│  (thermal core)     │   (hwmon driver)   │   (pwm driver)    │
└─────────────────────┴────────────────────┴───────────────────┘
┌──────────────────────────────────────────────────────────────┐
│                    设备树层                                     │
├─────────────────────┬────────────────────┬───────────────────┤
│  thermal-zones/     │   pwm_fan节点       │   pwm@7e20c000   │
│  cpu-thermal        │                    │                   │
└─────────────────────┴────────────────────┴───────────────────┘
┌──────────────────────────────────────────────────────────────┐
│                     硬件层                                      │
├─────────────────────┬────────────────────┬───────────────────┤
│  BCM2711温度传感器   │   PWM风扇硬件       │   PWM控制器       │
└─────────────────────┴────────────────────┴───────────────────┘
3.3 数据流向关系
温度传感器 → thermal_zone0 → trip points → cooling maps → cooling_device0 → pwm-fan → hwmon1/pwm1
     ↑                                                                              ↓
     └──────────────────── 温度反馈 ◄───────────────────────────────────────── 风扇冷却
4. 实现过程详解
4.1 阶段一:PWM风扇基础控制
4.1.1 设备树基础结构
/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2711";
    /* fragment@0: 启用PWM0控制器 */
    fragment@0 {
        target = <&pwm>;
        __overlay__ {
            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&pwm0_0_gpio12>;
        };
    };
    /* fragment@1: 创建pwm-fan设备 */
    fragment@1 {
        target-path = "/";
        __overlay__ {
            pwm_fan: pwm_fan {
                compatible = "pwm-fan";
                pwms = <&pwm 0 40000 0>;  // PWM0通道0, 25kHz (40µs周期)
                cooling-levels = <0 64 128 192 255>;  // 5级冷却强度
                pulses-per-revolution = <2>;  // 每转2个脉冲
                interrupt-parent = <&gpio>;
                interrupts = <17 2>;  // GPIO17, 下降沿触发
                #cooling-cells = <2>;  // 标记为cooling device
            };
        };
    };
};
4.1.2 编译与测试
# 编译设备树overlay
dtc -@ -I dts -O dtb -o /boot/overlays/seeed-router-fan-overlay.dtbo seeed-router-fan-overlay.dts
# 应用overlay
dtoverlay seeed-router-fan-overlay
# 验证PWM设备创建
ls /sys/class/pwm/pwmchip0/
ls /sys/class/hwmon/  # 查找新的hwmon设备
# 手动测试PWM控制
echo 0 > /sys/class/pwm/pwmchip0/export
echo 40000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 20000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
关键调试点:
- PWM控制器必须先启用才能创建pwm-fan设备
- #cooling-cells = <2>是关键属性,标记设备可作为cooling device
4.2 阶段二:Thermal Zone集成
4.2.1 添加Thermal管理
/* fragment@2: 配置thermal zone */
fragment@2 {
    target-path = "/thermal-zones/cpu-thermal";
    __overlay__ {
        trips {
            /* 添加风扇控制trip points - 不需要重复定义critical点 */
            cpu_fan_low: cpu-fan-low {
                temperature = <45000>;   // 45°C
                hysteresis = <2000>;
                type = "active";
            };
            cpu_fan_med: cpu-fan-med {
                temperature = <55000>;   // 55°C
                hysteresis = <2000>;
                type = "active";
            };
            cpu_fan_high: cpu-fan-high {
                temperature = <75000>;   // 75°C
                hysteresis = <2000>;
                type = "active";
            };
            cpu_fan_max: cpu-fan-max {
                temperature = <85000>;   // 85°C
                hysteresis = <2000>;
                type = "active";
            };
        };
  
        cooling-maps {
            map0 {
                trip = <&cpu_fan_low>;
                cooling-device = <&pwm_fan 1 1>;  // 冷却级别1
            };
            map1 {
                trip = <&cpu_fan_med>;
                cooling-device = <&pwm_fan 2 2>;  // 冷却级别2
            };
            map2 {
                trip = <&cpu_fan_high>;
                cooling-device = <&pwm_fan 3 3>;  // 冷却级别3
            };
            map3 {
                trip = <&cpu_fan_max>;
                cooling-device = <&pwm_fan 4 4>;  // 冷却级别4
            };
        };
    };
};
4.2.2 Thermal策略详解
温度阈值设计:
- 45°C:开始轻微冷却(PWM=64,25%转速)
- 55°C:中等冷却(PWM=128,50%转速)
- 75°C:高强度冷却(PWM=192,75%转速)
- 85°C:最大冷却(PWM=255,100%转速)
回滞机制:
- 温度上升超过阈值时启动冷却
- 温度下降到阈值-2°C时停止该级别冷却
- 防止频繁开关导致的振荡
4.3 验证与调试
4.3.1 系统状态检查
# 检查thermal zone状态
cat /sys/class/thermal/thermal_zone0/temp  # 当前温度(毫摄氏度)
cat /sys/class/thermal/thermal_zone0/trip_point_*_temp  # 所有温度阈值
cat /sys/class/thermal/thermal_zone0/trip_point_*_type  # 阈值类型
# 检查cooling device状态
cat /sys/class/thermal/cooling_device0/type  # 应显示"pwm-fan"
cat /sys/class/thermal/cooling_device0/cur_state  # 当前冷却级别(0-4)
cat /sys/class/thermal/cooling_device0/max_state  # 最大冷却级别
# 检查hwmon接口
find /sys/class/hwmon -name "pwm1"  # 查找PWM控制接口
cat /sys/class/hwmon/hwmon*/name  # 查看所有hwmon设备
4.3.2 功能测试
# 压力测试观察thermal响应
timeout 20s yes > /dev/null &
for i in {1..15}; do
    sleep 1
    temp=$(($(cat /sys/class/thermal/thermal_zone0/temp)/1000))
    cooling_state=$(cat /sys/class/thermal/cooling_device0/cur_state)
    pwm=$(cat /sys/class/hwmon/hwmon1/pwm1)
    echo "[$i] Temp: ${temp}°C, Cooling: $cooling_state, PWM: $pwm"
done
5. 关键问题与解决方案
5.1 问题一:PWM控制器未启用
症状:
$ ls /sys/class/pwm/
# 空目录,没有pwmchip0
原因:BCM2711的PWM控制器默认禁用
解决方案:
fragment@0 {
    target = <&pwm>;
    __overlay__ {
        status = "okay";                    // 启用PWM控制器
        pinctrl-names = "default";
        pinctrl-0 = <&pwm0_0_gpio12>;      // 配置GPIO12为PWM功能
    };
};
验证:
cat /sys/firmware/devicetree/base/soc/pwm@7e20c000/status
# 应显示"okay"而不是"disabled"
5.2 问题二:设备树常量未定义
症状:
Error: seeed-router-fan-overlay.dts:25.34-35 syntax error
FATAL ERROR: Unable to parse input tree
原因:IRQ_TYPE_EDGE_FALLING常量未定义
解决方案:使用数值代替
interrupts = <17 2>;  // 2 = IRQ_TYPE_EDGE_FALLING
常量对照表:
- 0= IRQ_TYPE_NONE
- 1= IRQ_TYPE_EDGE_RISING
- 2= IRQ_TYPE_EDGE_FALLING
- 3= IRQ_TYPE_EDGE_BOTH
5.3 问题三:Thermal Zone动态更新失效
症状:设备树中有新的trip points,但sysfs中只显示原有的trip point
根本原因:Linux thermal子系统不支持运行时动态添加trip points
深度分析:
# 设备树中确实有新的trip points
$ ls /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/trips/
cpu-alert0  cpu-crit  cpu-fan-high  cpu-fan-low  cpu-fan-max  cpu-fan-med
# 但sysfs中只有原来的trip point
$ ls /sys/class/thermal/thermal_zone0/trip_point_*
trip_point_0_hyst  trip_point_0_temp  trip_point_0_type
解决方案:在系统启动时应用overlay
# 添加到/boot/firmware/config.txt
echo "dtoverlay=seeed-router-fan-overlay" >> /boot/firmware/config.txt
# 重启后验证
reboot
# 重启后检查
ls /sys/class/thermal/thermal_zone0/trip_point_*
# 应显示trip_point_0到trip_point_5
5.4 问题四:Cooling Device绑定失败
症状:
$ cat /sys/class/thermal/cooling_device0/type
pwm-fan
$ find /sys/class/thermal/thermal_zone0/ -name "*cooling*"
# 没有找到cooling相关文件
原因:thermal zone与cooling device之间缺少映射关系
解决方案:确保cooling-maps正确配置
cooling-maps {
    map0 {
        trip = <&cpu_fan_low>;
        cooling-device = <&pwm_fan 1 1>;  // 引用必须正确
    };
};
验证方法:
# 检查cooling maps在设备树中的存在
ls /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/cooling-maps/
# 应显示map0, map1, map2, map3等目录
# 检查sysfs中的cdev映射
ls /sys/class/thermal/thermal_zone0/cdev*
# 应显示cdev0_trip_point, cdev0_weight等文件
5.5 问题五:hwmon设备编号变化
症状:PWM控制从hwmon2变为hwmon1
原因:设备初始化顺序变化,hwmon编号不是固定的
解决方案:使用设备名称或通配符
# 方法1:检查设备名称
for dev in /sys/class/hwmon/hwmon*; do
    name=$(cat $dev/name 2>/dev/null)
    if [ "$name" = "pwmfan" ]; then
        echo "PWM fan device: $dev"
        echo 128 > $dev/pwm1
    fi
done
# 方法2:使用通配符
echo 128 > /sys/class/hwmon/hwmon*/pwm1  # 自动找到正确设备
6. 最佳实践与注意事项
6.1 设备树设计原则
6.1.1 Fragment组织
// ✅ 推荐:按功能分组fragment
fragment@0 { /* PWM控制器配置 */ }
fragment@1 { /* PWM风扇设备 */ }
fragment@2 { /* Thermal集成 */ }
// ❌ 避免:混合不同功能在一个fragment中
6.1.2 引用关系
// ✅ 推荐:使用标签引用
cooling-device = <&pwm_fan 1 1>;
// ❌ 避免:使用字符串路径(易出错)
cooling-device = "/pwm_fan";
6.2 温度阈值调优
6.2.1 阈值设计考虑
- SoC特性:了解BCM2711的温度特性和安全范围
- 散热环境:考虑机箱、环境温度等因素
- 响应时间:平衡风扇噪音和冷却效果
- 回滞设置:防止频繁开关,建议2-5°C
6.2.2 推荐配置
// 保守配置(静音优先)
cpu_fan_low:  temperature = <55000>;  // 55°C
cpu_fan_med:  temperature = <65000>;  // 65°C  
cpu_fan_high: temperature = <75000>;  // 75°C
cpu_fan_max:  temperature = <85000>;  // 85°C
// 激进配置(性能优先)
cpu_fan_low:  temperature = <45000>;  // 45°C
cpu_fan_med:  temperature = <55000>;  // 55°C
cpu_fan_high: temperature = <65000>;  // 65°C
cpu_fan_max:  temperature = <75000>;  // 75°C
6.3 调试技巧
6.3.1 系统状态监控脚本
#!/bin/bash
# thermal_monitor.sh - 实时监控thermal状态
while true; do
    clear
    echo "=== Raspberry Pi Thermal Status ==="
    echo "Time: $(date)"
    echo
  
    # 温度信息
    temp=$(cat /sys/class/thermal/thermal_zone0/temp)
    echo "CPU Temperature: $((temp/1000))°C"
  
    # Trip points
    echo -e "\n=== Trip Points ==="
    for i in {0..5}; do
        if [ -f "/sys/class/thermal/thermal_zone0/trip_point_${i}_temp" ]; then
            temp=$(cat /sys/class/thermal/thermal_zone0/trip_point_${i}_temp)
            type=$(cat /sys/class/thermal/thermal_zone0/trip_point_${i}_type)
            echo "trip_point_$i: $((temp/1000))°C ($type)"
        fi
    done
  
    # Cooling devices
    echo -e "\n=== Cooling Devices ==="
    for i in {0..3}; do
        if [ -f "/sys/class/thermal/cooling_device${i}/type" ]; then
            type=$(cat /sys/class/thermal/cooling_device${i}/type)
            state=$(cat /sys/class/thermal/cooling_device${i}/cur_state)
            max=$(cat /sys/class/thermal/cooling_device${i}/max_state)
            echo "cooling_device$i: $type (state: $state/$max)"
        fi
    done
  
    # PWM状态
    if [ -f "/sys/class/hwmon/hwmon1/pwm1" ]; then
        pwm=$(cat /sys/class/hwmon/hwmon1/pwm1)
        enabled=$(cat /sys/class/hwmon/hwmon1/pwm1_enable)
        echo -e "\n=== PWM Fan Status ==="
        echo "PWM Value: $pwm/255 ($(($pwm*100/255))%)"
        echo "PWM Enabled: $enabled"
  
        if [ -f "/sys/class/hwmon/hwmon1/fan1_input" ]; then
            rpm=$(cat /sys/class/hwmon/hwmon1/fan1_input)
            echo "Fan RPM: $rpm"
        fi
    fi
  
    sleep 2
done
6.3.2 问题诊断清单
# 1. 检查设备树应用状态
dtoverlay -l | grep seeed-router-fan
# 2. 检查PWM控制器状态
cat /sys/firmware/devicetree/base/soc/pwm@7e20c000/status
# 3. 检查pwm_fan设备创建
find /sys -name "*pwm_fan*" -type d
# 4. 检查cooling device注册
cat /sys/class/thermal/cooling_device*/type | grep pwm-fan
# 5. 检查thermal zone配置
ls /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/trips/
ls /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/cooling-maps/
# 6. 验证sysfs接口
ls /sys/class/thermal/thermal_zone0/trip_point_*
ls /sys/class/thermal/thermal_zone0/cdev*
6.4 性能优化
6.4.1 Thermal Governor优化
推荐配置:
# 对于PWM风扇系统,推荐使用step_wise
echo "step_wise" > /sys/class/thermal/thermal_zone0/policy
# 验证配置生效
cat /sys/class/thermal/thermal_zone0/policy
性能调优参数:
# step_wise governor的调优参数
echo 1000 > /sys/class/thermal/thermal_zone0/polling_delay          # 1秒轮询间隔
echo 100 > /sys/class/thermal/thermal_zone0/polling_delay_passive   # 100ms被动轮询
# 如果使用power_allocator,还可以调整PID参数
echo 1000 > /sys/class/thermal/thermal_zone0/k_po  # 比例增益
echo 100 > /sys/class/thermal/thermal_zone0/k_pu   # 比例增益(负载)
echo 10 > /sys/class/thermal/thermal_zone0/k_i     # 积分增益
echo 1 > /sys/class/thermal/thermal_zone0/k_d      # 微分增益
Governor性能对比:
| Governor | 响应速度 | 稳定性 | CPU开销 | 适用场景 | 
|---|---|---|---|---|
| step_wise | 中等 | 优秀 | 低 | PWM风扇(推荐) | 
| power_allocator | 快 | 良好 | 中等 | 复杂多热源系统 | 
| bang_bang | 最快 | 较差 | 最低 | 简单开关控制 | 
| user_space | 取决于程序 | 取决于程序 | 高 | 自定义算法 | 
6.4.2 PWM频率优化
pwms = <&pwm 0 40000 0>;  // 25kHz,平衡噪音和效率
// 可选频率:
// 20000ns (50kHz) - 超静音,但可能影响低速控制精度
// 40000ns (25kHz) - 推荐值,兼顾静音和精度
// 100000ns (10kHz) - 可能产生可听见噪音
7. 总结与扩展
7.1 项目成果
通过本项目,我们成功实现了:
- 完整的DTS thermal管理方案:纯设备树配置,无需用户空间程序
- 4级温度控制策略:45°C、55°C、75°C、85°C四个阈值点
- 硬件抽象接口:标准的hwmon和thermal sysfs接口
- 转速监控能力:实时读取风扇RPM(如果硬件支持)
- 系统集成:与Linux thermal框架完美集成
7.2 技术收获
7.2.1 Linux Thermal子系统深度理解
- Thermal Zone、Cooling Device、Trip Points的工作机制
- 设备树与内核驱动的交互过程
- sysfs接口的动态创建原理
7.2.2 设备树开发技巧
- Fragment化设计的重要性
- 引用关系的正确建立方法
- 运行时vs启动时overlay应用的区别
7.2.3 系统调试经验
- 从设备树到sysfs的完整调试链路
- thermal子系统的限制与工作原理
- hwmon设备编号变化的应对策略
7.3 扩展方向
7.3.1 多风扇支持
// 可扩展支持多个PWM风扇
pwm_fan1: pwm_fan@0 {
    compatible = "pwm-fan";
    pwms = <&pwm 0 40000 0>;
    // ...
};
pwm_fan2: pwm_fan@1 {
    compatible = "pwm-fan";
    pwms = <&pwm 1 40000 0>;
    // ...
};
7.3.2 自定义Thermal Governor
// 可开发自定义thermal governor
// 实现特定的温度控制算法
static int custom_throttle(struct thermal_zone_device *tz, int trip) {
    // 自定义控制逻辑
    return 0;
}
7.3.3 GPU温度集成
// 可扩展支持GPU温度控制
thermal-zones {
    gpu-thermal {
        polling-delay = <1000>;
        thermal-sensors = <&gpu_thermal>;
        trips {
            gpu_fan_low: gpu-fan-low {
                temperature = <60000>;
                hysteresis = <2000>;
                type = "active";
            };
        };
        cooling-maps {
            map0 {
                trip = <&gpu_fan_low>;
                cooling-device = <&pwm_fan 1 2>;
            };
        };
    };
};
7.4 最终评价
本项目展示了Linux设备树和thermal子系统的强大能力。通过纯DTS配置实现复杂的温控系统,不仅技术上优雅,而且实用性强。这种方案特别适合:
- 嵌入式系统:资源受限,需要高效的温控方案
- 服务器应用:需要可靠的自动化温度管理
- 工业控制:要求稳定的硬件级温控响应
掌握这套技术栈,对于深入理解Linux内核、设备树开发和thermal管理都有重要意义。
附录
A.1 完整设备树源码
参见项目中的 seeed-router-fan-overlay.dts 文件
A.2 相关文档链接
A.3 故障排除快速指南
| 问题现象 | 可能原因 | 检查命令 | 解决方案 | 
|---|---|---|---|
| 没有pwmchip0 | PWM控制器未启用 | cat /sys/firmware/devicetree/base/soc/pwm@*/status | 检查fragment@0配置 | 
| 编译错误 | 常量未定义 | 查看dtc输出 | 使用数值替代常量 | 
| 只有1个trip point | overlay运行时应用 | ls /sys/class/thermal/thermal_zone0/trip_point_* | 添加到config.txt重启 | 
| cooling device无响应 | cooling maps未生效 | ls /sys/class/thermal/thermal_zone0/cdev* | 检查cooling-maps配置 | 
| 找不到pwm1 | hwmon编号变化 | find /sys -name pwm1 | 使用设备名或通配符 | 
本文档基于实际项目开发经验编写,涵盖了从理论到实践的完整过程。希望能够帮助读者深入理解Linux thermal子系统和设备树开发。