Volkswagen MEB panda safety:Gen2 CRC 边界

作者:

在

结论:Volkswagen MEB 的 panda safety 不是「按品牌名放行」,而是一组可逐帧核对的约束:MEB 选择 volkswagenMeb 安全模式与曲率转向,MEB_GEN2 额外设置 MEB_ALT_CRC;所有必需 RX 在 bus 0,使用 CRC-8H2F、四位计数器与存活检查;发送侧只放行 HCA_03、ACC_18、LDW_02、KLR_01、ACC_19、TA_01 六类地址。其中最容易被误读的一点是 Gen2 的替代 CRC:它不是「Gen2 一律不校验尾部」,标准整帧 CRC 仍可能被接受。

一、车型资格与 RX 格式

CarInterface._get_params() 为 MEB 选择 volkswagenMeb 安全模式和曲率控制;MEB_GEN2 设置 MEB_ALT_CRC。网关接线还由指纹判断,不能从品牌名推断物理总线。volkswagen_meb_init() 初始化 Gen1/Gen2 的 RX 长度与统一 TX 白名单,其中 Gen2 的 Motor_51 由 32 字节变为 48 字节,ESC_51 由 48 字节变为 64 字节。

RX 报文 频率 Gen1 / Gen2 长度 作用
LH_EPS_03 100 Hz — 驾驶员扭矩。
Motor_14 10 Hz — 制动状态,再由通用 RX 规则参与退出。
GRA_ACC_01 33 Hz — Set/Resume 释放沿且主开关开时使能;Cancel 位使其退出。
QFK_01 50 Hz 32 字节 测量曲率;本模式 max_curvature_error=0,不运行相对误差限幅。
ESP_21 50 Hz — 独立速度源。
Motor_51 50 Hz 32 / 48 字节 ACC 状态 2 表示主开关可用,3/4/5 表示巡航接合;否则撤销 controls_allowed。
ESC_51 50 Hz 48 / 64 字节 四轮原始速度判断移动并形成主速度。

频率是检查配置,并非对每帧的实时 deadline 保证;计数器从字节 1 低四位、报文 CRC 从字节 0 读取。双车速这条链尤其要谨慎:ESC_51 形成一个速度源,ESP_21 提供独立速度源,曲率安全 helper 调用 speed_mismatch_check(),但不能用任一消息单独证明双源一致。

二、Gen2 替代 CRC 的真实边界

Gen2 替代 CRC 只影响 QFK_01、ESC_51 和 Motor_51。其逻辑是:先按整帧算标准 CRC;若开启替代标志,再按 28/60/44 字节前缀和另一组 salt 计算,只有前缀计算值等于字节 0 时才返回该值。因此标准整帧 CRC 仍可能被接受,前缀算法的接受范围则要结合车辆实报文确认。

源文档给出的三项离线探针把这条边界说得很具体:对 QFK_01 的 32 字节帧,写入前缀 CRC 后修改索引 30 仍被接受,修改索引 20 则被拒;写入整帧 CRC 的帧修改索引 30 被拒。原因是 QFK_01 前缀长度 28 含校验字节,因此前缀算法不保护尾部索引 28..31。该结论只针对本机构造的 QFK_01 报文,不能外推为 Gen2 所有消息都忽略尾部或真实 ECU 会产生这种变异。

三、TX 白名单与安全门

地址 bus/长度 专属载荷检查
0x303 HCA_03 0/24 曲率、请求状态为 4 时的激活位、转向功率;共享曲率 helper。
0x14D ACC_18 0/32 加速度、HMS 停车状态、起步/保持位与 ACC 活动状态。
0x397 LDW_02 0/8 无本模式专属载荷分支。
0x25D KLR_01 0/8 与 2/8 无本模式专属载荷分支;仅 bus 2 项带 check_relay。
0x300 ACC_19 0/48 无本模式专属载荷分支。
0x26B TA_01 0/8 无本模式专属载荷分支。

