| 名称 | jetson-customize-fan |
| 描述 | >- 当需要在Jetson/Tegra(Orin、Thor)目标上添加、移除、编辑、列出或更改nvfancontrol风扇配置文件的启动默认值时使用。触发器:编辑风扇配置文件,调整风扇曲线。 |
| 版本 | 0.0.1 |
| 开源协议 | “Apache-2.0” metadata: data-classification: public |
| 作者 | “Jetson Team” tags: - thermal - fan - nvfancontrol - profile domain: thermal |
修改 nvfancontrol 风扇配置文件(BSP 侧)
目的
编辑每块板卡的 nvfancontrol 配置,使设备以期望的风扇曲线 / 控制模式 / 调节器 / 默认配置文件启动。仅限 BSP 侧——所有写入都落在覆盖跟踪器中,上游的 bsp_image 副本是只读的。
本技能处理对每块板卡 nvfancontrol 配置文件的 BSP 侧编辑:添加配置文件、移除配置文件、编辑温度 → PWM / RPM 曲线、更改启动默认配置文件 / 控制模式 / 调节器,以及列出已定义的配置文件。适用于 Jetson / Tegra 平台(T234 Orin、T264 Thor)。
文件格式(规范,按 BSP 文件头)
POLLING_INTERVAL <seconds>
<FAN <index>>
TMARGIN <ENABLED|DISABLED>
FAN_GOVERNOR <type> {
STEP_SIZE <int>
}
FAN_CONTROL <close_loop|open_loop> {
RPM_TOLERANCE <rpm>
}
FAN_PROFILE <name> {
# TEMP HYST PWM RPM
<T0> <H0> <P0> <R0>
...
}
FAN_PROFILE <name> { ... } # one or more profiles
THERMAL_GROUP <id> {
GROUP_MAX_TEMP <C>
# zone-name <coeffs csv> <max-temp>
<zone> <coeffs> <max-temp>
...
}
FAN_DEFAULT_CONTROL <close_loop|open_loop>
FAN_DEFAULT_PROFILE <name>
FAN_DEFAULT_GOVERNOR <type>
KICKSTART_PWM <0..255>
规则:
- 配置文件曲线元组为 4 列:
TEMP HYST PWM RPM。按TEMP升序排列点;守护进程在它们之间进行插值。 PWM为0..255(8 位占空比);RPM是闭环目标速度。在高端的尾随0 0行会在GROUP_MAX_TEMP以上关闭风扇。HYST是该点的迟滞(°C)——控制器在降低曲线之前等待HYST度的冷却。FAN_DEFAULT_PROFILE必须引用同一个<FAN N>中已存在的FAN_PROFILE块。如果默认名称指向不存在的配置文件,nvfancontrol 将启动失败。FAN_DEFAULT_CONTROL=close_loop(驱动至目标 RPM,需要测速)或open_loop(直接写 PWM)。FAN_DEFAULT_GOVERNOR=cont(连续插值)和其他特定系列的值;引入时从现有的每板文件中逐字复制。THERMAL_GROUP将热区映射到控制器的输入。系数是一个 20 元素 CSV——从现有条目中逐字复制;数值因芯片系列和区域而异。<FAN N>是每个风扇索引一个块(典型:<FAN 1>)。块边界<...>和{...}是严格的;保持与相邻行一致的缩进。- 曲线是表征出来的,不是发明的。 根据平台真实的热声数据添加或编辑曲线;不要从相邻配置文件插值或跨芯片系列复制。
先决条件
按 …/…/context/target-platform-contract.md 解析活动配置文件。以下情况拒绝并路由:
| 条件 | 拒绝方式 |
|---|---|
没有活动配置文件,或 active: NA |
路由到 /jetson-set-target 或 /jetson-init-target。 |
配置文件缺少 bsp_image: 块 |
路由到 /jetson-init-image。 |
<bsp_image.root_path>/Linux_for_Tegra/ 缺失 |
路由到 /jetson-init-image。 |
<source.root_path>/Linux_for_Tegra/ 缺失或不是 git 仓库 |
路由到 /jetson-init-source。 |
解析路径:
<bsp_image.root_path>来自bsp_image.root_path:(如果存在),否则为<workspace>/Image。<source.root_path>来自source.root_path:(如果存在),否则为<workspace>/Source。
<bsp_image.root_path> 对本技能是只读的;所有写入都在 <source.root_path>(覆盖跟踪器)下。这是 …/…/context/bsp-customization-workflow.md#workflow-invariants 中的工作流不变量——手工编辑上游会悄然破坏 diff 轨迹,使 /jetson-promote-image 变成空操作。
每板文件
本技能编辑的配置文件具有相对路径:
Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/nvfancontrol_<active-sku>.conf
它存在于两个根中;技能遍历两者:
| 角色 | 位置 | 技能写入? |
|---|---|---|
| 检测 + 原始来源 | <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/ |
否——只读 |
| 覆盖编辑目标 + git 提交 | <source.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/ |
是 |
后续章节中每板文件指的是 <source.root_path> 下的覆盖副本。操作 1-4 都针对该覆盖副本进行读取、编辑和保存。<bsp_image.root_path> 副本在“解析 <active-sku>”检测步骤期间读取一次,并在覆盖编辑配方的原始导入步骤期间读取一次,之后不再触碰。
解析 <active-sku>——要编辑哪个文件
文件名约定因产品系列而异:
nvfancontrol_<module.id>_<module.sku>.conf— 大多数 Orin 部件(例如nvfancontrol_p3767_0000.conf、nvfancontrol_p3701_0008.conf)。nvfancontrol_<module.id>_<module.sku>_<carrier.id>_<carrier.sku>.conf— Thor 变体,载板用于消除歧义(例如nvfancontrol_p3834_0008_p4071_0000.conf)。nvfancontrol_<carrier>_<sku>_<rev>.conf— IGX 修订变体(例如nvfancontrol_p3740_0002_b01.conf)。
nvfancontrol 守护进程在启动时根据已启动硬件的 DT 兼容性和板 ID 解析正确的文件(没有辅助脚本——它在二进制内部完成)。在没有运行目标的情况下,映射 BSP 侧,使用 <bsp_image.root_path>:
- 列出
<bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/。 - 筛选出包含活动配置文件中
<module.id>_<module.sku>的文件名。 - 如果仍有多个候选,使用
<carrier.id>_<carrier.sku>和(相关时)载板修订标签进行细化。 - 如果仍然不明确,运行每板 flash conf 分发链以读取内核 DTB 的
compatible,并选择名称与解析出的板 / 载板一致的文件。 - 验证所选文件确实存在于
<bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/下。
不要盲目组合文件名——命名约定因产品系列而异。
传播集——需要保持同步的配置
活动 SKU 文件很少是唯一应承载自定义的配置。编辑后,对传播集中的每个同级配置应用相同编辑,以便无论启动哪个模块 / 基板 SKU,更改都能保留:
- 参考平台的 nvfancontrol 配置 — 活动文件所派生的上游配置(通过活动配置中的
reference_devkit或jetson-derive-carrier派生祖先解析)。对于仅包含参考(无派生载板)的 BSP,这与活动文件相同,规则简化为无操作。 - 每个载板派生的 nvfancontrol 配置 — 由
jetson-derive-carrier针对同一模块 SKU 上的自定义载板生成的每个nvfancontrol_*.conf。
“应用相同编辑”≠ 整文件复制。 将更改的 FAN_PROFILE / 控制行移植到每个同级配置;保留其他每一行。同级配置通常包含载板特定的差异(不同散热解决方案的不同 THERMAL_GROUP 系数,不同的测速 RPM 上限),必须保持不变——整文件覆盖会错误调整这些载板上的风扇。仅当两个配置在编辑前字节相同时,整文件复制才是安全的。
覆盖编辑配方(在任何操作前应用)
遵循工作流文档中的规范 Off-skill 编辑配方——原始导入 + 自定义提交对,两者都由预览门控。每次运行应用一次,覆盖运行触及的每个每板文件(活动配置加上传播集中的每个同级)。
本技能的具体替换:
<rel>/<file>是rootfs/etc/nvpower/nvfancontrol/<conf>。- 建议的原始导入消息:
import pristine: <导入配置的逗号分隔相对路径>,正文Source: <bsp_image.root_path>/Linux_for_Tegra/ (BSP <bsp_image.version>)。 - 建议的自定义提交头:
jetson-customize-fan: <摘要>,正文行如nvfancontrol_p3767_0000.conf: added FAN_PROFILE static (open-loop, PWM=255 flat), FAN_DEFAULT_CONTROL close_loop -> open_loop, FAN_DEFAULT_PROFILE quiet -> static。
说明
选择与用户意图匹配的操作,并遵循相应小节。所有写侧操作(1-4)必须首先应用覆盖编辑配方。
- 操作 1 — 添加新的风扇配置文件。
- 操作 2 — 移除风扇配置文件。
- 操作 3 — 编辑现有风扇配置文件(曲线、迟滞)。
- 操作 4 — 更改启动默认值(控制 / 配置文件 / 调节器)。
- 操作 5 — 列出已定义的风扇配置文件(只读)。
在任何写侧操作后,运行部署链(## Deploy)以将更改落地到设备。
示例
向 P3767-0000(Orin Nano 开发套件)目标添加一个激进配置,并将其设为启动默认:
/jetson-customize-fan
> add a profile called "aggressive" with the curve {0:255, 40:150, 80:0}
> set FAN_DEFAULT_PROFILE to aggressive
柔化现有 quiet 配置上的风扇斜率(提高 HYST,降低中段 PWM):
/jetson-customize-fan
> edit FAN_PROFILE quiet — raise HYST to 5 from 30 °C up, drop PWM at 60 °C to 80
列出活动 SKU 当前定义哪些配置文件以及哪个是启动默认:
/jetson-customize-fan
> list defined fan profiles
操作 1 — 添加新的风扇配置文件
首先应用覆盖编辑配方。
- 在每板文件的
<FAN N>块内,在现有配置文件之间添加新的FAN_PROFILE <name> { ... }。守护进程解析顺序无关紧要,但与同级分组保持文件可扫描性。 - 选择
<name>小写,无空白(例如quiet、cool、aggressive)。 - 填充曲线表——4 列
TEMP HYST PWM RPM元组,TEMP升序。至少以一行高于GROUP_MAX_TEMP结束,以定义过温行为。
示例骨架:
FAN_PROFILE aggressive {
#TEMP HYST PWM RPM
0 0 255 6000
20 2 255 6000
40 2 150 3500
60 2 50 1500
80 0 0 0
105 0 0 0
}
验证(见规则):
- 每个
TEMP都位于THERMAL_GROUP的0..GROUP_MAX_TEMP范围内。 PWM∈[0, 255];RPM≤ 平台测速报告的最大值(因风扇部件而异)。- 元组按
TEMP升序排序。
如果你希望新配置文件成为启动默认,请遵循操作 4。
操作 2 — 移除风扇配置文件
首先应用覆盖编辑配方。
- 在每板文件中,删除整个
FAN_PROFILE <name> { ... }块,包括所有曲线行和右花括号}。 - 如果删除的
<name>与尾部的FAN_DEFAULT_PROFILE匹配,将FAN_DEFAULT_PROFILE指向剩余的配置文件——否则守护进程启动失败。 - 在声明更改安全之前,在 rootfs 中搜索硬编码引用:
grep -rn "nvfancontrol.*profile\|FAN_PROFILE" \ Linux_for_Tegra/rootfs/etc 2>/dev/null
剩余配置文件不需要重命名。
操作 3 — 编辑现有风扇配置文件
首先应用覆盖编辑配方。
- 在每板文件中,修改目标
FAN_PROFILE <name>的曲线行。保持 4 列TEMP HYST PWM RPM形状。 - 保持
TEMP升序;根据需要插入或移除行。 - 调整
HYST以调整防振荡:太低 → 风扇在曲线点附近抖动;太高 → 风扇滞后于现实。 - 按操作 1 的规则验证。
对 KICKSTART_PWM、RPM_TOLERANCE(在 FAN_CONTROL 内部)或 STEP_SIZE(在 FAN_GOVERNOR 内部)的编辑位于配置文件之外,但调节同一个风扇;同一每板文件。
操作 4 — 更改启动默认值
首先应用覆盖编辑配方。
编辑 <FAN N> 块内的尾部默认行:
FAN_DEFAULT_CONTROL <close_loop|open_loop>
FAN_DEFAULT_PROFILE <name>
FAN_DEFAULT_GOVERNOR <type>
FAN_DEFAULT_PROFILE 必须引用同一个 <FAN N> 块中现有的 FAN_PROFILE。FAN_DEFAULT_CONTROL 和 FAN_DEFAULT_GOVERNOR 必须引用二进制支持的值——更改时从现有每板文件复制。
操作 5 — 列出已定义的风扇配置文件
这是只读操作;无需设置覆盖跟踪器。针对你想检查的任何副本运行(<bsp_image.root_path>/... 用于原始状态,<source.root_path>/... 用于编辑后状态):
grep -E '^[[:space:]]*FAN_PROFILE ' <per-board file>
grep -E '^[[:space:]]*FAN_DEFAULT_' <per-board file>
第一个命令打印文件中每个配置文件名;第二个命令打印启动默认值(控制 / 配置文件 / 调节器)。
局限性
- 仅限 BSP 侧范围——本技能从不直接接触运行中目标的
/etc/nvpower/nvfancontrol/。实时调整需要通过## Deploy中描述的 Deploy 重启,或侧信道scp + systemctl restart流程。 - 编辑仅落在
<source.root_path>下的覆盖副本中;<bsp_image.root_path>副本是只读的,由/jetson-promote-image重写。手工编辑bsp_image会在下次/jetson-init-image重新提取时静默丢失。 - 曲线元组必须反映平台真实表征的热声数据——本技能不跨芯片系列插值或复制曲线。
- 跨同级载板(同一模块 SKU)的传播是部分设计:只移植更改的
FAN_PROFILE/ 控制行,绝不整文件覆盖,因为同级配置可能包含载板特定的THERMAL_GROUP/ RPM 上限。 - 曲线点限制因系列而异;引入新的
THERMAL_GROUP系数或FAN_DEFAULT_GOVERNOR值时,从现有配置中逐字复制。
故障排除
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 编辑后 nvfancontrol.service 启动失败 | FAN_DEFAULT_PROFILE 引用了被移除或重命名的配置文件 |
将 FAN_DEFAULT_PROFILE 设置为同一个 <FAN N> 中现有的 FAN_PROFILE <name>。 |
| 风扇在曲线点附近抖动 | HYST 太低 |
提高受影响行的 HYST(通常 2-5 °C)。 |
| 风扇滞后于现实 | HYST 太高 |
降低受影响行的 HYST。 |
| 高温时风扇从不启动 | 曲线缺少高于 GROUP_MAX_TEMP 的行,或尾随 0 0 在环境温度以上截断 |
添加非零 PWM/RPM 的高温元组;仅在 GROUP_MAX_TEMP 以上固定过温行。 |
| 守护进程解析错误引用列数 | 曲线行不是 4 列 TEMP HYST PWM RPM |
恢复 4 列形状;移除尾部空白和多余列。 |
闭环中 RPM 目标从未达到 |
目标高于测速报告的最大值,或 FAN_CONTROL 设置为 open_loop |
将 RPM 降低到风扇机械最大范围内,或将 FAN_DEFAULT_CONTROL 切换为 close_loop。 |
/jetson-init-image 重新提取后更改消失 |
编辑落在 <bsp_image.root_path> 而不是 <source.root_path> 覆盖中 |
通过覆盖编辑配方重新应用,使更改提交到覆盖跟踪器。 |
| 传播后同级载板以错误的测速上限启动 | 整文件复制破坏了载板特定的 THERMAL_GROUP / RPM 行 |
按传播集只移植更改的行;恢复载板原始 THERMAL_GROUP。 |
部署
覆盖跟踪器中的自定义提交不会自行到达设备。部署链:
/jetson-promote-image— 将覆盖中每个跟踪文件复制到<bsp_image.root_path>/Linux_for_Tegra/。差异感知(跳过字节相同);对rootfs/*目标使用sudo cp -p。/jetson-flash-image— 将更新后的bsp_image刷写到设备。- (替代,不刷写)直接将
<source.root_path>/Linux_for_Tegra/rootfs/etc/nvpower/nvfancontrol/<conf>复制到运行中目标的/etc/nvpower/nvfancontrol/<conf>,然后sudo systemctl restart nvfancontrol.service(或重启)。
编辑 <source.root_path>/... 而不提交——或直接编辑 <bsp_image.root_path>/...——对 /jetson-promote-image 没有任何作用,并会在下次 /jetson-init-image 重新提取时静默丢失。