结论:Ford safety 的核心不是「有没有白名单」,而是双车速源、质量位、曲率/jerk 门与构建变体共同构成的判据。ABS 与 PCM 第二车速名义 50 Hz、yaw 100 Hz,曲率由 yaw 除以经下界保护的车速得到;CAN FD 的自控纵向 TX 白名单只在 ALLOW_DEBUG 且纵向参数位置位时开放。因此官方测试套件默认带 ALLOW_DEBUG,不能用来证明 release 固件开放该能力。
函数与责任
| 函数 | 输入、状态或约束 |
|---|---|
ford_get_counter()、ford_get_checksum()、ford_compute_checksum() |
从 ABS 车速与 yaw 帧提取/计算计数和校验;其它 RX 消息靠检查表选择忽略。 |
ford_get_quality_flag_valid() |
ABS、PCM 第二车速和 yaw 的指定质量位必须为 3;其余 RX 帧在配置表中显式忽略质量位。 |
ford_rx_hook() |
ABS 与 PCM 双车速进入共享状态;yaw 除以经过下界保护的车速后形成实测曲率;另更新停车、油门、刹车和原车巡航状态。 |
ford_tx_hook() |
检查 ACCDATA、方向盘按钮、Lane Assist 和两种 LateralMotionControl;返回 false 拒绝候选帧。 |
ford_init() |
选择 6 条 RX 健康规则、经典 CAN/CAN FD TX 白名单及调试编译门;没有 Ford 专属转发钩子。 |
RX 数据与新鲜度
总线 0 上,ABS 车速和 PCM 第二车速名义 50 Hz、yaw 100 Hz、刹车/巡航 10 Hz、油门 100 Hz、停车状态 50 Hz。ABS 帧检查校验、4 位计数和质量位;yaw 帧检查校验、8 位计数和质量位;PCM 第二车速帧忽略计数器和校验和,但仍检查质量位,源码注释将此与某些 ECU 的跳计数/短暂校验异常联系起来。其余三类无计数/校验帧在配置中也忽略质量位。
共享 rx_msg_safety_check() 先更新检查状态;只有当前帧有效且匹配 RX 检查表时,safety_rx_hook() 才调用 ford_rx_hook()。坏校验/质量帧不能按这条调用链更新 Ford 车况,而且有效性失败可撤销 controls_allowed。共享曲率检查中的 speed_mismatch_check() 再比较双速度源;自制网关若合并来源、丢失质量位或用单一速度伪造两路,将破坏这层判据。一个关键细节:yaw 可能先于新车速到达,此时曲率使用的是已保存车速,不能声称两个采样硬件同步。
ford_init() 选择 6 条 RX 健康规则;FORD_COMMON_TX_MSGS 对两个按钮总线设 check_relay=false,其余列出的发送帧设为 true;共享 safety_fwd_hook() 依据当前 TX 表静态阻断从相机总线向主总线转发的受控地址,因此经典 CAN 与 CAN FD 的阻断集合也随模式变化。这些白名单都含 Steering_Data_FD1 的 0/2 两路和 ACCDATA_3、Lane_Assist_Data1、IPMA_Data 的 0 路;Ford 函数单独调用不能代表完整安全判定。
TX 模式矩阵与位级门
| 选择 | ACCDATA |
横向报文 | 依据 |
|---|---|---|---|
| 经典 CAN,任意纵向参数位 | 白名单包含 | LateralMotionControl |
FORD_LONG_TX_MSGS;并非参数位才开放。 |
| CAN FD,默认或 release 固件 | 白名单不含 | LateralMotionControl2 |
FORD_CANFD_STOCK_TX_MSGS。 |
CAN FD,ALLOW_DEBUG 且纵向参数位置位 |
白名单包含 | LateralMotionControl2 |
FORD_CANFD_LONG_TX_MSGS 与 ford_init() 的编译门。 |
ford_tx_hook() 对 ACCDATA 同时检查请求油门、预测油门、制动加速度及制动预充/减速位;CmbbDeny_B_Actl 为 1 一律拒绝,以免禁止原车 AEB。get_longitudinal_allowed() 还要求使能且驾驶员未踩油门;禁用时仅允许各字段的中性编码。cancel 只在前次原车巡航已接合时放行,resume 只在 controls_allowed 时放行;Lane Assist 的执行动作必须为零。
两个横向格式分别解析曲率、曲率率、路径角/偏移,后面三项必须保持源码规定的 inactive 原始编码。steer_curvature_cmd_checks() 再检查绝对曲率、随车速变化的横向加速度/jerk、与实测曲率的偏差及非使能中性值;它会维护 desired_last,拒帧时清零,因而更换插件或安全模式时不能把拒帧当作完全无状态事件。另外,ACCDATA_3 与 IPMA_Data 在 Ford TX 钩子中没有专属载荷检查,不能把白名单解释成逐信号验证。
证据、缺口与插件边界
test_ford.py 定义经典 CAN 纵向、CAN FD 原车纵向和 CAN FD 自控纵向三类具体测试配置。2026-10-04 在本地用原版 CANPacker、CFFI 和编译的 libsafety 运行 python -m unittest opendbc.safety.tests.test_ford -q:102 项中 91 项通过、11 项跳过。跳过的是三种具体配置均无 _user_regen_msg 的九个通用再生制动用例,以及两个抽象基类的 setUpClass,不是 Ford 曲率或纵向边界失败。
但要注意:测试库的 _build_libsafety() 默认加 ALLOW_DEBUG,所以这次官方套件不能证明 release 固件开放 CAN FD 自控纵向 TX 白名单。七项帧级离线探针分别编译不带/带 ALLOW_DEBUG 的原 libsafety,确认:界内曲率帧通过;坏 ABS 质量位不更新车速并撤销 controls_allowed;两路合法但相差 5 m/s 的车速在曲率 TX 时触发失配退出。面向「万物即插件」,Ford 车型插件应声明经典/CAN FD、总线拓扑、DBC、纵向能力、固件构建变体和 safetyParam,并把两路车速及 yaw 的来源、质量位、时间戳分别传到受信任安全层。
常见问题
为什么 yaw 先到会用到旧车速?
因为源码注释明确指出 yaw 可能先于新车速到达,此时曲率使用的是已保存车速;因此不能声称两个采样硬件同步。探针也确认,先更新 ABS 车速再更新 yaw 时,实测曲率在新 yaw 到达前保留旧值。
PCM 第二车速为什么忽略计数器与校验和?
源码注释将此与某些 ECU 的跳计数/短暂校验异常联系起来。但该帧仍检查质量位,质量位不为 3 时不能更新车速。
CAN FD 的自控纵向在 release 固件下能开吗?
默认或 release 固件的白名单不含 ACCDATA;只有 ALLOW_DEBUG 且纵向参数位置位时才使用 FORD_CANFD_LONG_TX_MSGS。官方测试套件默认带 ALLOW_DEBUG,所以不能据此证明 release 固件已开放该能力。
白名单里出现 ACCDATA,说明每个信号都被校验了吗?
不是。白名单只核对地址/总线/长度并调用 ford_tx_hook(),而 ACCDATA_3 与 IPMA_Data 在该钩子中没有专属载荷检查。白名单准入不等于逐信号验证,也不等于 ECU 接受。
延伸阅读
- CAN FD 与经典 CAN 的安全模式差在哪 —— 承接本文编译门与白名单随模式变化的对照。
- 横向限幅的四种算法:主机候选与 panda 判决为什么不是一件事 —— 承接本文曲率/jerk 门与实测曲率偏差检查。
- 从使能到车轮:执行链上的八道门,以及它们各自不保证什么 —— 解释白名单准入为何不等于执行。
- panda 板级固件:三条 CAN 路径与 1 Hz 巡检的真实边界 —— 承接 RX/TX/转发钩子的板级执行链。
- VW 与 Subaru 车型协议:白名单与匹配门怎么各管一段 —— 对照其它车厂的模式组装方式。
参考资料
- 项目 02 ——
openpilot-research/FORD_PANDA_SAFETY_MODE_DEEP_DIVE.md(取用了 RX 数据与新鲜度、TX 模式矩阵与位级门、测试证据与缺口,以及插件边界)。 - 项目 02 ——
openpilot-research/PLUGIN_REFACTOR.md(仅用于确认车型插件与安全模式归位的引用位置)。
说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。
更新记录
首次发布 2026-10-11 最近核对:2026-10-11
发表回复