通用 safety_tx_hook() 先按地址、bus、长度白名单过滤,再调用车型 TX 钩子,最终还受继电器故障阻断;静态转发只在 bus 0↔2 间,阻断目的总线中带 check_relay 的地址。TX 准入不是 ECU 已接受、仪表内容正确或原车 AEB 不受影响的证明。

ACC_18 的加速度量纲为 0.001 m/s²,活动范围 -3.5 至 2.0,未激活专用码为 3.01;停车请求 HMS=1(保持)或 4(起步)仅在允许控制时可发,0(无请求)与 5(坡道释放)可在退出后发。HCA_03 采用有符号曲率、请求位和功率三类输入,最大绝对曲率 29105、功率 125、名义频率 50 Hz;未请求转向时曲率必须为 0、功率必须为 0。一个关键细节:控制许可撤销后,带请求位的严格递减功率可作为退出时的降功率路径,不能把它误写成「失能后所有请求位帧必拒」。

四、自制硬件与插件边界

车型插件须提交 MEB 代际、DBC、接线位置和 CRC 变体的证据;未经确认时保持只读,不能仅按 ID.4/Born 名称自动授予 TX。感知/定位插件应分别报告 ESC_51 与 ESP_21 的来源、时间戳及健康;控制插件不能自行合并双车速再宣称冗余检查已通过。纵向控制插件应输出带语义的「加速度 / 保持 / 起步 / 坡道释放 / ACC 状态」,由可信任网关负责编码与状态序列,MCU 保留独立的字段检查和失联门。

HUD、TA 与 KLR 白名单帧缺专属载荷检查,插件网关需给这些帧最小模板、速率和所有权,不能开放任意原始 CAN 写入。验证顺序应包含 Gen1/Gen2 CRC 尾部变异、错长度/计数、双车速失配、按钮沿、失联时保持/释放与功率降阶。现有 test_volkswagen_meb.py 覆盖两代配置、计数/校验、双车速、曲率功率、加速度与停车状态;本机运行该模块 90 项,7 项跳过,其余通过,但它不代替上述 Gen2 前缀/整帧 CRC 尾部变异探针,也未验证目标硬件。

常见问题

Gen2 是不是「不校验尾部 CRC」?

不是。Gen2 替代 CRC 只影响 QFK_01、ESC_51 和 Motor_51,且先按整帧算标准 CRC;只有前缀计算值等于字节 0 时才返回该值,所以标准整帧 CRC 仍可能被接受。QFK_01 前缀长度 28 含校验字节,故前缀算法不保护尾部索引 28..31,这只是一个具体探针结论,不能外推为所有消息都忽略尾部。

两条车速报文能互相证明冗余吗?

不能。ESC_51 从四轮原始速度形成主速度,ESP_21 提供独立速度源,曲率 helper 调用 speed_mismatch_check(),但源文档明确不能用任一消息单独证明双源一致。控制插件也不能自行合并双车速再宣称冗余检查已通过。

失能后所有带请求位的转向帧都会被拒吗?

不是。源文档指出控制许可撤销后,带请求位的严格递减功率可作为退出时的降功率路径,相邻测试 test_power_without_control() 为此设了专门断言,不能把它误写成「失能后所有请求位帧必拒」。

按车型名 ID.4/Born 就能自动授予发送权限吗?

不能。车型插件须提交 MEB 代际、DBC、接线位置和 CRC 变体的证据,未经确认时保持只读;源文档明确不能仅按 ID.4/Born 名称自动授予 TX。网关接线位置还由指纹判断,不能从品牌名推断物理总线。

延伸阅读

参考资料

  • 项目 02 —— openpilot-research/VOLKSWAGEN_MEB_PANDA_SAFETY_DEEP_DIVE.md(取用了 MEB 车型资格、RX 格式与使能链、Gen2 替代 CRC 边界、TX 白名单与安全门、硬件插件边界)。

说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

更新记录

首次发布 2026-10-11 最近核对:2026-10-11

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注