结论:热状态不是「一过热就立刻停机」,而是分层的:新启动要求热状态低于 overheated,而已在行车只要求低于 critical,因此允许在 overheated 暂时滞留,直到达到 critical 才撤销在途资格。状态机按当前档位的严格小于/大于判断,每轮最多移动一档,精确等于阈值时保持原档;另有驻车捷径——设备未在行车且满足「本次未曾进入行车、没有驻车起点、驻车超过 5 分钟」之一时,不含 PMIC 的驻车复合温度超过 mici 的 85 °C 或其他设备的 75 °C 就直接设为 critical。本文为固定源码快照 c8fb906 的静态追踪与临时探针,未运行真实设备温升、风扇或热故障注入。
关键函数与配置
| 组件 | 实现行为 |
|---|---|
ThermalZone.read() |
首次按温区 type 名称发现编号,之后缓存编号;读取 temp 并按默认 1000 缩放;temp 不存在时返回 0 |
ThermalConfig.get_msg() |
遍历平台配置的单温区或列表形成各温度字段;各项顺序读取,没有共同时戳 |
HardwareComma.get_thermal_config() |
提供 8 个 CPU、2 个 GPU、DSP、DDR、2 个 PMIC 温区;mici 额外配置进气、排气、GNSS、底部 SoC |
FirstOrderFilter.update() |
两条滤波器用 0.5 秒采样步长与 5 秒时间常数,首个样本直接成为状态,随后固定系数推进 |
THERMAL_BANDS |
mici 与其余设备使用不同的升降温阈值 |
hardware_thread() 热状态分支 |
计算两类复合温度,先更新风扇目标,再执行驻车危险覆盖或逐级状态转换 |
| 阈值 | mici | 其他设备 |
|---|---|---|
| 正常升级到 overheated | 大于 100 °C | 大于 96 °C |
| overheated 升级到 critical | 大于 107 °C | 大于 107 °C |
| 降级阈值 | 92 °C 与 98 °C | 88 °C 与 94 °C |
| 驻车危险捷径 | 大于 85 °C | 大于 75 °C |
采样与聚合边界
ThermalZone 只缓存找到的编号,不跟踪该编号以后是否换了类型;五项临时系统探针确认同一编号从一种温区类型改为另一种后,旧对象仍读取原编号的温度。找不到名称时编号仍为负一,随后读取会得到文件不存在错误并返回 0;稍后出现该名称时,由于尚未缓存编号,又可重新发现。单个 temp 文件消失同样变成 0 °C 而不是缺测,但 temp 内容不是整数会抛值错误,发现阶段的类型文件缺失会抛文件不存在错。名称扫描与非「文件不存在」类异常不在读取函数的捕获范围内,因此不能概括成「所有传感器错误都回零」。
复合温度上,驻车复合温度取内存、CPU 最大与 GPU 最大中的最大值,行车复合温度另加入 PMIC 最大值;DSP、进气/排气、GNSS 和底部 SoC 虽进入设备状态,却不参与这两条复合温度。两条滤波器互相独立,初始化为未就绪,第一次更新不从 0 慢慢爬升;之后每次用固定系数推进,若调用周期因消息或调度变化而不等于 0.5 秒,物理时间常数会偏离标称的 5 秒。缺测温区的 0 不会作为「未知」传给聚合器,若关键热源缺失,最大值可能被其他热源掩盖,也可能整体偏低。
热带状态与行为门
正常状态机按当前档位的下限与上限做严格小于/大于判断,每轮最多向相邻档移动一步。六项热带分支探针确认从正常遇到极高温先到 overheated,下一轮高温持续才到 critical,精确等于阈值时保持原档。降温时 critical 和 overheated 有不同下限,形成迟滞。驻车危险捷径是独立分支:设备未在行车且满足前述三条件之一时,不含 PMIC 的驻车复合温度超过对应阈值就直接设为 critical;已启动的设备即使驻车复合温度很高也不走该捷径,首次驻车可立即直升,已启动过的设备则要严格超过五分钟。
| 资格门 | 条件 | 后果 |
|---|---|---|
| 新启动 | 热状态低于 overheated |
overheated 与 critical 都阻止进入 |
| 已在途 | 热状态低于 critical |
可在 overheated 暂留,达 critical 才撤销在途 |
| 告警与风扇 | 点火为真且温度阻止启动或在途 | 请求高温离车告警并把风扇目标覆盖为 100% |
告警还要求点火为真。热状态阻止启动或在途时,它会请求高温离车告警,并在目标计算后强制风扇目标为 100%;告警清除或点火消失时,这一覆盖停止,后续目标回到风扇控制器独立的积分与前馈状态。对外报告的热状态是档位,既不证明哪个温区有效,也不证明风扇已执行。
测试边界与硬件插件验收
相邻的风扇单测只验证控制器数值上下限,本目录未找到对温区缺失、档位迟滞、驻车捷径与在途退场组合的专门单测。五项系统探针执行原温区读取类,六项热带分支探针执行原阈值表、状态转换与两项资格门;它们不是完整设备进程测试,实车热惯量、传感器布局、目标板系统接口格式和恢复时序均待验证。自制硬件的温区插件应提供稳定传感器身份、单位、量程、采样时间、有效位和故障原因,聚合器不能把失效当成 0 °C;可信热安全层要独立规定多传感器不一致、全部缺测和超温时的降级策略,并把「禁止新启动、在途退出、风扇全速」作为分别可验证的动作。
常见问题
设备过热就直接停机吗?
不是。热状态分两档门槛:新启动要求低于 overheated,已在途只要求低于 critical,所以在 overheated 允许暂时滞留,直到达到 critical 才撤销在途资格。这两个门不能合并成一条「过热就立刻停机」的规则。
传感器读不到温度会怎样?
单个 temp 文件消失或编号为负一时读取返回 0 °C,而不是缺测;但 temp 内容不是整数会抛值错误,发现阶段的类型文件缺失会抛文件不存在错,名称扫描等异常也不在捕获范围内。因此不能概括为「所有传感器错误都回零」,聚合器也不能把 0 当作未知。
为什么驻车时也判 critical?
有一条独立捷径:设备未在行车且满足「本次未曾进入行车、没有驻车起点、驻车超过 5 分钟」之一时,不含 PMIC 的驻车复合温度超过 mici 的 85 °C 或其他设备的 75 °C 就直升 critical。已启动的设备即使驻车复合温度很高也不走这条捷径。
温度报的档位能代表风扇已执行吗?
不能。对外报告的是档位,既不证明哪个温区有效,也不证明风扇已执行;风扇目标的 100% 覆盖只在点火为真且温度阻止启动或在途时生效,告警清除或点火消失后即停止覆盖,回到控制器独立的积分与前馈状态。
延伸阅读
- 功耗监测与容量关机契约 —— 对照本文热状态与功耗在关机决策中的分工。
- 硬件状态与设备遥测 —— 解释温区、CPU 与风扇状态如何汇总进设备状态。
- 进程生命周期、通信与设备服务 —— 承接本文硬件线程在进程管理中的位置。
- panda 健康 ABI 与主机版本映射 —— 说明风扇与温度反馈在 MCU 侧的健康语义。
参考资料
- 项目 02 ——
openpilot-research/THERMAL_ZONE_BAND_STARTUP_EXIT_CONTRACT_DEEP_DIVE.md(取用了温区采样、聚合边界、热带状态机、驻车捷径与两项资格门)。 - 项目 02 ——
openpilot-research/FAN_HOST_PANDA_FEEDBACK_CONTRACT_DEEP_DIVE.md(仅用于确认风扇指令与转速告警的分工位置)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复