标签: DBC

  • 设备 CI 的四道门:锁、凭据、检出与测试跳过判定

    结论:设备 CI 的保护不是一道门,而是四道:设备锁、凭据注入、检出隔离与测试跳过判定。真正的风险不在「CI 通过」,而在两处静态缺口——差异列表用子串匹配判断是否跳过步骤,且检出快路径会保留被忽略文件与旧构建产物。UNSAFE=1 只是检出快路径的环境变量,不是车辆 safety 许可。

    阶段骨架:node 到 deviceStage

    流水线从 node 开始:setupCredentials() 注入三类 token,checkout(scm) 取分支/提交,再按分支选择 staging/nightly 或常规矩阵。特殊 chestnut-stresstest 最多循环 100 次并归档报告;其余按分支触发 staging/nightly,未排除分支运行常规并行矩阵。整个流水线的控制权都集中在 Jenkinsfile 的 node 段,因此插件化改造的关键不是换脚本,而是把设备锁、凭据与步骤过滤各自契约化。

    函数/阶段 主要实现契约
    setupCredentials() 从 Jenkins 凭据读三类 token 并放入 env;后续 device() 把它们扩展到远端 shell 环境。SSH 私钥另在 withCredentials 中取得。
    device() 用 alpine-ssh 包装的远端 SSH;连接禁用严格主机密钥检查。AGNOS 上清临时目录/共享内存、必要时启动 DNS 与重绑 USB hub;链接 Python 路径,执行步骤并等待子进程退出。
    deviceStage() 禁止 Jenkins Replay;按设备标签 lock(quantity: 1) 独占,在 Docker 中给整个阶段 35 分钟;设备时间同步与检出一起最多重试三次,测试步骤本身不自动重试。
    hasPathChanged() 对 GitHub compare 的返回字符串做子串匹配,不是解析已验证的文件列表;非 master/非 Jenkins loop 分支可据 diffPaths 跳过部分 build/test。
    chestnutStage() build、Chestnut 模型回放和指定 TestChestnutOnroad;设备标签为 mici-chestnut-ci。

    devel-staging 调用设备上的 build_release.sh 推 tizi/mici staging;__nightly 同时提交普通与 PANDA_DEBUG_BUILD=1 变体;__nightly-chestnut 加入 INCLUDE_BIG_MODEL=1。普通矩阵并行覆盖 onroad、功耗/编码器/manager、两种 camerad、sensord、模型回放、panda loopback/SPI/功放及 Chestnut。

    凭据与 SSH 信任边界

    setupCredentials() 从 Jenkins 凭据读 Azure、CI 工件、GitHub 评论 token 并放入 env,随后 device() 把它们扩展到远端 shell 环境;SSH 私钥另在 withCredentials 中取得。远端连接禁用严格主机密钥检查,因此 CI 网络、节点与凭据范围应被视为独立信任边界。

    需要分清的是:lock(label=...) 是 Jenkins 设备池的并发协调,不是车端进程互斥。在自建硬件平台上应收紧主机验证并落实凭据最小权限,而不是把 CI 的协调机制误当作运行时的排他保证。

    从信任边界看,凭据实际有三层:Jenkins 环境中的凭据存储、经 device() 扩展到远端 shell 的环境变量,以及独立取得的 SSH 私钥。三层的作用域应各自最小化,远端主机验证应收紧;本地 ZIP 归档无法代表真实 Jenkins 插件及凭据配置,因此本文的结论只到脚本与流水线文本层。

    检出两条路径:unsafe 与 safe

    setup_device_ci.sh 先要求 SOURCE_DIR、GIT_COMMIT、TEST_DIR,清数据与 staging 目录,再写 /data/continue.sh。该脚本中的 continue.sh 内容含 abctl --set_success、sshd/NetworkManager 修改与长循环;此处只写文件并设可执行位,后续由什么启动机制执行应另行验证,不能把写入等同于本轮已执行。

    路径 实现 结果/代价
    快路径 unsafe_checkout() 直接在 TEST_DIR fetch/强制 checkout/reset,清理,对子模块做 reset/clean/update。 不使用忽略文件清理标志,忽略文件和旧构建产物可留存;失败后回退 safe。
    全清路径 safe_checkout() 在 SOURCE_DIR fetch 固定提交,清顶层内容、全量清理与子模块,拉 LFS,再 rsync -a --delete 到 TEST_DIR。 删未跟踪/忽略文件和目标旧内容,隔离更强但仍依赖 Git 远端、LFS 与 rsync 成功。
    LFS pull_lfs() CHESTNUT 时拉全部;普通设备排除 big driving 模型,必要时恢复指针并删对应本地 LFS 对象。 防止普通设备携带大模型实体;只代表该脚本处理的路径,不证明所有模型/构建输入完整。
    包导入路径 在 TEST_DIR 创建 msgq/opendbc/rednose/teleoprtc/tinygrad 包链接,与运行时 Python 导入结构对齐。 链接结构需与运行时一致,否则导入行为分叉。

    safe_checkout() 在脚本中会删除工作目录内容、源仓锁文件与设备真实路段缓存;这只能在专用 CI 设备上使用,不能作为用户车辆的插件更新机制。

    跳过与漏测风险:hasPathChanged 的子串匹配

    deviceStage() 用 curl -s ... | jq ... || echo "/" 取得差异;未使用失败即错选项、管道错误传播或结构化校验。API/解析失败可能返回仅 /,后续 hasPathChanged() 找不到目标路径,导致带 diffPaths 的步骤被跳过。这是代码路径风险,不表示当前 CI 已发生漏测。

    跳过的范围也需准确理解:diff 是与 master 比较后的文本,跳过仅应用于带 diffPaths 的步骤且非 master/非 Jenkins loop,不是整个矩阵的开关。模型回放路径的 build 和 replay 都带同一过滤条件,其他硬件测试大多总跑。

    CI 绿灯不等于实车授权

    Chestnut 压测仅对特定中断异常记 FAIL 并继续,其它异常会使循环中断,但 finally 仍归档包含 INCOMPLETE 的报告;常规分支的测试集合还受设备资源、差异跳过和环境变量影响。因此 CI 绿灯不能替代完整覆盖,也不能作为实车安全性的证明。本专题未运行 Jenkins Groovy、compare API、SSH、设备锁、模型回放或硬件测试。

    换句话说,四道门保护的是「谁来跑、在哪跑、跑什么、跑哪些」这四件事,它们各自都有可被绕过的边界;把它们理解为一条不可绕过的单一闸门,正是设备 CI 最常见的误读。

    常见问题

    为什么差异接口失败可能导致步骤被跳过?

    因为 deviceStage() 用 curl -s ... | jq ... || echo "/" 取得差异,未使用失败即错、管道错误传播或结构化校验。API/解析失败可能返回仅 /,hasPathChanged() 找不到目标路径,带 diffPaths 的步骤就会被跳过。

    省略的检出快路径有什么代价?

    unsafe_checkout() 不使用忽略文件清理标志,忽略文件和旧构建产物可留存,因此隔离更弱;失败后才回退到 safe_checkout()。这条快路径仅适用于专用 CI 设备。

    lock 是否等同于车端进程互斥?

    不等同。lock(label=...) 是 Jenkins 设备池的并发协调,不是车端进程互斥。CI 网络、节点与凭据范围应被视为独立信任边界,并在自建硬件平台收紧主机验证与凭据最小权限。

    CI 全绿是否代表实车安全可用?

    不代表。Chestnut 压测仅对特定中断异常记 FAIL 并继续,其它异常会中断循环但仍归档 INCOMPLETE 报告;常规测试集合还受设备资源、差异跳过和环境变量影响,CI 绿灯不能替代完整覆盖。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/JENKINS_DEVICE_CI_CHECKOUT_LOCK_CREDENTIAL_TEST_GATE_DEEP_DIVE.md(取用了阶段骨架、凭据与 SSH 边界、检出两路径及跳过与信任边界)。
    • 项目 02 —— openpilot-research/RELEASE_BUILD_FILE_SELECTION_LFS_PUSH_CONTRACT_DEEP_DIVE.md(仅用于确认发布构建与强推语义的边界)。

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

    更新记录

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

  • GM panda safety:三个参数位切换拓扑,白名单不等于字段认证

    结论:GM panda safety 按 HW_CAM、HW_CAM_LONG、EV 三个参数位切换硬件拓扑与 TX 表,三者的使能与转发策略互不相同:ASCM 分支 disable_forwarding=true 完全禁转发、由按钮沿使能;相机原车纵向跟随 PCM;相机自控纵向仅在调试构建且 HW_CAM_LONG 置位时才把 gm_pcm_cruise 改为假。白名单只控制 CAN 地址、总线、长度,不代表所有字段都经安全认证。

    本文基于固定源码快照逐函数静态解析 opendbc/safety/modes/gm.h,结合通用 safety 分发与本机原版 GM 测试。未编译目标固件或接入车辆;这里的总线号、编码和阈值仅适用于该源码快照及匹配车型,不能直接当作新硬件配置。

    RX:来源、使能与完整性缺口

    GM_COMMON_RX_CHECKS 监视总线 0 的 0x184 驾驶员扭矩、0x34A 后轮速度、0x1E1 按钮、0xBE 踏板、0x1C4 油门/巡航和 0xC9 制动状态;0xBE 允许三种长度以适配不同车型。各项暂以 10 Hz 标称检查,且显式忽略校验和、计数器、质量位——源码 TODO 指出这不是完整报文完整性校验。EV 参数位另把 0xBD 再生制动消息纳入 RX 表,频率配置为 40 Hz。

    报文 用途 完整性处理
    0x184 驾驶员扭矩(11 位有符号,进共享采样窗口) 忽略校验和/计数器/质量位
    0x34A 后轮双速;两轮原始速度均不超过 10 判静止 停车判据,不是完整车速估计
    0x1E1 按钮沿使能(ASCM 用 SET 松开沿或 RESUME 按下沿) 忽略完整性字段
    0xBE ASCM 刹车(字节阈值);允许三种长度 与相机刹车帧 0xC9 不是同义来源
    0x1C4 相机原车纵向读取巡航接合状态 走 pcm_cruise_check()
    0xC9 相机刹车(bit 40) 与 0xBE 不能互换
    0xBD EV 再生制动,仅 EV 参数位置位时入 RX 表 配置为 40 Hz

    safety_rx_hook() 只在检查通过、命中表后调用 gm_rx_hook(),因此再生制动分支并非在非 EV 模式下无条件接收。ASCM 以 0x1E1 的 SET 松开沿或 RESUME 按下沿使能,CANCEL 按下退出;相机原车纵向则从 0x1C4 读取巡航接合状态。

    TX 与模式矩阵

    GM 自控纵向时 gm_pcm_cruise=false;相机原车纵向时为 true。相机自控纵向仅在调试构建且 HW_CAM_LONG 位置位时把它改为假。这决定使能来自按钮沿还是 PCM,影响告警与执行权限,不只是 TX 白名单的变化。

    模式 纵向 TX 转发与使能
    ASCM,HW_CAM=0 0x2CB 位于总线 0,0x315 位于总线 2;另有观测/keepalive 帧 disable_forwarding=true,由按钮沿使能
    相机,默认或 release 无 0x2CB/0x315;0x1E1 总线 2 仅允许取消 跟随 PCM 巡航接合,仍可发横向 0x180
    相机,ALLOW_DEBUG 且 HW_CAM_LONG=1 0x2CB/0x315 总线 0 改用按钮沿,禁原车 0x1E1 TX
    上述模式叠加 EV 不改变所选 TX 表 仅增加 0xBD 再生制动 RX

    gm_tx_hook() 对 0x180 调用共享扭矩安全检查,含 300 原始单位上限、变化率、驾驶员扭矩与实时增量限制。0x315 的 12 位原始编码先反转为非负制动量,再用 longitudinal_brake_checks() 限制到 max_brake=400 且未使能时必须为零。0x2CB 将油门/再生制动信号偏移到整数域后分别按 ASCM/相机限值检查,apply 位在 controls_allowed=false 时禁止。相机原车纵向的 0x1E1 只有原车巡航已接合且按钮编码为 CANCEL 时放行。

    白名单不等于字段认证

    并非所有 GM 白名单帧都有逐信号检查:例如 ASCM 的 keepalive/观测帧和相机的 0x184 状态帧,在 gm_tx_hook() 中没有对应载荷分支。白名单控制的是 CAN 地址、总线、长度。

    转发层面同样分层:相机模式中 0x184 总线 2 的 check_relay=true 会使共享转发逻辑阻断来自总线 0、目标为总线 2 的同地址帧;ASCM 则完全禁转发。应把「是否允许发」「是否阻断原车转发」「是否检测原车 ECU」分别建模。

    验证范围与插件边界

    test_gm.py 有 ASCM、相机、EV、相机自控纵向测试类,包含按钮、踏板、扭矩/纵向限值和点火用例。本机运行原版 GM 模块测试为 Ran 192 tests、OK (skipped=19),即 173 项执行且通过,19 项未执行。跳过项来自无 _user_regen_msg 的通用再生制动用例、无第二车速消息的通用检查,以及四个抽象基类的 setUpClass,不能计入通过。

    测试调用 libsafety_py._build_libsafety() 默认加 ALLOW_DEBUG,因此相机自控纵向用例不能证明 release 固件接受 HW_CAM_LONG。本机另用严格警告把测试库 safety.c 分别编译为不含/含 ALLOW_DEBUG 的目标文件,只在后者找到 GM_CAM_LONG_TX_MSGS——这核对的是本机编译分支,不是 STM32 固件或运行时许可。实板转发、实际 CAN 来源和目标 ECU 响应仍未测试。

    • 自制硬件的 GM 插件契约应固定车型/DBC、ASCM 或相机接线、EV 位、总线号、固件构建类型和 safetyParam。
    • 只读采集和回放先验证 0xBE 长度变体、0xC9 刹车、0xBD 再生制动、按钮沿、PCM 巡航及 0x184 驾驶员扭矩。
    • 台架再做丢帧、重放、错总线、故障继电器和 release/debug 差异。
    • 普通插件只产生候选控制,不能设置安全钩子或绕过板端 TX/转发判定。

    常见问题

    GM 白名单里的帧都经过字段级安全检查吗?

    不是。白名单只控制 CAN 地址、总线、长度;ASCM 的 keepalive/观测帧和相机的 0x184 状态帧在 gm_tx_hook() 中没有对应载荷分支,不能据此声称所有字段都经过安全认证。

    相机自控纵向在 release 固件里能用吗?

    测试不能证明。相机自控纵向仅在调试构建且 HW_CAM_LONG 位置位时把 gm_pcm_cruise 改为假;而测试默认加 ALLOW_DEBUG,本机只在含该宏的目标文件里找到 GM_CAM_LONG_TX_MSGS,这核对的是编译分支而非运行时许可。

    ASCM 和相机的刹车帧可以互换吗?

    不能。ASCM 的刹车取 0xBE 字节阈值,相机刹车取 0xC9 的 bit 40,切换拓扑时不能把两种刹车帧视为同义来源;0xBE 还允许三种长度以适配不同车型。

    GM 的 RX 完整性与校验和有关系吗?

    没有做完整校验。各项暂以 10 Hz 标称检查,且显式忽略校验和、计数器、质量位;源码 TODO 指出这不是完整报文完整性校验。所以「命中 RX 表」不等于「报文完整可信」。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/GM_PANDA_SAFETY_MODE_DEEP_DIVE.md(取用了 GM 三参数位模式矩阵、RX/TX 与转发边界、白名单不等于字段认证,以及本机测试计数)。
    • 项目 02 —— openpilot-research/ACTUATION_GATE_CHAIN_DEEP_DIVE.md(仅用于确认执行链分层语义,未取用其未公开内容)。

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

    更新记录

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

  • 起亚 Soul EV(PS)DBC 档案:转向、制动与四轮速信号

    结论:这是一份以起亚 Soul EV(PS)命名的 DBC 数据档案,由两部分组成:一份「整车」文件记录可读的转向角、制动压力与四轮车速(每 20 毫秒更新,单位分别为度、Bar、KPH);一份「DriveKit」文件记录可写的转向角、转向扭矩、油门踏板与制动踏板命令(同样 20 毫秒)。三条硬边界:其一,这不是厂家整网定义,而是研究与自动驾驶平台用的消息集合;其二,文档把底盘控制(雨刮、转向灯、喇叭、大灯、读 VIN)标为 Niro 专用,每条 DriveKit 消息是否适用于 Soul EV「未建立」;其三,所有声明的量程都是 [0|0],不能当作真实范围。

    本文整理自该项目的 DBC 说明与其来源说明。来源说明本身就把适用范围、许可与验证状态标得很保守,本文原样保留这些限定。

    车辆与适用范围

    仓库说明该项目是一个起亚 Soul EV 的 CAN 记录与解码脚本,用于某实验室的自动驾驶平台采集;DBC 覆盖范围被描述为「有限」。来源说明进一步指出:这是记录集合而非出厂整网,本归档也未针对具体年款、配置或固件做过独立核对。

    项 内容
    车型 起亚 Soul EV(PS)
    年款 / 市场版本 源文档未确认(未绑定具体年款、配置或固件)
    ECU / 改装状态 面向自动驾驶平台的数据采集;DriveKit 为可写命令集
    采集跨度 源文档未给出;说明称用于 AV 平台数据采集,本归档未核对原始采集
    适用范围 仅该 DBC 快照;DriveKit 消息对 Soul EV 的适用性未建立

    总线与寻址

    来源说明没有给出该车的总线速率或 11 位 / 29 位寻址结论,也没有 CAN FD 的说明。文档给出的是消息与信号的名称、方向(读 / 写)与周期,属于应用层与数据层;物理层与链路层细节属源文档未覆盖项,本文不补。

    项 内容
    物理层 源文档未给出
    链路层 源文档未给出
    寻址 源文档未给出 11 位 / 29 位结论
    CAN FD 源文档未提及
    消息周期 文档列出的信号多为 20 毫秒周期

    已解码信号

    下表分「整车文件(只读)」与「DriveKit 文件(可写)」两组。所有声明的物理量程均为 [0|0],因此「单位」是文档给出的量纲,不是经验证的范围。表格中凡「Niro only」者不得套到 Soul EV。

    信号 / 命令 来源与方向 解码 / 取值 证据
    Steering Angle(整车) Vehicle DBC,只读 度,20 毫秒 源文档规格表
    Brake Pressure(整车) Vehicle DBC,只读 Bar,20 毫秒 源文档规格表
    Individual Wheel Speed(整车) Vehicle DBC,只读 KPH,20 毫秒(四个轮速) 源文档规格表
    steering_angle_cmd_flags DriveKit STEERING_ANGLE_COMMAND,写 Disable / Enable 源文档命令表
    steering_angle_cmd_angle 同命令消息 度 源文档命令表
    steering_angle_cmd_max_velocity 同命令消息 度(文档示例用 300) 源文档命令表与示例
    steering_angle_report_flags DriveKit STEERING_ANGLE_REPORT,读 Enable / Disable,每 20 毫秒发布 源文档报告表
    steering_angle_report_errors 同报告消息 Angle Missing / Angle Irrational / Module Disabled / Command Rejected 源文档报告表
    steering_enable_magic DriveKit STEERING_ENABLE 默认 magic number(用于先使能扭矩控制器) 源文档示例
    Steering Torque DriveKit,写 度,20 毫秒 源文档规格表
    Throttle Pedal Position DriveKit,写 百分比,20 毫秒 源文档规格表
    Brake Pedal Position DriveKit,写 百分比,20 毫秒 源文档规格表
    CHASSIS_CONTROL_COMMAND(Niro only) DriveKit,写 前雨刮(off / intermittent / slow / fast)、后雨刮(off / on)、左右转向灯、喇叭、读 VIN、大灯(off / low / high) 源文档命令表,标注 Niro 专用

    读取方法与注意事项

    转向角命令三步走。文档给出的顺序是:先发 STEERING_ENABLE(带默认 magic number)使能转向扭矩控制器;再发 STEERING_ANGLE_COMMAND,其中 flags 置 Enable、angle 设目标角、max_velocity 设最大角速度(示例用 300 度/秒);最后应能在总线上看到 STEERING_ANGLE_REPORT 回报 flags 为 Enable、errors 为 None。

    命令互斥与越界拒绝。文档明确:转向角命令与转向扭矩命令不能同时使用,二者互斥。示例还演示越界:请求超过车辆能力的角度(9999 度)时回报变为 flags 为 Disable、errors 为 Command Rejected,控制器自我禁用。

    底盘控制是 Niro 专用。CHASSIS_CONTROL_COMMAND 可在一条消息里同时设置一个或多个底盘部件(雨刮、转向灯、喇叭、大灯,以及请求 VIN),但文档把这组功能标为 Niro only。是否适用于 Soul EV,来源说明写明「未建立」,因此不能照搬。

    写命令有实车风险。DriveKit 文件里转向、油门、制动等都是写入类命令,一旦发送就会作用在真实车辆上。本文只转述文档记录,不构成操作指引。

    证据等级与边界

    第一层是覆盖范围:来源说明写明整车文件只有 3 条消息、6 个信号,DriveKit 文件有 15 条消息、32 个信号,这是一套研究用的消息集合,不是厂家整网定义。

    第二层是数据质量:每个声明的物理范围都是 [0|0],来源说明把它列为需要独立复核的信号准确性问题;DriveKit 说明文件还提到 Niro 专用的底盘控制,因此「每条 DriveKit 消息都适用于 Soul EV」并未成立。

    第三层是来源状态:项目自报做了 AV 平台采集,但本归档未将该副本与其采集数据、具体年款 / 配置 / 固件做独立核对;快照中也未发现仓库级许可证,仅作私有离线研究副本保留。据此,本文的信号与方向只能视为「这份 DBC 所声明的范围」,不能外推到其他 Soul EV 或其他起亚车型。

    常见问题

    这份 DBC 是起亚 Soul EV 的整车出厂网络吗?

    不是。来源说明写明整车文件只有 3 条消息、6 个信号,DriveKit 文件有 15 条消息、32 个信号,是一套研究 / AV 平台用的消息集合,而非厂家整网定义。

    为什么每个信号的物理范围都写成 [0|0]?

    因为源 DBC 就是这么声明的,来源说明也把它列为「信号准确性需要独立复核」的问题。所以 [0|0] 不能当作真实量程,表格里的「度 / Bar / KPH / 百分比」只是文档给出的量纲。

    转向角命令和转向扭矩命令能一起发吗?

    不能。文档明确二者互斥,不能同时使用。示例演示的顺序是先发使能消息,再发转向角命令,并通过报告消息确认 flags 为 Enable、errors 为 None。

    Niro 的底盘控制能不能套到 Soul EV?

    未确认。文档把这组底盘控制(雨刮、转向灯、喇叭、大灯、读 VIN)明确标注为 Niro only;来源说明也指出「每条 DriveKit 消息是否适用于 Soul EV 尚未建立」。因此不能照搬到 Soul EV。

    转向角报告里会出现哪些错误?

    文档列出的四种是:Angle Missing(角度缺失)、Angle Irrational(角度不合理)、Module Disabled(模块禁用)、Command Rejected(命令被拒)。越界请求(如示例中的 9999 度)会得到 Command Rejected,随后控制器自我禁用。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/aroongta-kia-soul-ev/DBC/DBC-README.md(本项目车型档案主来源,取用了整车 / DriveKit 的信号与周期表)。
    • 项目 01 —— public-can-dbc-datasets/additional/aroongta-kia-soul-ev/SOURCE.md(取用了覆盖范围、[0|0] 量程与「未建立」等边界说明)。
    • 项目 01 —— public-can-dbc-datasets/additional/aroongta-kia-soul-ev/README.md(取用了 AV 平台采集的项目背景)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • FT86 与 MX-5 的赛道 CAN 信号:RaceChrono 公式表

    结论:这是一组面向赛道数据记录的 CAN 信号表,覆盖四类车:2013-2020 Subaru BRZ / Toyota 86 / Scion FR-S、2022 BRZ / GR86、Mazda MX-5 的 NC 与 ND 两代。它们的共同点是——老一代 FT86 与 NC/ND 的主 CAN 就在 OBD 口引脚 6/14 上,用一款 OBD 读取器即可直接抓广播帧;而 2022 BRZ/GR86(以及 2018+ WRX、许多 Porsche)把 CAN 与 OBD 口隔离了,只能拿慢速有限的 OBD 数据,或另找接入点。下表登记的是各平台可用的通道与公式,其中若干系数源文档自述为「经验值」或「可能有误」。下述条目只适用于各表所记录的车型与年款。

    车辆与适用范围

    源文档是一个 DIY BLE CAN 记录设备的说明,作者用它给一款商业赛道计时 App 供数。信号表按车型分组保留,ND 表明确说明是在一台 2019 MX-5 RF 上测试的。

    项 内容
    车型 2013-2020 Subaru BRZ / Toyota 86 / Scion FR-S;2022 Subaru BRZ / Toyota GR86;Mazda MX-5 NC(2005-2015)、ND(2019 RF 实测)
    年款 / 市场版本 各表相互独立;ND 表按 2019 MX-5 RF 测试,其他 ND 年款「应可适用」但未独立确认
    ECU / 改装状态 原厂状态;接入走 OBD 口或隐藏连接器,作者自制 nRF52840 + MCP2515 记录设备
    采集跨度 源文档未给出统一日志数;MX-5 NC 表附有一份怠速时 10 秒内的 CAN ID 直方图
    适用范围 各车型表只适用其列出的年款/代际;跨代不可套用(同一功能在不同代的 ID 完全不同)

    总线与寻址

    源文档说明 FT86 与 Miata 的老一代主 CAN 在 OBD 引脚 6/14 上;较新的车把 CAN 与 OBD 口隔离。信号表以 11 位 ID 记录(如 0x140、0xD1、0x081、0x201),源文档未展开 29 位或 CAN FD 话题,按经典 CAN 处理。

    项 内容
    物理层 双绞线 CAN;FT86/Miata 老一代主 CAN 在 OBD 引脚 6/14
    链路层 / 比特率 源文档未统一给出比特率,按经典 CAN 处理
    寻址方式 11 位 ID
    CAN FD 源文档未涉及
    接入差异 2022 BRZ/GR86、2018+ WRX 等把 CAN 与 OBD 口隔离,需另找接入点

    已解码信号

    下表从四张源表中抽取代表性信号,逐条标注车型与证据/置信度。源文档标注为经验值、可能错误或请求独立核对的系数,按原样保留。

    信号 车型 / ID 解码 证据 / 置信度
    加速踏板位置 FT86 gen1 / 0x140 A / 2.55(%) 源表「Recommended」
    加速踏板位置 FT86 gen2 / 64 E / 2.55(%) 源表「Recommended」
    制动位置 FT86 gen1 / 0xD1 min(C / 0.7, 100)(%) 0.7 为经验除数;看到频繁 100% 可改用 0.8 / 0.9
    制动压力 FT86 gen1 / 0xD1 C × 128 源表「Recommended」
    制动压力 FT86 gen2 / 313 F × 128 系数取自 gen1,源文档称「似乎吻合」
    冷却液温度 FT86 gen1 / 0x360 D − 40 → °C 源表「Recommended」
    机油温度 FT86 gen1 / 0x360 C − 40 → °C 源表「Recommended」
    转速 FT86 gen1 / 0x140 bitsToUIntLe(raw, 16, 14) 源表「Recommended」
    车速 FT86 gen1 / 0xD1 bytesToIntLe(raw, 0, 2) × 0.015694 源文档建议对 GPS 核对乘数
    车速 FT86 gen2 / 313 bitsToUIntLe(raw, 16, 13) × 0.015694 乘数同样建议对 GPS 核对,换更大/更小直径轮胎时尤其
    转向角 FT86 gen1 / 0xD0 bytesToIntLe(raw, 0, 2) × −0.1(正值为左转) 源表「Recommended」
    四轮车速 FT86 gen1 / 0xD4 每 2 字节一个轮,× 0.015694 与「车速」同乘数
    横摆角速度 FT86 gen2 / 312 bytesToIntLe(raw, 4, 2) × −0.2725 对某款外部陀螺仪标定;gen1 用 0.286478897
    横/纵向加速度 FT86 gen1 / 0xD0 bytes(6,1) × 0.2;bytes(7,1) × −0.1 源文档标注「数据噪声大」
    离合器位置 FT86 gen1 / 0x140 (B & 0x80) / 1.28(只有 0% 和非 0%) 源文档标注仅能区分 0% 与「非 0%」
    转速 MX-5 NC / 0x201 bytesToUInt(raw, 0, 2) / 4.00 源表(WIP)
    车速 MX-5 NC / 0x201 ((bytesToInt(raw, 4, 2) / 100) − 100) / 3.6 原始值含 100 km/h 偏移;/3.6 转 m/s
    制动压力 MX-5 NC / 0x085 (3.4518689053 × raw − 327.27) / 1000 kPa 乘数取自他人数据,源文档标注「可能有误」
    车速 MX-5 ND / 514 bytesToInt(raw, 2, 2) / 360.0 源表「Recommended」(2019 RF 实测)
    转速 MX-5 ND / 514 bytesToUInt(raw, 0, 2) / 4 源文档提问:若有人记录到 > 8192 rpm 请告知
    转向角 MX-5 ND / 134 (16000 − bytesToUInt(raw, 0, 2)) × 0.1(正值为右转) 源表「Recommended」

    读取方法与注意事项

    第一是通道预算:源文档提醒,每增加一个基于新 CAN ID 的通道都会增加会话文件体积,并可能拖低其他通道的更新率,因为 BLE 带宽有限;但如果新通道与已有通道共用同一个 CAN ID(例如「节气门位置」和「加速踏板位置」都用 0x140),协议会自动优化,基本不影响更新率。

    第二是接入点:FT86 与 Miata 老一代可以直接用 OBD 引脚 6/14;作者也提到可以在信息娱乐主机后方找一个隐藏连接器做完全隐式的接入。2022 之后的部分车型把 CAN 与 OBD 口隔离,这时要么接受慢速 OBD 数据,要么另找物理接入点并自制连接。

    第三是公式单位:源表的车速公式末尾带「/3.6」,是把 km/h 换成 App 内部使用的 m/s,再由 App 换算成用户选择的单位;照着抄时不要重复换算。转向角公式前的负号只是朝向约定(正值为左转或右转随车型不同),可按喜好去掉。

    证据等级与边界

    可视为有证据的是 ND 表(在 2019 MX-5 RF 上实测)与各表标注为「Recommended」的基础信号。属于经验值/待核对的是:制动位置的 0.7 除数、gen2 制动压力沿用 gen1 系数、车速乘数(建议对 GPS 核对)、MX-5 NC 的制动压力乘数(源文档自述可能有误)、横/纵向加速度(噪声大)、离合器位置(只能区分 0%)。

    不能外推的地方有两处。第一,同一功能在不同代际是不同的 ID 与公式(例如加速踏板 gen1 是 0x140、gen2 是 64),跨代套用必然出错。第二,各表相互独立,ND 表虽称「应适用于其他 ND 年款」,但只有 2019 RF 一台被实测,其他年款与配置需自行确认。

    关于「安全访问」类问题:源文档未提供任何绕过方法,且不建议尝试;这些表都是监听广播帧得到的结果,不涉及对车辆安全机制的规避。

    常见问题

    哪些车能直接从 OBD 口抓到主 CAN?

    源文档说明 2013-2020 的 BRZ/86/FR-S,以及 NC 与 ND 代 Miata,主 CAN 就在 OBD 引脚 6/14 上,用一款 OBD 读取器即可直接抓。2022 BRZ/GR86、2018+ WRX 以及许多 Porsche 把 CAN 与 OBD 口隔离了,只能拿慢速有限的 OBD 数据或另找接入点。

    2022 BRZ 和 2013-2020 的公式能通用吗?

    不能。同一功能在不同代是不同的 ID 与公式,例如加速踏板 gen1 用 0x140、gen2 用 ID 64;两代表是独立维护的。

    车速公式里的乘数需要改吗?

    源文档建议对 GPS 核对,换更大或更小直径轮胎时尤其要核对;FT86 两代都用 0.015694,MX-5 NC 用含 100 km/h 偏移的分式。

    加更多通道会影响刷新率吗?

    会,若新通道基于新的 CAN ID。源文档说明同一 CAN ID 上的多个通道不影响更新率,而基于新 ID 的通道很可能拖低所有其他通道的更新率。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/timurrrr-racechrono-can-notes/README.md(主来源:设备与接入总说明)。
    • 项目 01 —— public-can-dbc-datasets/additional/timurrrr-racechrono-can-notes/can_db/ft86.md 与 can_db/ft86_gen2.md(两代 FT86 信号表)。
    • 项目 01 —— public-can-dbc-datasets/additional/timurrrr-racechrono-can-notes/can_db/mazda_mx5_nc.md 与 can_db/mazda_mx5_nd.md(MX-5 NC/ND 信号表)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • Cabana CAN 分析:五种输入源、MessageId 严格解析与保存陷阱

    结论:Cabana 是一个明确的只读采集与分析工具:它把路段回放、本地/设备 msgq、ZMQ 桥接、USB Panda、Linux SocketCAN 五种输入汇入同一套 CAN 事件与消息状态模型,并在这之上做 DBC 编辑与 CSV 导出。MessageId 严格解析为「总线:十六进制地址」,不能只用地址当唯一键。要特别记住一个保存陷阱:saveFile() 没有检查 DBCFile::save() 的布尔返回值就把撤销栈标记为 clean 并显示「File saved」,因此磁盘写入失败时 UI 状态不能当作保存成功证据。此外,界面能解码不等于允许发送帧——DBC 文件不等于固件安全策略。

    五种输入源汇入同一事件层

    main() 解析 CLI 后按 --msgq、--zmq、--panda、Linux --socketcan、路段回放的顺序选择一个输入源;路段加载被延后到窗口出现后执行,避免网络文件列表阻塞首屏。各源最终进入 AbstractStream 的 CAN 事件和消息状态模型。下表是各输入组件的关键行为与限制。

    输入组件 关键函数 源码行为与限制
    路段回放 ReplayStream::loadRoute()、mergeSegments() 用 Replay 加载 can、视频索引与 carParams;回放线程解析段内 CAN,主线程插入排序索引。鉴权、网络、文件缺失有不同错误文案。
    本地 / 设备消息 DeviceStream::start()、streamThread() 本地从 can msgq 订阅;指定 ZMQ 地址时先 fork/exec 桥进程并用 can 过滤,失败经 self-pipe 报错,析构时终止桥进程。
    Panda PandaStream::connect()、streamThread() 连接后设置 NO_OUTPUT 安全模式,配置三个总线速率及适用设备的 CAN-FD 数据速率;循环接收 CAN、发 heartbeat(false),断线尝试重连。
    SocketCAN SocketCanStream::connect()、streamThread() Linux RAW CAN socket 绑定指定接口、尝试启用 CAN-FD,读取帧后映射到 src=0 的 cereal CAN。当前此流只读。
    实时共用层 LiveStream::handleEvent()、updateLastMessages() 可按一分钟目录写本地 rlog;非主线程收帧,主线程合并、节流刷新并支持暂停/回看。是否落盘取决于设置,不应默认视为无数据留存。

    需要提醒两点:Panda 的连接与速率设置仍是硬件操作,不能当作纯软件只读模拟;SocketCAN 的 src=0 映射也不适合直接表达多总线车辆拓扑。

    MessageId 是「总线:地址」,不能用地址当唯一键

    AbstractStream::newEvent() 从 cereal CanData 复制时间、地址、来源和字节;mergeEvents() 按 (source, address) 建立每消息索引,并维护总时间序列。MessageId 严格解析「总线:十六进制地址」,不能只用地址当唯一键。updateLastMessages() 把后台新数据合并到可供 UI 消费的最后消息状态,seek 则按时间重建消息快照。

    这里还有一个容易被当成结论的提示:CanData::compute() 的颜色与翻转频率只是观察和提示信号,不构成 DBC 正确性证明。它能帮你发现可疑的字节变化,但不能替代逐车型的 DBC 校验。

    边界 源码事实 正确理解
    消息键 MessageId 严格解析「总线:地址」 地址可跨总线重复,单用地址会串帧
    字节频率 CanData::compute() 给颜色与翻转频率 是观察提示,不是 DBC 正确性证明
    SocketCAN 来源 读取帧后映射到 src=0 不适合直接表达多总线车辆拓扑
    实时落盘 可按一分钟目录写本地 rlog 是否落盘取决于设置,不应默认无留存

    DBC 编辑:UI 状态不是保存成功证据

    DBCFile::parse() 解析 BO_ 消息、SG_ 信号、VAL_ 枚举和 CM_ 注释,保留首个识别语句之前的头部;遇到重复地址或重复信号会报错,异常附带行号。DBCManager::open() 把文件关联到一个或多个来源总线,同一个 DBC 可共享给多个总线;没有专属文件时 findDBCFile() 回退全来源 DBC。因此源总线与文件关联影响解码结果,不能只按车型名称自动推定。

    编辑路径同样要注意状态与磁盘的分离:DBCManager::addSignal() 等编辑接口发出变化通知;updateMasks() 在「抑制已定义信号」开启时按 DBC 掩码清理高亮位计数;UndoStack::push() 立即执行命令并维护撤销/重做,只有 saveFiles() 才尝试写文件。最关键的失败模式是 saveFile() 不检查 DBCFile::save() 的布尔返回值就把撤销栈标记 clean 并显示「File saved」——磁盘写入失败时,界面提示不能作为保存成功的证据。

    导出与安全边界:只读采集不是控制许可

    utils::exportToCSV() 导出时间、地址、总线与十六进制原始数据;exportSignalsToCSV() 按当前 DBC 对选中消息解码信号值。导出的是观察数据和当前解释版本,时间戳被格式化为秒的小数三位;用于控制验证时应保留原始日志、DBC 版本与更高精度时间源。

    面向自制硬件与插件化,源文档给出三条要求:第一,把 Cabana 当成只读采集与分析插件,接入自制硬件时分别记录物理总线、接口速率、时间戳来源、丢帧与 CAN-FD 能力,保留原始帧以供回放;第二,DBC 编辑器产物必须经过版本管理、逐车型测试和 opendbc/panda 独立安全策略审查,「界面能解码」不等于允许发送帧;第三,直播桥与本地 rlog 涉及车内数据外传/留存,应有明确的用户授权、加密、存储期限和网络访问边界,开发工具不应共享车辆控制进程的写权限。

    常见问题

    Cabana 能直接当成车辆控制工具吗?

    不能。源文档把它定位为协议分析工具,明确「不是车型安全许可或控制执行器」。Panda 输入路径虽设置 NO_OUTPUT 安全模式,SocketCAN 流也只读,但连接与速率设置仍是硬件操作;「界面能解码」不等于允许发送帧。

    为什么 MessageId 不能只用地址?

    因为 MessageId 严格解析「总线:十六进制地址」,mergeEvents() 按 (source, address) 建立每消息索引。同一个地址可能出现在不同总线上,只用地址当唯一键会导致串帧,也无法正确表达多总线拓扑。

    为什么点了「File saved」仍可能没保存成功?

    因为 saveFile() 没有检查 DBCFile::save() 的布尔返回值,就把撤销栈标记为 clean 并显示「File saved」。源文档明确指出磁盘写入失败时,UI 状态不能当作保存成功证据,需要另行核对磁盘文件内容。

    字节变化热图能否证明 DBC 解析正确?

    不能。CanData::compute() 的颜色和翻转频率是观察与提示信号,源文档明确它不构成 DBC 正确性证明。发现可疑字节后仍需按车型核对 DBC 版本与解码结果。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CABANA_CAN_ANALYSIS_DEEP_DIVE.md(取用了五种输入源、MessageId 严格解析、DBC 编辑与保存失败模式、CSV 导出与只读安全边界)。

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

    更新记录

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

  • Fiat Ducato X250 车身 CAN 档案:50 kbit/s 上的 24 条信号

    结论:Fiat Ducato X250 的一个反直觉特征是OBD 口后面不是发动机 CAN,而是一张 50 kbit/s 的车身 CAN:引脚 6/14 承载 B-CAN,500 kbit/s 上什么都没有;发动机 ECU 走引脚 7 的 K 线(ISO 14230-4 KWP2000)。好消息是仪表需要的多数发动机量(转速、冷却液温度、车速、里程、续航)都被广播到这张车身网上,所以一个只监听、不发送的 CAN 记录器就能读到。源文档记录 18 个 ID、约 90 帧/秒,并逐条说明每个信号是怎么在实车上核对出来的。下述结论仅限源文档记录的那一台 2009 X250。

    车辆与适用范围

    源文档是一位车主的业余项目,属于单台车、单人实验。作者明确声明「只做监听、绝不发送」,并说明是配合一款支持 MQTT 的 OBD-CAN 记录适配器完成的;文档还提到另一台车(同平台另一辆 van)提供了油量数据。作者列出该平台同款车型(Citroën Jumper / Peugeot Boxer 2006–2014),但只有 Ducato X250 被测试过。

    项 内容
    车型 Fiat Ducato X250,2.3 MultiJet 柴油(车身改装为 Elnagh Prince 55L 房车,7.15 m)
    年款 / 市场版本 2009(第一代 X250,模拟仪表 + 橙色 LCD);意大利(EU)市场
    ECU / 改装状态 原厂线束未改;OBD 口插一款 OBD-CAN 记录适配器(只监听模式);发动机 ECU 走 K 线
    采集跨度 5 段真实抓包(怠速、门与灯、杂项动作、冷启动与轰油、约 20 分钟 7 km 行驶),约 90 帧/秒
    适用范围 仅限这一台 Ducato X250;同平台 Jumper/Boxer 未测试,车身电路(例如车门与柜锁共用一条回路)因改装而异

    总线与寻址

    源文档把物理层写在最前面:OBD 引脚 6/14 是车身 CAN(B-CAN),50 kbit/s、11 位 ID;引脚 7 是发动机 ECU 的 K 线。作者特别提醒:把记录器设成 500 kbit/s 时「什么都看不到」,因为这张网上没有 500 kbit/s 的流量。

    项 内容
    物理层 双绞线 CAN,B-CAN 高/低;OBD 引脚 6/14
    链路层 / 比特率 50 kbit/s(源文档明示;500 kbit/s 无流量)
    寻址方式 11 位 ID,文档记录 18 个 ID
    CAN FD 否;按经典 CAN 处理
    发动机 ECU 走 OBD 引脚 7 的 K 线(ISO 14230-4 KWP2000)
    模式 只监听(Silent / listen-only),记录器不在总线上发送

    已解码信号

    源文档对每个信号都写了「怎么验证」的一列,并明确保留未完成核对的条目。下表抽取代表性信号;油量与瞬时油耗两条按源文档原样保留其未完成核对的标注。

    信号 位置(ID / 字节 / 位) 解码 证据
    制动踏板 0x180,b0 位 7 位 踩踏板
    示宽灯 / 近光 / 远光 0x180,b1 位 5 / 3 / 4 各自为 1 位 灯光开关、拨杆
    左 / 右转向灯 0x180,b2 = 0x40 / 0x20 随闪光跳变 拨杆
    发动机是否运转 0x281 用「转速 > 300」判定(不用 b1 位 7) 3 次钥匙测试(仅通电、启动、运转后停机)
    冷却液温度 0x281,b3 b3 − 40 → °C 表针居中时 81 °C
    转速 0x281,b5 与 b6 (b6×256 + b5) / 8 → rpm 怠速约 830,轰油 1800 / 3000
    车速 0x286,b2 与 b3 (b2×256 + b3) / 16 → km/h 4 段稳态行驶与 GPS 差在 1% 内
    车速(副本) 0x2A0,b0 与 b1 (b0×256 + b1) / 16 → km/h 同 0x286
    驻车制动 0x380,b0 位 5 位 拉手刹
    任一车门开 0x380,b1 任一门开时为 0x0C,全关为 0x00 驾驶室门、房车门、储物柜共一条回路
    倒挡 0x380,b2 位 2 位 挂倒挡进出 3 次
    启动电池电压 0x380,b3 b3 × 0.16 → V 与启动电池上的分流计对比 20 分钟行驶
    低油量告警 0x380,b4 位 1 0x02 表示进入储备 与仪表储备灯同亮时 b5 = 11、续航 110 km
    油量 0x380,b5 b5 → 升 另一台满油 90 L 罐读 91;本文档尚未在本车下次加油时交叉核对
    驾驶员安全带 0x39A,b2 位 0 1 = 未系(副本见 0x3C3 b4 位 1) 系/解 3 次,跟随仪表告警灯
    里程 0x603,b1 低半字节 + b2 + b3 20 位 → km 61744 与仪表一致,行驶 7 km 后 +7
    续航 0x603,b4 位 2-0 + b5 11 位 → km 272 与仪表一致
    瞬时油耗 0x603,b0 + b1 高半字节,BCD BCD → L/100km(示例 11 6x = 11.6) 源文档标注「待行驶中验证」
    行程平均油耗 / 平均车速 / 时间 / 距离 0x643,b0-b7 油耗 BCD、车速 km/h、时间 BCD、距离 20 位×0.1 km 与仪表行程电脑一致
    仪表时钟 0x683,b0 / b1,BCD 时 / 分 BCD 与本车仪表钟一致(本车约慢 3 分钟)

    读取方法与注意事项

    第一是速率设置:把记录器设成 50K、静默(Silent)模式,并在协议上选 slcan 以便抓包;源文档提醒设成 500K 会完全看不到流量。第二是总线上没有的东西:增压压力、发动机负荷、进气温度与故障码都在 K 线上,CAN-only 的记录器看不到;源文档把这条写进「不在本总线」一节。

    第三是时间边界的陷阱。源文档给出三条:车钥匙拔出时整条总线静默,什么也读不到;熄火瞬间的最后一帧会「说谎」(油量 0、驻车制动释放、发动机仍报运转),不要基于该边沿做自动化;判断发动机是否运转要用「转速 > 300」,不要用 0x281 的 b1 位 7——它在仅通电、发动机未启动时就是 1,熄火最后一帧和行驶后 ECU 继续发送约 20 秒时也会误报。

    第四是数据回读的取舍:里程、续航与油量没有过期机制,停车时会保留最后值,但在重启或 MQTT 重载后会变成未知值,直到下次通电;需要的话要在自己一侧加保留(retain)。此外作者提到,同一 ID 上的多个按位条目在实践中不一定都能可靠发布,所以灯、刹车、转向被合成一个 24 位原始值再在上层拆分。

    证据等级与边界

    可视为实车证据的是绝大多数条目——源文档逐条写了验证方式(踩踏板、切灯、GPS 对比、与分流计/仪表比对)。属于明确未完成的是油量(本文档尚未在本车加油时交叉核对,数字来自另一台车)与瞬时油耗(标注为待行驶中验证)。

    不能外推的地方有两处。第一,这台是改装房车,车门、房车门与储物柜共用一条回路,所以 0x380 只能给「某个门开着」,不能分辨具体是哪扇门——同平台不同车身(van、底盘车、房车)的门路会不同。第二,源文档只测试了这一台 Ducato X250;同平台的 Jumper/Boxer 未测试,年款差异也可能改变 ID 与位定义。

    关于「安全访问」类问题:源文档未提供任何绕过方法,且不建议尝试;它是纯监听项目,明确「不要在总线上发送报文」。本文只整理公开文档登记的只读信号。

    常见问题

    Ducato X250 的 OBD 口能读到发动机数据吗?

    能读到一部分。源文档说明 OBD 引脚 6/14 是 50 kbit/s 的车身 CAN,引脚 7 是 K 线的发动机 ECU;转速、冷却液温度、车速、里程、续航这些被广播到车身网上的量,CAN-only 记录器可以只监听读到,而增压压力、负荷、进气温度与故障码在 K 线上读不到。

    为什么设成 500K 看不到任何报文?

    因为这张 OBD 口的车身 CAN 跑在 50 kbit/s,源文档说 500 kbit/s 上什么都没有。应设为 50K。

    怎么判断发动机是否在运转?

    用「转速 > 300」。源文档明确不要用 0x281 的 b1 位 7:它在仅通电、发动机未启动时就是 1,熄火最后一帧和行驶后 ECU 继续发送约 20 秒时也会误报。

    为什么熄火后油量显示为 0?

    因为源文档记录熄火瞬间的最后一帧会给出异常值(油量 0、驻车制动释放、发动机仍报运转)。作者建议不要基于这个边沿触发自动化,并让实时传感器用超时机制转为「不可用」而不是冻结。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/danderik88-fiat-ducato-x250/README.md(主来源:车辆、总线、取数路径与坑点)。
    • 项目 01 —— public-can-dbc-datasets/additional/danderik88-fiat-ducato-x250/docs/can-id-reference.md(逐 ID 的信号表与验证方式)。
    • 项目 01 —— public-can-dbc-datasets/additional/danderik88-fiat-ducato-x250/captures/README.md(5 段真实抓包的用途说明)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • Holley EFI 的 29 位 CAN ID:通道索引与参数解码档案

    结论:Holley EFI 系统(HP / Dominator V4+、Terminator X、Sniper V2+ 等)用的是29 位扩展 CAN 标识符,而且把「命令位 + 目标 + 通道索引 + 源 ID + 源序列号」编进 ID 本身。文档记录的结构是:位 28 为命令位(等于 1)、位 27:25 为目标(等于 111 表示广播)、位 24:14 承载通道索引 / 参数标识、位 13:11 为源 ID(等于 010 表示 ECU)、位 10:0 为 ECU 序列号低 11 位。读取侧的关键一步是用 ECU 序列号的低 11 位做过滤(例如序列号 19838 对应 0x57E,即 1406)。默认波特率是 1000000(1 Mbit/s)。边界:源文档是工具说明,参数含义来自官方 DBC,本文不为其数值或安全阈值背书。

    本文整理自该解析工具的 CAN 部分文档。它记录的是「怎么把 Holley 的 ID 与 DBC 对起来」,而不是某一台车的出厂网络定义。

    车辆与适用范围

    这里的「车型」应理解为被记录的 Holley EFI 平台,而非某一款整车:文档适用的产品线是 HP / Dominator(V4+)、Terminator X 与 Sniper(V2+),解码依据是官方 DBC 文件。文档没有绑定到某台具体车辆,也没有给出硬件型号随年款变化的说明。

    项 内容
    车型 / 平台 Holley EFI 系统:HP / Dominator(V4+)、Terminator X、Sniper(V2+)
    年款 / 市场版本 源文档未给出(按产品代次表述)
    ECU / 改装状态 面向后装电喷 ECU;示例 ECU 序列号 19838(CAN ID 中使用 0x57E)
    采集跨度 源文档未给出;示例为一段实时会话与一份 candump 日志
    适用范围 工具与 ID 结构说明;不含具体车辆的整网定义

    总线与寻址

    文档明确使用 29 位扩展标识符,并给出默认波特率 1000000(1 Mbit/s)。没有提到 CAN FD,也没有给出 11 位寻址的用法。ID 的位域划分本身就是寻址方式的一部分,见下表。

    项 内容
    物理层 CAN,默认波特率 1000000(1 Mbit/s,文档默认值)
    链路层 29 位扩展标识符
    寻址 ID 内置:命令位(位 28)、目标(位 27:25,111 为广播)、通道索引(位 24:14)、源 ID(位 13:11,010 为 ECU)、源序列号低 11 位(位 10:0)
    CAN FD 源文档未提及
    多 ECU 按 ECU 序列号低 11 位过滤,用于多 ECU 同总线场景

    已解码信号

    下表分两部分:ID 位域(用来定位是哪个 ECU、哪个通道)与参数(由官方 DBC 解码的量)。源文档是工具说明,未对单个参数标注置信度;参数含义来自官方 DBC,安全阈值则是「可配置的代码取值」,不是厂商规格。

    条目 位置 解码 / 含义 证据
    命令位 ID 位 28 等于 1 表示命令 源文档 ID 结构说明
    目标 ID ID 位 27:25 111 表示广播 源文档 ID 结构说明
    通道索引(参数标识) ID 位 24:14 标识具体参数通道 源文档 ID 结构说明
    源 ID ID 位 13:11 010 表示 ECU 源文档 ID 结构说明
    源序列号(低 11 位) ID 位 10:0 取 ECU 序列号低 11 位;例:19838 用 0x57E(1406) 源文档 ID 结构说明
    RPM 示例 0x9E005000,ECU 1406,通道 8 DBC 解码;示例值 6500 rpm 源文档示例输出
    FUEL_AFR_AVERAGE DBC 消息 由 DBC 解码 源文档配置示例
    OIL_PRESSURE DBC 消息 由 DBC 解码;文档阈值 警告 30 psi、危险 20 psi 源文档阈值表
    COOLANT_TEMP DBC 消息 由 DBC 解码;阈值 警告 210 华氏度、危险 230 华氏度 源文档阈值表
    机油温度 DBC 消息 阈值 警告 250 华氏度、危险 280 华氏度 源文档阈值表
    燃油压力 DBC 消息 阈值 警告 40 psi、危险 30 psi 源文档阈值表
    爆震退点火 DBC 消息 阈值 警告 2 度、危险 4 度 源文档阈值表
    增压 DBC 消息 阈值 警告 20 psi、危险 25 psi 源文档阈值表
    转速阈值 RPM 参数 警告 7000、危险 8000 源文档阈值表
    DL 日志参数 二进制日志列 Param_002 = RPM、Param_066 = TPS,共 516 个参数 源文档参数表

    读取方法与注意事项

    先按序列号过滤。解析器会自动提取 ECU 序列号的低 11 位用于匹配,因此多 ECU 同总线时,必须先填对序列号,否则会同时看到别的 ECU 的消息。

    DBC 决定字段含义。参数名与单位来自官方 DBC(文档列出的文件包括 HP Dominator & Terminator X DBC.dbc、Sniper V2 DBC.dbc、HARDWIRE HOLLEY DBC FILE.dbc)。DBC 放错或不匹配,字段会解不出或解错。文档建议把 DBC 放在同目录或用 --dbc 指定完整路径。

    实时与离线两条通道。实时侧可直接监听 can0 等接口(无需先跑 candump),也可把 candump 文本通过管道或文件喂给解析器;输出支持人类可读、JSON、CSV 与实时仪表盘四种格式,仪表盘可按 --minmax 跟踪最小 / 最大值并同时 --record 录制。

    二进制日志的格式差异。同一仓库还处理 .DL / .DLZ 日志:.DLZ 先做字节交换、RLE 解压、再字节交换;.DL 分 V3(魔数 0x0095365F)、V4 / V5(魔数 0x0085F41F)与 V6。文档说明 V5 为稀疏存储、无法直接解析,需要先在官方软件里打开转换成 V6;V6 可端到端解析。

    证据等级与边界

    源文档是工具说明,没有为单个参数标注置信度。表中「解码 / 含义」一列,凡属参数含义者都来自官方 DBC;凡属数值(如 RPM 6500)都是示例输出;凡属阈值(如 OIL_PRESSURE 20/30 psi)都是「代码里可配置的取值」,文档原文即写明可配置,因此不能当作厂商规格或安全红线。

    范围边界同样清楚:这套 ID 结构与 DBC 面向的是 Holley 的后装 EFI 平台,不是某一款整车的出厂网络;文档未绑定具体车辆、年款或整车网络,也未提供实车验证结论。任何字段值、阈值或「安全」判断,都应回到你自己的 ECU、DBC 与实车数据上复核,不能跨平台外推。

    常见问题

    Holley EFI 的 CAN ID 为什么用 29 位?

    因为它要在 ID 里同时编码「谁发的、发给谁、哪个通道、什么命令」。文档给出的划分是:位 28 命令、位 27:25 目标(111 广播)、位 24:14 通道索引、位 13:11 源 ID(010 为 ECU)、位 10:0 源序列号低 11 位。

    总线上有多个 ECU,怎么只看其中一个?

    按 ECU 序列号过滤。解析器自动取序列号的低 11 位做匹配,例如序列号 19838 对应 ID 中的 0x57E(1406);填错序列号会解到别的 ECU 的消息。

    默认波特率是多少?

    文档默认值是 1000000,即 1 Mbit/s。可在命令行用 --bitrate 覆盖。

    .DLZ 和 .DL 是什么关系?

    .DLZ 是压缩日志,文档给出的解压步骤是字节交换、RLE 解压、再字节交换。解出的 .DL 分 V3 / V4 / V5 / V6;其中 V5 为稀疏存储、不能直接解析,需在官方软件里转成 V6 才能端到端解析。

    文档里的阈值能当安全结论用吗?

    不能。文档原文写明这些阈值是「代码里可配置」的取值,不是厂商规格或安全红线。它们只用于实时仪表盘的红 / 黄 / 绿显示,实际判断需回到你自己的标定与实车数据。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/hackinglz-holley-efi/can/README.md(本项目车型档案主来源,取用了 Holley CAN ID 结构与参数阈值表)。
    • 项目 01 —— public-can-dbc-datasets/additional/hackinglz-holley-efi/README.md(取用了 DL / DLZ 日志格式与参数列说明)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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

  • Chrysler 固件身份:0x22 F132 双偏移与转向能力前缀启发式

    结论:Chrysler 平台的身份链里,0x22 F132 这一个 DID 走的是两条响应路由:仪表/SRS/ABS/雷达/EPS 用 rx_offset=-0x280,ABS/混动/发动机/变速箱用默认 +0x8,发动机与变速箱还额外查 supplier 软件号。匹配分精确与通用 fuzzy 两级,fuzzy 明确排除 EPS/前视雷达并要求两个 ECU 地址上的独有版本指向同一车型,且 Chrysler 没有品牌自定义 fuzzy。转向能力不是规范化零件号解析,而是对 EPS 固件版本前 4 字节的前缀启发式:非 Ram 平台 >= b"6841" 抬高最低转向速度,Ram 1500 落在 b"68" < prefix <= b"6831" 时才可设为 0。识别、BSM、雷达解析与可发送控制是四种不同能力,必须分别声明与验证。

    十个平台是入口索引,不是适用性声明

    CAR 与 ChryslerCarSpecs 声明 10 个平台:Pacifica 4、Jeep 3、Ram 2、Durango 1,并给出 PT/雷达 DBC、质量、轴距与基础最低转向速度。Cherokee 使用 CUSW PT DBC,Ram 使用独立 DBC。FW_VERSIONS 对这 10 个平台逐一列出 ECU 地址与版本原始字节:发动机版本可含尾部空格,Ram HD 列了 engine 0x7e0 却没有 transmission 条目,该文件也没有旧式 FINGERPRINTS。

    这些声明不是物理线束、EPS 固件或执行权限的证明,也不代表已完成所有年款的报文与安全审计。版本字节必须按字节保存,不应剥除尾部空格或把车型名称当成版本匹配规则。

    FW_QUERY_CONFIG:一个 DID,两条响应路由

    查询配置在 bus 0 上组织了三组请求,最容易踩坑的是「同一个 ABS 类型出现在两组」——因此不能只按 ECU 类型推导响应地址,必须按请求组分别对应偏移。

    请求组 目标 ECU 偏移 / 结果
    0x22 F132 仪表 / SRS / ABS / 雷达 / EPS rx_offset=-0x280;如 EPS 0x75a 预期响应 0x4da
    0x22 F132 ABS / 混动 / 发动机 / 变速箱 默认 +0x8;如发动机 0x7e0 默认响应 0x7e8
    0x22 supplier 发动机 / 变速箱 额外查询 supplier ECU 软件号
    extra_ecus 混动 ABS 替代地址 0x7e4 加入查询集合,get_fw_versions() 标为 logging,build_fw_dict() 排除

    CHRYSLER_VERSION_REQUEST 为 0x22 F132,supplier 软件号也走 0x22,每组正响应以 0x62 加相同 DID 为前缀。这里的版本正则 [A-Z0-9_]{10} ? 只用于离线固件表的全匹配测试,不是运行时未知版本归一化器。混动 ABS 的替代地址应视为额外采集,不应成为自动选型证据。

    精确与模糊匹配:独有 ECU 数与冲突拒绝

    match_fw_to_car_exact() 对每个候选的已知 ECU/版本逐项检查:未见 essential ECU 或已见不匹配都可淘汰,非 essential 缺席可略过。要记住它返回的是集合,不保证唯一,没有实测固件时不能据此宣称车型已识别。

    通用 fuzzy(match_fw_to_car_fuzzy())排除 EPS、前视雷达等共享 ECU,要求两个不同 ECU 地址上的独有版本都指向同一车型。Chrysler 未配置品牌自定义 fuzzy,因此未知 EPS 版本不能单独作为 fuzzy 身份;两个 ECU 冲突时会拒绝候选,缺帧或共享件则可能导致无结果。

    能力 判定依据 边界
    精确匹配 候选的已知 ECU/版本逐项核对,essential 缺失或不匹配可淘汰 返回集合,不保证唯一
    通用 fuzzy 两个不同 ECU 地址上的独有版本指向同一车型 排除 EPS/前视雷达;Chrysler 无品牌自定义 fuzzy
    BSM 依据 bus 0 地址探测,而非固件型号 与车型识别是两件事
    雷达解析 统一 radarUnavailable=True 默认禁用,需另行启用

    转向能力:前缀启发式,不是零件号解析

    CarInterface._get_params() 用固件版本前 4 字节做前缀判断。非 Ram 平台:新平台或任意 EPS 版本前缀按字节序 >= b"6841" 时,置高最低转向速度标志;Ram 1500 的 EPS 前缀落在 b"68" < prefix <= b"6831" 时可设 minSteerSpeed=0;最后的高阈值标志把最低速度设为 17.5 m/s。

    这些判断是代码里的能力启发式,不是规范化零件号解析;CarParams 需要保留固件来源和未知状态。CarController.update() 用 minSteerSpeed 决定 LKAS 使能,平台分支决定关断迟滞并包含重新使能等待,扭矩在未激活或使能位关闭时归零。参数阈值会进入实时执行链,不能仅凭插件清单声明「支持低速转向」。

    四种能力必须分开声明

    Ram HD 与 CUSW 被标记 dashcamOnly;CUSW 选独立 safety model,Ram DT/HD 使用安全参数位;雷达统一 radarUnavailable=True;BSM 依据 bus 0 地址而非固件型号。源文档把这一点总结为一句要求:车型识别、BSM、雷达解析和可发送控制是四种不同能力,必须分别声明、验证和降级。对缺失或相互矛盾的证据应返回未知,高阈值与零速转向不应从车型说明或单一未验证响应推断。

    常见问题

    为什么 ABS 的响应地址不能只按 ECU 类型推导?

    因为同一个 DID 0x22 F132 在 bus 0 上有三组请求,同一个 ABS 类型会同时出现在 rx_offset=-0x280 组和默认 +0x8 组。源文档明确不能按 ECU 类型单独推导响应地址,必须按请求组对应偏移。

    EPS 版本能不能单独决定车型身份?

    不能。通用 fuzzy 明确排除 EPS、前视雷达等共享 ECU,要求两个不同 ECU 地址上的独有版本都指向同一车型,且 Chrysler 未配置品牌自定义 fuzzy。因此未知 EPS 版本不能单独作 fuzzy 身份。

    Ram 1500 的零速转向是怎么判定的?

    由 EPS 固件版本前 4 字节的前缀启发式判定:当 b"68" < prefix <= b"6831" 时可设 minSteerSpeed=0。这是代码中的能力启发式,不是规范化零件号解析,CarParams 需保留固件来源和未知状态。

    车型被识别出来,是否就能发送转向控制?

    不能等同。源文档强调车型识别、BSM、雷达解析和可发送控制是四种不同能力。Ram HD/CUSW 标记 dashcamOnly,雷达统一 radarUnavailable=True,而 minSteerSpeed 等阈值会进入实时执行链,不能仅凭插件清单声明支持低速转向。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CHRYSLER_FIRMWARE_QUERY_STEERING_CAPABILITY_IDENTITY_DEEP_DIVE.md(取用了 10 个平台固件库、0x22 F132 双偏移查询、精确与 fuzzy 匹配边界、转向能力前缀启发式及四类能力分层)。

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

    更新记录

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

  • Chrysler 四套构帧:0x292 与 0xa6 为什么不能互换

    结论:Chrysler 的构帧不是一套模板,而是四套并存的布局:Pacifica/常规 Jeep、Ram DT、Ram HD 与 Cherokee CUSW,三帧消息的地址、字节长度和所在总线都不同,不能互相套用。几个最容易踩的点是:Ram 的按钮帧走 bus 2 而其他走 bus 0;Ram HD 与 CUSW 的 TX/RX 只在 ALLOW_DEBUG 构建中注册且参数层标 dashcamOnly;Pacifica、Ram DT、Ram HD 的转向扭矩上限分别是 261、261、361,CUSW 为 250。字段名相同并不代表可共用原始载荷。以下为固定快照 c8fb906 的静态分析,未向车辆发送 CAN。

    四套发帧布局

    主机侧三类输出分别是 LKAS 转向命令、DAS_6 图标/车系码/警示,以及巡航按钮。CANPacker.pack() 会在未显式提供时按地址递增 COUNTER,并调用 DBC 对应的 CHECKSUM 函数;chrysler_ 系列 DBC 使用 chrysler_checksum(),即最后一字节之外的 CRC-8 J1850,初值与尾异或都是 0xff。

    平台族 LKAS / DAS_6 / 按钮(地址/长度) 主机 bus panda 限制
    Pacifica / 常规 Jeep 0x292/6 B、0x2a6/8 B、0x23b/3 B 三种都在 bus 0 扭矩最大值 261,速率上/下限每次 3。
    Ram DT 0xa6/8 B、0xfa/8 B、0xb1/3 B LKAS/HUD bus 0,按钮 bus 2 主机扭矩上限 261,固件白名单 350,实际受主机更紧约束。
    Ram HD 0x276/8 B、0x275/8 B、0x23a/3 B LKAS/HUD bus 0,按钮 bus 2 主机/固件扭矩上限均 361,速率 14;TX/RX 仅 ALLOW_DEBUG 注册。
    Cherokee CUSW 0x1f6/4 B、0x5dc/4 B、0x2fa/3 B 三种都在 bus 0 独立 safety model,扭矩 250,速率 4;参数层标 dashcamOnly。

    控制周期与按钮时序

    CarController.update() 以 DT_CTRL = 0.01 s 的帧计数运行。按钮只在距上次发送严格超过 0.05 s 时生成,优先取消、其次恢复;计数用 CS.button_counter + 1,再由 create_cruise_buttons() 截成 4 位。这里有一个平台差异:CUSW 的 update_cusw() 没有像常规分支那样刷新 button_counter,若生成按钮帧会反复使用初始化值加一,是否触发原车计数拒收仍需台架确认。

    DAS_6 的字段由 create_lkas_hud() 生成:它把激活态、车系码和告警转成图标与车道线字段;Ram 额外带原车自动远光状态,而 CUSW 的告警字段固定为零。也就是说,同一个「车道保持已激活」在四套布局里落在不同字段上,跨平台复用图标语义需要分别核对。

    HUD 每 25 帧尝试一次,且只有 CS.lkas_car_model != -1 才发送。hud_count 小于 4 的启动告警只覆盖最初四个实际发送的 HUD 帧,源码注释里的「first 3 seconds」不能当作精确时长。转向周期由 CarControllerParams 设为普通/Ram 50 Hz、CUSW 100 Hz;控制位则依 minSteerSpeed、平台迟滞和最近下降沿约 200 个控制帧的等待决定。由于 lkas_active 在本次控制位更新前读取上一状态,控制位首次置位的周期不会产生非零扭矩。

    时序项 取值 备注
    控制步长 DT_CTRL = 0.01 s 按钮与 HUD 都按帧计数节流。
    按钮最小间隔 严格大于 0.05 s 优先取消,其次恢复。
    HUD 周期 每 25 帧 仅当 lkas_car_model != -1。
    转向速率 普通/Ram 50 Hz、CUSW 100 Hz 由 CarControllerParams 决定。
    控制位迟滞 约 200 个控制帧 自最近下降沿起等待。

    控制字段与原始载荷不能共用

    create_lkas_command() 对 Ram 的控制字段编码为 2,其他为 1。这对应固件里的不同检查:常规固件在 Pacifica 上检查 bit 4、在 Ram 上检查字段值 2,而 CUSW 独立检查 bit 12。字段名相同并不代表可以共用原始载荷,这也是四套布局必须分别验证的原因之一。

    panda 是最后一道独立门

    主机发出的三类帧仍要经过 panda 安全钩子。常规模式仅允许表中的地址、总线与长度;转向再做扭矩与请求位检查;按钮只接受纯取消,或在 controls_allowed 下的纯恢复,CUSW 的取消/恢复位解析则不同。这套白名单与按钮限制应被视为独立于应用插件的最后一道门。生成式 Ram DBC 的地址映射(DAS_6 与按钮来自 Stellantis 共用 DBC 的地址替换)也应纳入构建一致性检查。

    硬件与插件验收边界

    把 DBC、总线、帧长、安全模式与固件构建作为同一车型插件的版本化契约;Ram 的按钮 bus 2 与普通平台的 bus 0 不可互换。台架应分别验证编码后的计数、CRC、控制位与 panda TX 的接受/拒绝矩阵,尤其覆盖 Pacifica、Ram DT、Ram HD、CUSW 四套布局——软件里有构帧函数,并不意味 HD/CUSW 的 release 固件允许发送。

    实车验证前应先只读记录原车的 DAS_6、按钮计数与测得 EPS 扭矩以及 LKAS 故障时序,确认线束与转发路径。本文没有 DBC 动态编码回放、目标板或车辆响应证据,不构成上路控制许可。

    常见问题

    四套 Chrysler 布局能共用同一套构帧代码吗?

    不能。Pacifica/常规 Jeep、Ram DT、Ram HD、Cherokee CUSW 的地址、长度和总线都不同:例如 Ram 的按钮帧走 bus 2,其他走 bus 0;Ram HD 与 CUSW 的 TX/RX 还只在 ALLOW_DEBUG 构建中注册。

    为什么控制字段取值在 Ram 和其他平台上不同?

    create_lkas_command() 对 Ram 的控制字段编码为 2、其他为 1,对应固件的不同检查:常规固件在 Pacifica 检查 bit 4、在 Ram 检查字段值 2,CUSW 则独立检查 bit 12。字段名相同不等于原始载荷可共用。

    按钮计数在 CUSW 上有什么特殊之处?

    CUSW 的 update_cusw() 没有像常规分支那样刷新 button_counter,若生成按钮帧会反复使用初始化值加一;这是否触发原车计数拒收仍需台架确认。

    软件里有构帧函数就说明 HD/CUSW 可发送吗?

    不能这样推断。Ram HD 与 CUSW 的参数层标 dashcamOnly,HD 的 TX/RX 只在 ALLOW_DEBUG 构建中注册;台架应分别验证四套布局的 panda 接受/拒绝矩阵,构帧函数存在不代表 release 固件允许发送。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/CHRYSLER_CAN_FRAME_CONTROL_CONTRACT_DEEP_DIVE.md(取用了四平台发帧矩阵、控制周期与按钮/HUD 时序、控制字段编码差异与 panda 安全门边界)。

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

    更新记录

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

  • 雪铁龙 C2 的 CAN-Confort:125 kbit/s 上解码 16 个 PSA 标识符

    结论:在一辆雪铁龙 C2 1.1(TU1JP,BSI AEE2004,EMF 为 Magneti Marelli)上,舒适总线 CAN-Confort 是 125 kbit/s、11 位标识符,而且它不经过 OBD 口——只能在收音机后方的 Quadlock 连接器(pin 10 CAN-H、pin 13 CAN-L)上接入。文档在该总线上识别出 16 个 PSA AEE2004 标识符,并解码转速、车速、水温、车门、灯光、方向盘按钮、续航与保养提醒等信号。边界有三条:部分信号只有单点标定或来自公开参考结构、未在本车验证;外部温度与总里程存疑;结论只覆盖这一辆 C2,不能外推到其他 C2 或 PSA 车型。

    本文整理自该项目的 CAN 解码文档。文档为每个信号标注了证据等级,本文原样保留其分级。

    车辆与适用范围

    数据来自一位车主的这辆 C2;原车 RD4 收音机换为一台后装安卓车机,解码用于方向盘控制、实时仪表与多功能屏(EMF)操控。

    项 内容
    车型 雪铁龙 C2 1.1(发动机 TU1JP,BSI AEE2004,EMF 为 Magneti Marelli)
    年款 / 市场版本 源文档未给出具体年款(PSA C2 平台文档标注为 2003–2009,BSI 第二代)
    ECU / 改装状态 原车 RD4 收音机已拆,替换为后装安卓车机;由一款 SLCAN 协议的开源 CAN 适配器接入
    采集跨度 实车现场测试 2026-04-26;配合诊断工具截图的标定会话 2026-05-03
    适用范围 仅这一辆 C2;多条标定仍需在车上复核

    总线与寻址

    目标是舒适总线 CAN-Confort,速率 125 kbit/s、11 位标识符。接入点在收音机后方的 Quadlock,pin 10 为 CAN-H、pin 13 为 CAN-L;文档明确指出 OBD 口不暴露这条总线,因此不能从诊断座直读。适配器未加 120 Ω 终端电阻(文档说明总线本身已有终端)。

    项 内容
    物理层 CAN-Confort,125 kbit/s(区别于 500 kbit/s 的 CAN-IS)
    链路层 11 位标识符
    接入点 收音机 Quadlock:pin 10 CAN-H、pin 13 CAN-L;OBD 口不暴露该总线
    CAN FD 源文档未提及,按 125 kbit/s 的 AEE2004 语境应视为经典 CAN
    现场总线负载 约 185 帧/秒、38 个不同标识符(现场测试记录)

    已解码信号

    下表从文档信号表中抽取代表性条目,证据等级沿用原文:✅ 在本车验证(现场测试或用户确认)、🎯 只用一个测量点标定(该点正确、斜率未验证)、📄 取自公开的 AEE2004 参考结构(未在本车验证)、⚠ 来源互相矛盾。字节从 0 起编号,BE 为大端。

    信号 位置(ID / 字节) 解码 证据
    发动机转速 rpm 0x0B6 字节 0-1(BE) ÷ 8,四舍五入到 0.1 转/分 ✅ 怠速 704–768 转/分(诊断工具读数)
    车速 speed 0x0B6 字节 2-3(BE) ÷ 100,四舍五入到 0.1 km/h ✅ 静止时确认;行驶中待与 GPS 比对
    冷却液温度 tCoolant 0x0F6 字节 1 字节 − 53 摄氏度;0xFF 表示未就绪(null) 🎯 92 摄氏度对应 0x91(测量中水温在 86–92 波动)
    总里程 odo 0x0F6 字节 2-4(BE) ÷ 10 公里;0xFFFFFF 表示未就绪 ⚠ 取自参考结构;现场测试未找到对应图案
    外部温度 tExt 0x0F6 字节 6 字节 − 102 摄氏度;0xFF 表示未就绪;另加用户偏移 ⚠ 三种假设互相矛盾
    倒挡 reverseGear 0x0F6 位 7.7 位为 1 表示挂倒挡 📄 参考结构
    手刹 handbrake 0x128 位 0.5 位为 1 表示手刹拉起 ✅
    转向灯(左 / 右) 0x128 位 4.1 / 4.2 对应位为 1 表示点亮(双闪为两位同时) ✅
    远光 / 近光 / 示宽灯 0x128 位 4.5 / 4.6 / 4.7 对应位为 1 表示点亮 ✅
    机油温度 tOil 0x161 字节 2 字节 − 64 摄氏度;0x00 与 0xFF 表示未就绪 🎯 71 摄氏度对应 0x86(算出 70)
    燃油百分比 fuelPct 0x161 字节 3 直接取百分比 ✅ 用户确认(2026-05-09)
    续航 rangeKm 0x221 字节 3-4(BE) 公里;0xFFFF 表示未计算 ✅ 440 km(帧内 0x01B8)
    瞬时油耗 fuelInst 0x221 字节 1-2(BE) ÷ 10 升/百公里;0xFFFF 表示未计算(停车时) 📄 与诊断工具「停车时显示未计算」一致
    方向盘按钮 0x21F 字节 0(位图) 位 1 源、位 2 音量减、位 3 音量加(本车与通用文档相反)、位 6 上一曲、位 7 下一曲 ✅ 本车完全验证
    车门(驾驶员 / 乘客 / 尾门) 0x220 位 0.7 / 0.6 / 0.3 对应位为 1 表示打开 ✅
    平均油耗 tripAvgCons 0x261 字节 4 ÷ 10 升/百公里 ✅ 7.6 升/百公里对应 0x4C

    读取方法与注意事项

    哨兵值一律视为「未就绪」。文档规定:温度为 0xFF、里程为 0xFFFFFF、0xFFFF 类字段在充电或刚唤醒时代表「尚未可用」,解码器应输出 null,绝不当作真实数值。

    节奏由 0x0B6 决定。0x0B6 以 20–50 Hz 发送,界面按 10 Hz 采样,音频逐帧跟随。

    按钮要防抖,并注意本车接线方向。0x21F 的字节 1 是滚轮的累计计数,应用需自行计算两帧之间的带符号差值。信号处理采用上升沿加 200 毫秒防抖。这台 C2 的 VOL+ 与 VOL− 与通用文档相反,位图不能照抄。

    发送会落在真车上。文档列出的发送帧(如多功能屏按键、校时帧)会直接发到车辆实际总线,有风险。关于用 CAN 设置 EMF 时钟:文档记录了多次尝试与「未提供可行方法,也不建议尝试」的结论——校时要么走多功能屏自身的菜单,要么依赖原车收音机的私有序列,不存在文档化的 CAN 校时方案。

    证据等级与边界

    文档的分级是硬边界:✅ 本车验证,🎯 只有单点标定(点正确、斜率未验证),📄 取自公开参考结构未在本车验证,⚠ 来源互相矛盾。也就是说,🎯 与 📄 两类条目尚未在这辆 C2 上成立,不能当作已确认字段使用。

    文档还专门列出「待复核」清单:外部温度存在三种互斥假设,都只在 23 摄氏度一点上对齐,斜率未验证;总里程来自参考结构但现场测试未找到对应图案,且参考诊断点自身也不自洽;机油 / 水温斜率只有一个点;行驶中的车速尚待与 GPS 比对;保养 0x3A7 与行程距离 0x261 的格式也未确认。

    另有至今未找到的信号:电池电压、进气温度、BSI 时间(0x276 帧缺失)、EMF 时钟(不能通过 CAN 设置)。这些应记为「未确认」,而非「不存在」。所有结论限于这一辆 C2,不能外推到其他 C2 或 PSA 车型——本车已经出现了与通用文档相反的方向盘按钮接线,正说明逐车核对是必需的。

    常见问题

    雪铁龙 C2 的 CAN-Confort,能从 OBD 口直接读吗?

    不能。文档明确指出 OBD 口不暴露这条总线,接入点是在收音机后方的 Quadlock 连接器(pin 10 CAN-H、pin 13 CAN-L),速率 125 kbit/s、11 位标识符。

    为什么车速在静止时已确认,行驶中还要再核对?

    因为静止时只能确认零值与量程端点,无法验证斜率。文档把「行驶中把 speed 与 GPS 比对」列为待办,说明该字段在动起来之后仍需独立确认。

    为什么这台车的 VOL+ 和 VOL− 与通用 PSA 文档相反?

    文档记录这台 C2 的接线本身就把 VOL+ 与 VOL− 对调了。方向盘按钮 0x21F 虽已在本车完全验证,但位图不能照抄通用文档,必须按本车实测为准。

    外部温度和总里程为什么被标成存疑?

    外部温度有三种互斥假设,且都只在 23 摄氏度这一个点上对齐,斜率未验证;总里程取自公开参考结构,但现场测试未在总线上找到与仪表读数对应的图案,参考诊断点自身也不自洽。两者都需要更多实车数据才能确定。

    能用 CAN 设置多功能屏(EMF)的时钟吗?

    文档记录的全部尝试都失败了,并明确给出「源文档未提供可行方法,也不建议尝试」的结论。校时只能走多功能屏自身菜单,或依赖原车收音机的私有序列;不存在文档化的 CAN 校时方案。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/signaux_decodes.md(本项目车型档案主来源,取用了信号表与证据分级)。
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/psa_can_confort.md(取用了 CAN-Confort 的通用标识符与载荷说明)。
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/c2_field_test_results.md(取用了现场测试的验证项与失败尝试记录)。

    说明:本文整理自第三方开源项目的公开文档,仅代表该文档所记录的单个车辆样本,不代表同型号全系车型。CAN 与诊断操作存在风险,任何实车操作前请自行复核并遵守当地法规。

    更新记录

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