树莓派基于 DTS 的 Thermal 管理实现指南

1. 项目初衷与目标

1.1 背景

本项目旨在为Raspberry Pi CM4/Seeed路由器设备实现完全基于 Device Tree Source (DTS) 的PWM风扇温控系统。相比于用户空间脚本方案,DTS方案具有以下优势:

  • 内核级别的温度控制:响应速度快,延迟低
  • 系统集成度高:与Linux thermal框架完美集成
  • 配置简洁:一次配置,系统自动管理
  • 硬件抽象:标准化的hwmon和thermal接口

1.2 技术目标

  1. PWM风扇硬件控制:通过GPIO12输出25kHz PWM信号控制风扇转速
  2. 转速反馈:通过GPIO17读取风扇转速信号(tachometer)
  3. 温度感知:集成CPU温度传感器
  4. 自动调速:根据CPU温度自动调节风扇转速
  5. 多级控制:实现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 工作流程

graph TD A[温度传感器读取] --> B[Thermal Zone处理] B --> C[Thermal Governor算法] C --> D{检查Trip Points} D -->|超过阈值| E[Governor计算冷却需求] D -->|未超过| F[维持当前状态] E --> G[根据Cooling Maps调整] G --> H[PWM风扇调速] H --> I[温度反馈] I --> A F --> A C1[step_wise: 阶梯调整] C2[power_allocator: PID控制] C3[bang_bang: 开关控制] C --> C1 C --> C2 C --> C3

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 项目成果

通过本项目,我们成功实现了:

  1. 完整的DTS thermal管理方案:纯设备树配置,无需用户空间程序
  2. 4级温度控制策略:45°C、55°C、75°C、85°C四个阈值点
  3. 硬件抽象接口:标准的hwmon和thermal sysfs接口
  4. 转速监控能力:实时读取风扇RPM(如果硬件支持)
  5. 系统集成:与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子系统和设备树开发。


留下你的脚步
推荐阅读