结论:Chestnut 的故障告警大多锁存到下一个行车周期边沿,不是按当前测量实时刷新:usb_failed、model_failed、power_lost、pcie_failed 都在 offroad→onroad 边沿才复位。因此「告警消失了」不等于「故障已清」,而 state is None(遥测缺失)这一轮既不更新供电/PCIe/温度,也不会自动清除原故障——没有新有效样本既不证明健康,也不必然生成新告警。
本文基于固定源码快照追踪 ChestnutStatus.update() 的状态转换及其上下游,并以原类方法离线探针核对部分迁移。探针使用假 USB 快照、时钟和告警回调,未接真实桥接层、USB 或设备,不代表实板故障已复现。USB/GPU 原始遥测的有效位属于相邻专题。
状态迁移与复位
ChestnutStatus.update() 每次由 USB、模型和遥测输入更新锁存状态,再计算七类 offroad 告警。hardwared.hardware_thread() 把慢速 USB 快照、固件失败、Params 和存活且有效的遥测传入状态机;set_offroad_alert_if_changed() 以 (show_alert, extra_text) 去重,只在变化时写 Params。
| 状态 | 置位/更新条件 | 清除条件与后果 |
|---|---|---|
usb_seen |
仅在 offroad→onroad 边沿取当时的 firmware_ok |
下次行车边沿重取;若出发时未识别成功,之后出现再消失不会触发本轮 usb_failed |
usb_failed |
行车中曾在边沿看见 USB,后来 firmware_ok 为假 |
下次行车边沿清除;置位后即使设备恢复也维持缺失告警,并压下 PCIe/供电锁存 |
model_loading_seen / model_attempted |
本次行车边沿后曾见加载为真,随后加载为假且 model_active 非 None |
下次行车边沿清除;驻车阶段曾见加载会在切入行车时清空 |
model_failed |
行车中、已尝试且 model_active is False |
下次行车边沿清除;显示时再受 missing 或 pcie_failed 抑制 |
power_seen / power_lost |
行车中有效遥测电压不低于 5000 mV;已尝试后供电故障或低于阈值 | 下次行车边沿清除;power_lost 锁存,power_restored 记录后续恢复用于改告警文本 |
link_failures / pcie_failed |
已尝试且有效遥测中 LTSSM 连续两次不为 0x78,或供电丢失 |
计数在下次 0x78 样本清零,故障位仍锁存至下次行车边沿;USB 失败会清故障位 |
overheated |
有效遥测 GPU 不低于 100°C 或显存不低于 95°C | 已过热时降至各阈值减 5°C 以下才清除;行车边沿不重置该位 |
usb_failed 优先级最高:源码会把若干供电/PCIe 锁存清掉,并用 missing 抑制模型错误显示;pcie_failed 也抑制模型错误,以免同一根因重复报错。锁存用于保留行车周期内已发生的事件,其恢复语义要与实时测量分开。
缺测不等于正常:state is None 的语义
hardwared 只在 chestnutState 同时 alive 且 valid 时传具体 state,否则传 None。state is None 时本轮不更新供电、PCIe 和温度状态,不会把原故障自动清除。离线探针确认:一次异常 LTSSM、一次 state=None、再一次异常 LTSSM 会累计到两次并锁存 pcie_failed;之后正常样本把计数清零,却不会在当前行车周期清除故障位。
| 观测 | 源码行为 | 不能推出的结论 |
|---|---|---|
本轮 state is None |
不更新供电/PCIe/温度,也不清原故障 | 不能判定「故障已恢复」 |
| 两次异常 LTSSM 后正常样本 | 计数清零,但故障位锁存至下次行车边沿 | 不能判定本周期内 PCIe 已健康 |
| USB 快照重复消费 | 快照来自较慢线程,可能被数次调用重复消费 | 不能按调用次数换算固定毫秒数 |
两次异常不能简单换算成固定毫秒数:link_failures 按有效融合消息的消费次数计,不按 PCIe 原始采样时间计;USB 快照也来自较慢的线程,状态机可能在数次调用中重复消费同一枚举结果。
告警条件与其边界
Offroad_ChestnutNotDetected 有两条路径:本轮行车周期内 usb_failed 锁存,或处于 release 分支且驻车、进程启动超过 10 秒、运行态加 ROM 态候选数不等于一。这里的 10 秒是 ChestnutStatus 创建后的时间,不是每次进入驻车后重新计时。
其余告警各有窄边界:Offroad_ChestnutUsbSlow 仅在驻车且恰好一个运行态设备时检查速度低于 5000 Mbps,并不校验产品字符串,sysfs 缺测读成零速时也符合该比较;Offroad_ChestnutBranch 是非 release 分支且恰好一个运行态设备的提示;Offroad_ChestnutUpdateFailed 只在驻车展示固件更新失败。
Offroad_ChestnutPcieUnavailable 的文本按电源失去、恢复或纯链路失败选择:首次失电前是否曾达到 5 V 决定「连接断开」还是「运行中丢电」文案;恢复后仍要求重新点火,而不是在本周期自动解除锁存。温度告警可在驻车和行车更新,其附加文字只展示 GPU 温度,即使触发源实际上是显存温度。以上均为代码显示语义,不等于硬件电气诊断结论。
自研硬件与插件化约束
硬件诊断插件应输出独立的 observation 与 latched_fault:每条观测携带设备身份、采样时间、有效位和新鲜度;故障事件携带首次发生时刻、恢复时刻及重置原因。告警展示由宿主统一仲裁,避免插件自己清除更高优先级的安全故障。
- 车辆控制安全链不应依据这些展示用 offroad 告警直接授权执行;外置计算丢失时仍须经模型有效位、控制状态机和独立网关处理。
- 台架需分别注入:启动边沿 USB 缺失后再恢复/断开、运行中 USB 消失后恢复、连续与间隔的 LTSSM 错误、供电跌落后恢复、模型加载中/失败/回退。
- 还须覆盖温度在 5°C 迟滞带附近抖动、遥测失效和慢速 USB 快照;比较故障锁存、告警可见性与实际控制退出。
- 不得把告警消失当作故障已清。
此仓库没有 ChestnutStatus 的专门单测;五项原类方法离线探针核对驻车加载历史在行车边沿清空、USB 消失优先级、遥测缺失时的 PCIe 计数、温度迟滞和 release 缺失计时。
常见问题
告警消失是不是说明故障已经清除?
不一定。usb_failed、model_failed、power_lost、pcie_failed 都锁存到下一个 offroad→onroad 边沿才复位,用于保留行车周期内已发生的事件;其恢复语义与实时测量是两回事,不能把告警消失当作故障已清。
state 为 None 会清掉原故障吗?
不会。hardwared 只在 chestnutState 同时 alive 且 valid 时传具体 state,否则传 None;本轮不更新供电、PCIe 和温度状态,也不会自动清除原故障。没有新有效样本既不证明健康,也不必然生成新告警。
两次 LTSSM 异常等于固定毫秒数吗?
不等于。源码把 link_failures 按有效融合消息的消费次数计,不按 PCIe 原始采样时间计;USB 快照来自较慢线程,可能被数次调用重复消费同一枚举结果,所以两次异常不能简单换算成固定毫秒数。
温度告警文字为什么只显示 GPU 温度?
因为显示语义就是这样:温度告警的附加文字只展示 GPU 温度,即使触发源实际上是显存温度。过热位在有效遥测 GPU 不低于 100°C 或显存不低于 95°C 时置位,已过热时降至各阈值减 5°C 以下才清除,行车边沿不重置。
延伸阅读
- Chestnut USB 固件:快照、firmware_ok 与识别边界 —— 解释
usb_seen依赖的 USB 快照来自哪里。 - 事件、状态与告警:谁在什么时候置位 —— 对照本文的锁存与显示仲裁为何要分层。
- tinygrad 与 Chestnut 的 USB/AMD 桥接 —— 补齐模型加载与 PCIe 链路的设备侧背景。
- pandad 主循环的存活与遥测 —— 类比「存活位与有效位必须同时满足」的判定方式。
参考资料
- 项目 02 ——
openpilot-research/CHESTNUT_STATUS_ALERT_LATCH_LIFECYCLE_DEEP_DIVE.md(取用了ChestnutStatus.update()状态迁移表、缺测语义、告警条件与五项离线探针结论)。 - 项目 02 ——
openpilot-research/CHESTNUT_TELEMETRY_VALIDITY_CONTRACT_DEEP_DIVE.md(仅用于确认遥测有效位边界,未取用其未公开内容)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复