标签: DBC

  • KTM TBI mapswitch:31 条 BO_ 里只有 4 条真实帧

    结论:这份 KTM TBI mapswitch 的 DBC 有 31 条 BO_ 报文与 36 条 SG_ 信号,但其中只有 0x6DA、0x6DB、0x4C0、0x4C1 四条是真正的 CAN 广播或地图按键 / 命令帧;其余 27 条把 UDS 的 DID、IOID、RID 当作伪 CAN ID,用来描述响应载荷。配套的车型矩阵则把 TBI(2024 年起)与两代 TPI 的 27 项能力分成三档。

    31 条报文里只有 4 条是真实总线帧

    这是使用这份 DBC 前必须先看清的一点。归档说明按文件自身的头部描述作了分类:只有四条条目属于 CAN 广播或地图按键 / 命令流量,其余 27 条用的是 UDS 诊断标识符(DID、IOID、RID)充当伪 CAN ID,目的是描述请求之后的响应数据结构。

    条目性质 数量 标识示例 能不能当总线报文监听
    真实 CAN 广播或按键 / 命令帧 4 0x6DA、0x6DB、0x4C0、0x4C1 能,可直接按 ID 过滤与解析
    UDS DID / IOID / RID 伪 ID 27 文件头声明为响应载荷描述 不能,需先发起请求再解析响应

    UDS 传输层本身使用请求 0x7E0、响应 0x7E8。也就是说,那 27 条「报文」在总线上并不会以该 ID 出现;把它们当普通帧去过滤,结果必然是永远收不到。正确用法是先按 0x7E0 发诊断请求,再按 DBC 里对应伪 ID 的定义去解 0x7E8 回来的载荷。

    另外两个兼容性问题也要提前处理:部分伪报文声明的载荷长度超过 8 字节(其中包含 96 字节的条目),而源文件带有 // 注释——严格的 DBC 解析器可能需要预处理才能读入。

    三代车型的 27 项能力分档

    项目面向 KTM、Husqvarna 与 GasGas 三个品牌的摩托车,车型矩阵把能力分成「骑行模式」与「诊断」两大组,横跨 TBI(2024 年起)、TPI(2020–2023)、TPI(2018–2019)三代。这份 DBC 明确以 KTM TBI 的 ECU 命名,来源并未为每个定义确立具体车型、排量或固件版本。

    能力 TBI(2024+) TPI(2020–2023) TPI(2018–2019)
    按键切换地图 支持 不支持 不支持
    按键清除 ECU 故障 支持 支持 支持
    RaceChrono 遥测 支持 支持 支持
    显示当前地图 支持 支持 不支持
    按模式统计摩托小时(油门、转速) 支持 不支持 不支持
    动力阀开度百分比 支持 不支持 不支持
    大气压力(MAP,大气) 支持 支持 不支持
    TPS 电压与开启角度 支持 不支持 不支持
    TPS 开启百分比 不支持 支持 支持
    运输锁状态 / 翻车传感器 / 机油泵回路 支持 不支持 不支持

    把这张表读成决策依据,可以归纳出三条:第一,按键切换地图是 TBI 独有能力,两代 TPI 都做不到;第二,TBI 独有项共 8 项(按键切地图、按模式小时计、动力阀开度、TPS 电压、TPS 角度、运输锁、翻车传感器、机油泵回路),这些是 TBI 平台新增诊断能力的全部;第三,TPI 2018–2019 相比 2020–2023 只少了显示当前地图与大气压力两项。

    还有一处反向差异值得注意:TPS 的表示方式在三代之间不兼容——TBI 给电压与角度,两代 TPI 只给百分比。做跨代统一解析时,TPS 必须按代分别处理。

    三档之外,按键清除故障、冷机指示、过热指示、保养间隔指示、故障灯指示、RaceChrono 遥测、总摩托小时、发动机转速、水温、进气温度、进气压力、点火提前角、电池电压、读取当前与存储故障、清除故障这些项目在三代上全部支持,可以视为这套装置的能力基线。

    把分档结果与项目命名放在一起看,能得出一条实用的选型判断:这套装置以 KTM TBI 命名,而矩阵显示按键切换地图仅在 TBI(2024 年起)这一档可用,两代 TPI 均不支持。因此面对 TPI 车型时,可用能力退化到上述基线加上显示当前地图(仅 2020–2023)、大气压力(仅 2020–2023)与 TPS 百分比,不能照搬 TBI 的功能清单。

    常见问题

    31 条 BO_ 里有多少是真实的总线报文?

    只有 4 条,即 0x6DA、0x6DB、0x4C0 与 0x4C1,属于 CAN 广播或地图按键 / 命令流量。其余 27 条按文件头的声明,是用 UDS 的 DID、IOID、RID 值充当伪 CAN ID 来描述响应载荷,总线上并不会以这些 ID 出现。

    UDS 请求与响应用的是什么 CAN ID?

    请求为 0x7E0、响应为 0x7E8。那 27 条伪 ID 报文描述的正是响应里的数据结构,因此正确流程是先向 0x7E0 发起诊断请求,再按 DBC 中对应伪 ID 的定义解析 0x7E8 返回的内容,而不是直接按伪 ID 去过滤总线。

    TPI 2018–2019 相比 2020–2023 少了什么?

    在 27 项能力矩阵里只少两项:显示当前地图与大气压力(MAP,大气)。其余项目中,按键清除故障、冷机与过热指示、保养间隔、故障灯、RaceChrono 遥测、总小时、转速、水温、进气温度、进气压力、点火提前角、电池电压、TPS 百分比、故障读取与清除等在这两代上均为支持。

    为什么这份 DBC 在严格的解析器里可能报错?

    有两个原因。一是部分伪报文声明的载荷长度超过 8 字节,其中包含 96 字节的条目,超出经典 CAN 单帧能力;二是源文件带有 // 注释。因此严格的 DBC 解析器可能需要先做预处理(剥离注释、处理超长载荷)才能读入。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/psamoilov-ktm-tbi-mapswitch/SOURCE.md(31 条 BO_ 与 36 条 SG_、4 条真实帧与 27 条伪 ID、UDS 0x7E0/0x7E8、超长载荷与注释问题、权利状态)
    • 项目 01 —— public-can-dbc-datasets/additional/psamoilov-ktm-tbi-mapswitch/models.md(TBI 2024+ 与两代 TPI 的 27 项能力矩阵)

    免责声明

    本文内容整理自公开开源项目,属社区逆向工程产物,不代表 KTM、Husqvarna 或 GasGas 的官方数据。来源未为每个定义确立具体车型、排量或固件版本,信号与车型适配未经独立抓包验证。检查的目录树中未找到仓库许可证或逐文件的再分发授权,相关材料应作为私有离线研究副本,在权利确认前不得再分发或集成。

    更新记录

    • 2026-10-14 初稿

  • ECT2026 的 DBC:16 报文 61 信号同时喂固件与 Flutter

    结论:ECT2026 的 network.dbc 不是挂在某个 App 旁边的说明文件,而是同时被 C 固件工具链与 Dart 解码目录消费的唯一真源:16 条报文、61 个信号。真正的使用门槛不在信号规模,而在两处容易被忽略的事实——归档方在该修订版里没有找到仓库许可证,且这个 DBC 描述的是一台生态马拉松原型车的自建网络,不是任何量产车型的原厂定义。

    一份 DBC,两条生成链

    这套舱内 telemetry 面板值得借鉴的地方在于:它没有让「协议定义」和「解析代码」各自演化。上游文件被固定为 dbc/network.dbc,一致性靠代码生成保证,而不是靠人工同步。

    下游产物 生成方式 消费方 漂移风险
    C 语言解码源码 python -m cantools generate_c_source --database-name network dbc/network.dbc ECT2026 车载固件 低,由 cantools 统一语义
    Dart 解码目录 tools/generate_can_dart.py 生成并提交入库 Flutter App 解码路径 低,产物入版本库可 diff
    信号与状态映射 lib/models/telemetry/can_bindings.dart 手工维护 App 状态树与 MQTT 指标名 中,改名需同步 broker 侧订阅
    Spool 与 CSV 镜像 由信号解码结果透传 本地会话 CSV 与 Grafana 面板 中,字段名变更会污染历史数据

    这张表里真正需要人盯的只有第三、四行。前两行是「改 DBC 后跑一遍生成器」,机器保证一致;后两行是「改命名之后谁还依赖旧名」,只能靠约定。实际踩坑通常出现在 MQTT 指标名上——telemetry/eco_archers/events 这个导出主题一旦被外部订阅方写死,重命名就不再是本地重构,而是跨端协议变更。

    DBC 的 61 个信号按功能分成踏板与辅助控制、电池包与辅助电源、车辆运动与时间、GPS、电机状态五类。这个切面恰好说明车辆本身的形态:它不是一条完整的动力总成总线,而是「驾驶员输入 + 能耗 + 位置 + 电机」的最小闭环,服务于节能赛事的能耗管理,而不是故障诊断或刷写。

    数据流背后的三层持久性

    这份文档的工程价值更在于它把「车里可能断电」「蜂窝链路可能断」「服务端可能挂」三件事分别做了兜底,且每一个参数都写死在文档里,可以直接对照自己的项目做取舍。

    层级 取值 触发时机 失效后的表现
    可读 CSV 镜像 缓冲写、每秒 flush;默认保留 7 天 MQTT 服务启动时按保留天数裁剪 突发断电最多丢约 1 秒的行,不清空整份数据
    MQTT 本地 spool 磁盘最多保留 50,000 个待发批次 broker 不可达时堆积,恢复后重放 触及上限丢弃最旧批次,驾驶舱显示 SPOOL 并标记 DROP-OLDEST
    服务端 CSV 落盘 csv_streamer.py,1 秒 fsync、不设保留策略 随写入持续进行 服务端异常时该侧数据缺失,但车端 spool 仍完整

    三层的关键在于「各自独立」。车端 SQLite/WAL 的 edge_spool.db 面向链路可靠性,CSV 镜像面向现场可读性,服务端 1 秒 fsync 面向服务端掉电。把它们合成一层,任何一次裁剪或掉电都会同时击穿三个目标。

    还有一个容易被忽略的行为:镜像的 7 天裁剪发生在 MQTT 服务启动时。如果设备长期离线不启动服务,策略并不会执行,磁盘占用会一直往上涨。做车机部署时,容量估算要按「上线时才裁剪」而不是「按自然时间滚动」来做。

    怎么把这套后端跑起来

    文档给了两条等价路径。一条是单容器:仓库里的 ops/backend/Dockerfile 把 TimescaleDB、Mosquitto、Telegraf 与 Grafana 打包进同一个镜像,运行在 tini 之下作为 PID 1,并把 Telegraf 固定在 1.31.x、Grafana 固定在 13.1.1,同时对数据库、broker 与 CSV 服务分别做健康检查;对外暴露 1883、5432、3000、8080 四个端口。另一条是 ops/local-stack/docker-compose.yml 的多容器栈。

    两条路径的选择依据其实很朴素:单容器适合快速验证,代价是任一组件重启会牵动整容器;多容器适合长期运行,代价是编排与网络配置要自己维护。若只需要观测而不需要长期留存,还可以只跑 ops/backend/Dockerfile.csv-streamer 给出的最小镜像。

    建议的顺序是先用样本数据跑通整条链路——docker build 之后直接 docker run,再用 db/scripts/verify_setup.sql 核对 hypertable 与索引,确认 telemetry_raw、sessions、laps 三张表的行数符合预期——最后才替换成自己的 DBC 与会话数据。跳过这一步,后面所有的曲线都可能是空跑。

    什么时候不该直接搬用它

    有三个边界必须提前划清。第一是权利状态:归档说明在检视的修订版中没有找到仓库许可证,因此该 DBC 与派生文件被作为私有离线研究副本保留,任何再分发或对外数据服务之前都需要先确认权利。第二是适用范围:它是项目专用车辆网络定义,把 ID 与信号布局套到量产车上属于无意义迁移。第三是证据强度:这一归档没有独立核验部署情况、信号缩放系数与物理量测量,61 个信号的单位与 factor 不应被当作可直接用于能耗结算的标定值。

    常见问题

    ECT2026 的 DBC 能用于量产车的 CAN 解析吗?

    不能。它描述的是生态马拉松项目车自建的网络,覆盖踏板与辅助控制、电池包与辅助电源、车辆运动与时间、GPS、电机状态五类,共 16 条报文 61 个信号,属于项目专用定义。任何 ID 与信号布局都不能跨车型迁移。

    本地 CSV 镜像的 7 天保留是怎么执行的?

    由 MQTT 服务启动时按配置的保留天数裁剪,默认值是 7 天。这意味着裁剪时机与服务的启动强绑定:设备长时间离线且不启动服务时,镜像文件不会被清理,磁盘占用会持续增长,部署前需要按最坏情况估算容量。

    MQTT 断连一段时间后数据会全部重放吗?

    不一定。本地 spool 最多在磁盘保留 50,000 个待发批次,broker 恢复后自动重放;一旦触及这个上限,最旧的批次会被丢弃,同时驾驶舱显示 SPOOL 并标记 DROP-OLDEST,此时需要人工判断数据缺口的位置。

    这份 DBC 现在适合公开再分发吗?

    不适合。归档说明指出在检视的修订版中没有找到仓库许可证,虽然 Git blob 与 SHA-256 都已固定可用于比对,但权利状态未明。在确认权利之前,它只适合作为私有离线研究副本,不应集成进对外产品或公开发布的数据集。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/lugilugi-ect2026/SOURCE.md(仓库与固定修订版、DBC blob 与 SHA-256、16 报文 61 信号、五类信号切面、未找到许可证与未独立核验的声明)
    • 项目 01 —— public-can-dbc-datasets/additional/lugilugi-ect2026/README.md(App 栈与 MQTT 导出主题、spool 与 50,000 批上限、7 天保留与每秒 flush、单容器后端与四个端口、generate_can_dart.py 与 can_bindings.dart、cantools generate_c_source 调用方式)

    免责声明

    本文引用的报文数量、信号数量与工具链调用方式均来自公开开源仓库的说明文件,属社区项目产物,未经独立实车核验,也不代表任何车辆制造商的官方定义。文中参数(如 50,000 批上限、7 天保留、每秒 flush、Telegraf 1.31.x 与 Grafana 13.1.1)为上游文档声明值,不同版本部署可能存在差异。涉及行车安全与能耗结算的判断请以实车测量为准。

    更新记录

    • 2026-10-14 初稿

  • LiveWire S2 Del Mar:60 报文副总线与 9 个 UDS 模块

    结论:2024 LiveWire S2 Del Mar 的公开 CAN 资料给出了两件东西,用途完全不同:副总线的广播 .dbc(60 条报文、111 个信号)和一份跨 9 个诊断模块的 UDS DID 目录。转速、车速这类实时量直接从广播拿;电池单体电压、ABS 轮速、绝缘电阻这类不广播的数据,必须走 BCM 网关用 0x22 读——把它们混为一谈是初学者最常见的错。

    总线事实:先记这四条

    这份社区资料把前置条件写得非常干净,接入之前四条必须对齐。

    维度 取值 错配后果
    速率与类型 500 kbit/s,classical CAN,11 位标准 ID 按 CAN FD 或扩展帧配置时完全解不出帧
    字节序 big-endian,Motorola 起始位记作 @0 多字节信号反向拼接,数值量级明显偏大
    保护机制 约 36 个 ID 带 E2E 保护(AUTOSAR Profile-1 风格) 自定义解析时未跳过校验字节,信号整体错位
    拓扑 副总线上只有 BCM、IM、TCU、DLC;电机、BMS、ABS 在主总线 在副总线上找电机转速,永远找不到

    第三条 E2E 保护值得单独说:D7 是 6 位 alive counter,D8 是覆盖 D1 到 D7 的 CRC-8 / SAE-J1850(多项式 0x1D,初值与异或输出均为 0xFF)。它的价值不在于安全,而在于充当解码预言机——位对齐一旦算错,CRC 立即失败,不需要等到物理量不合理才发现问题。这是逆向过程中极少数可以机器判定对错的抓手。

    九个模块各管什么

    副总线的广播成员是 BCM(网关)、IM(仪表)、TCU、DLC 四个,其余全部在主总线上,通过 BCM 网关用 ISO-TP 上的 0x22 ReadDataByIdentifier 读取。下面这张表是挑选 UDS 模块时的直接依据。

    模块 请求与响应 ID 角色 能拿到的关键数据
    BCM 0x7E2 → 0x7EA 车身控制器,副总线网关 纵向加速度 ADC 快照、内部 mV 电源轨、时间同步、骑行模式配置表、防盗与钥匙块
    VSC 0x7E4 → 0x7EC 车辆监控控制器,监管 ABS 与 IMU 实时电机转速与驱动状态、扭矩记录、油门位置、电池包端电压、当前骑行模式序号及逐模式标定三元组
    RESS 0x7E6 → 0x7EE 高压电池管理,信息价值最高的模块 逐单体电压阵列、逐单体温度阵列、包电流双传感 A/B、SoC/SoE/SoH、累计安时
    EHCU 0x7E7 → 0x7EF Bosch ABS 液压单元 双路逐轮轮速、前制动压力、制动激活标志、12 V 辅助电源轨、ABS 事件计数器
    OBC / HV 0x7D3 → 0x7DB 车载充电机,交流充电时才活跃 充电器与枪状态、充电电流与功率、充电机散热片温度、母线电压
    TCU 0x7D4 → 0x7DC 远程通信,含 eSIM 与 GPS,隐私敏感 GPS 位置、信号强度、归属网络、固件版本

    表里没有列的还有 LHCM(0x7E3,识别信息与硬件件号,同时携带 VIN)、RHCM(0x7E5,制动激活标志与内部参考电源轨)、以及一个 ID-only ECU(0x7F0 → 0x7F8,只有供应商件号、没有任何实时数据块,属于硬上限)。

    需要注意的是,9 个已映射响应者是下限而不是总数。资料明确提到存在一个未映射的响应方(响应 0x6E6 / 请求 0x6DE)被被动观察到,另有目标地址 0x7F2;并且 IMU 本身没有 UDS 地址,它由 VSC 监管。这意味着你在总线上看到的地址比这张表多,是预期行为。

    读懂它的置信度标注

    这份资料最值得模仿的不是结论,而是它把不确定性强塞进数据结构里:每条信号的行内注释都带四类信息——置信度、标定依据、已撤回的假设与尚未解决的疑问。[CONFIRMED](两种以上方式交叉验证)、[STRONG](一次干净抓包且物理一致)、[TENTATIVE](数据不足)。已撤回的假设会原样保留而不是删除,避免后来者重复尝试同一条死路。

    这套标注的实际用法:写解析代码时,只对 [CONFIRMED] 与 [STRONG] 做断言和告警,[TENTATIVE] 一律只记录不做判断。把三级标注 flatten 成一个 schema,等于把作者的证据强度信息彻底丢弃。

    它的取证方法也相当严格:单人单次动作隔离抓包 + 差分分析;一次相关只构成假设,必须有第二次「专门设计来推翻它」的抓包失败才算成立;未被动作覆盖的字节标记为未解,而不是当作常量写死。这套流程解释了为什么 111 个信号里真正能用作线上判据的比例并不高——大量位置至今没有足够证据。

    三条使用边界

    第一,0x27 SecurityAccess 门禁:BCM、VSC、TCU 上有 16 个 DID 被上锁,种子为 128 位随机数,其内容是按相邻关系推测的,不是读出来的。任何把推测值当成实测值的下游都会出错。第二,隐私:车主 PII 在这份公开副本中被抽掉,VIN、模块序列号、GPS 坐标与 SIM 标识都变成占位符,但结构完整,复现时必须自己填自己的值。第三,版本状态:整体标注为 v0.1 进行中,TENTATIVE 条目可能错误或不完整;并且它只描述如何读取与理解总线,不含任何执行动作的方法。

    常见问题

    电机转速和电池单体电压能不能直接从副总线广播里读?

    不能。副总线上的广播成员只有 BCM、IM、TCU、DLC 四个,电机/逆变器、电池、ABS、充电机、远程通信都在主总线上,需要通过 BCM 网关用 ISO-TP 上的 0x22 ReadDataByIdentifier 主动读取。能直接广播读到的只有广播成员的那些信号。

    E2E 的 CRC 除了校验还有什么用?

    它是逆向时的位对齐预言机。约 36 个 ID 采用 AUTOSAR Profile-1 风格保护,D7 为 6 位 alive counter,D8 为覆盖 D1 到 D7 的 CRC-8 / SAE-J1850,多项式 0x1D、初值与异或输出 0xFF。只要起始位或长度算错,CRC 立即失败,可以在物理量失真之前发现错位。

    已映射的 9 个模块是不是这辆车的全部 ECU?

    不是,作者明确写这是一个下限。被动观察到的还有一个未映射响应方(响应 0x6E6、请求 0x6DE)以及目标地址 0x7F2;IMU 没有自己的 UDS 地址,由 VSC 监管。也就是说实际地址数会多于这 9 个。

    为什么有些 DID 的内容看起来是「猜」出来的?

    因为 BCM、VSC、TCU 上有 16 个 DID 被 0x27 SecurityAccess 上锁,种子是 128 位随机数,作者无法读取其值,只能按相邻关系推测其含义。使用这类字段时必须标注为推测值,不能参与任何判定逻辑。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/inklit-livewire-s2-delmar/README.md(500 kbit/s、11 位 ID、Motorola @0、约 36 个 ID 的 E2E 与 CRC-8 参数、60 报文 111 信号、9 个 UDS 模块、CONFIRMED/STRONG/TENTATIVE 标注体系、取证方法论、CC BY 4.0 授权)
    • 项目 01 —— public-can-dbc-datasets/additional/inklit-livewire-s2-delmar/MODULES.md(九个诊断模块的请求与响应 ID、角色与关键数据;9 为下限的说明、0x27 上锁 16 个 DID、IMU 无 UDS 地址、PII 抽除说明)

    免责声明

    本文所述总线参数、模块地址与信号数量均来自社区公开整理的说明文件,属第三方逆向工程产物,未独立实车验证,也不代表 LiveWire 或任何制造商的官方数据。不同年份、市场与固件版本的 ECU 可能存在差异。涉及 0x27 安全访问的字段为作者推测值。任何改动请以实际测量与官方资料为准,操作在用车存在风险。

    更新记录

    • 2026-10-14 初稿

  • PSA 架构逆向:94 份报文 YAML 与 DBMUXEv 格式

    结论:PSA-RE 不是 DBC 集合,而是一套自研的 DBMUXEv 描述格式:归档快照含 94 份总线报文 YAML、110 份车型映射文件,覆盖 AEE2001(VAN)、AEE2004(第一代 FullCAN)与 AEE2010 三代架构。它不用 DBC 的原因很具体——需要同时描述多个世代,而每个世代又包含多条网络,DBC 这种单网络格式装不下。

    为什么放弃 DBC:单网络格式的边界

    DBMUXE 格式的规范文档写明了动机:现有格式(包括 Vector 的 DBCan)无法满足需求,因为要描述多代设计,而每代设计又包含多条网络。格式名本身也是线索——DBMUX 取自 PSA 内部用于描述多路复用网络的软件名,后缀 ev 在 PSA 语境里常表示某个事物的演进版本。

    维度 DBC(DBCan) DBMUXEv
    组织单位 单一网络上的报文与信号 architecture、variant、network、bus、node 逐层嵌套
    多世代设计 需拆成多份彼此无关的文件 按目录分层;跨架构相同的报文只写一份,其余用符号链接
    诊断数据 不在格式范围内 同级 diag 目录下有 dids、dtcs、resets、routines 四类
    协议覆盖 主要面向 CAN 面向多种车载网络,规范仍列为待完成项的有 LIN、KWP2k、K-lines、PSA2k
    语言 单一语言 按 ISO 两字母码扩展,示例仅设置 en 与 fr
    转出工业格式 即用 规范 TODO 中:需编写生成器解析 YAML 产出 DBC、ODX

    代价也很清楚:这套格式目前没有官方工具链,想把它喂给 SavvyCAN 或 CANoe,要先自己写生成器。仓库 README 的求助清单里,「编写生成器把 YAML 转成 DBC、ODX 等工业标准格式」被列为最需要的贡献之一。

    目录结构即数据模型

    规范给出的目录树基本等同于它的概念模型:architecture 是一组设计模板的名字(如 AEE2004),variant 是其衍生版本;network 是共享节点的一组总线,bus 是节点之间的物理链路(可以是 CAN,也可以是 LIN);node 是挂在一或多条总线上的控制器;protocol 是在总线上发送数据的协议;message 是总线上的一帧;signal 是帧里的一个数据点。

    路径 存放内容 作用
    architectures.yml 架构定义 整个数据集的顶层索引
    cars/{id}.yml 车型到架构的映射 把具体车型挂到一或多个架构上
    nodes/{architecture}.{variant}.yml 节点定义 描述该架构变体下有哪些 ECU
    buses/{architecture}.{variant}/{network}.{bus}/{message}.yml 单帧报文 一帧一个文件,是快照里 94 份报文文件的所在
    diag/{architecture}.{variant}/{node}/ dids、dtcs、resets、routines 诊断侧数据,与总线报文分列

    命名上用点号 . 作分隔符,需要时嵌套。跨架构复用有一条明确规则:若某条报文在多个架构(及其版本)中完全相同,只在第一个实现它的架构的最相关版本里描述一次,其余位置创建符号链接。这条规则让 94 份报文文件能覆盖远多于 94 个「车型 × 总线」组合。

    车型命名规则:第二位数字是车身

    仓库单独写了一份车型命名说明。规则是:一个字母加一个数字构成基础车型,后面可能跟第二个数字表示车身形式。

    第二位数字 车身形式
    0 3 门
    1 5 门
    2 SW / Break(旅行版)
    3 4 门
    4 休闲车 / MPV / 大型多功能
    5 Coupe
    6 Coupe / Cabriolet(敞篷)
    7 Cabriolet(敞篷)
    8 Monospace / Minispace
    9 (小型)多功能 / 商用

    另外说明提到改款通常(但不总是)把第一个数字加 1。这条规则的价值在于把 110 份车型映射文件变成可推导的体系:看到车型代号就能预判它挂在哪个架构上,而不必逐份打开文件。

    证据边界:覆盖率与安全内容的取舍

    归档说明给出的边界必须先看。上游 README 声称理论上覆盖 1993 年雪铁龙 XM(首款使用 VAN 的车)到 2020 年代初的标致、雪铁龙与 DS,并说明 2022/2023 年起的新架构尚不清楚;但快照里的报文文件实际位于 AEE2001/CONF 与 AEE2004.full 的 HS.IS 或 LS.CONF 之下,也就是说 README 的车型覆盖表述并不能证明每个车型或信号都已收录。

    上游 107 份总线 YAML 中含有防盗或安全访问相关术语的 13 份被刻意剔除,未纳入本次归档。仓库声明 Apache-2.0 并保留 LICENCE,但 README 同时警告数据可能有误,并承认部分材料来自无法追溯的泄露,因此原始数据权利并未完全确立。留存的报文仍需要与被动抓包做独立的适配性与缩放核对。

    常见问题

    PSA-RE 里为什么没有 DBC 文件?

    因为它用的是自研的 DBMUXEv 格式。规范文档写明动机:现有格式(包括 Vector 的 DBCan)无法描述多代设计,而每代设计又包含多条网络。该项目用 YAML 按 architectures、cars、nodes、buses、diag 分层组织,把 YAML 转成 DBC 需要另外编写生成器,这一点被列在仓库的求助清单里。

    94 份报文 YAML 覆盖了哪些架构?

    项目目标是 PSA 的 AEE2001(VAN 架构)、AEE2004(第一代 FullCAN 架构)与 AEE2010(2010 年至约 2020 年的车型)三代。但本快照的报文文件实际位于 AEE2001/CONF 与 AEE2004.full 的 HS.IS 或 LS.CONF 之下,README 中关于覆盖 1993 年至 2020 年代初的宽泛表述并不能证明每个车型或信号都已收录。

    车型文件的命名规则是什么?

    规则是一个字母加一个数字构成基础车型,后面可跟第二个数字表示车身形式:0 为 3 门、1 为 5 门、2 为旅行版、3 为 4 门、4 为休闲车或 MPV、5 为 Coupe、6 为 Coupe 或敞篷、7 为敞篷、8 为 Monospace、9 为小型多功能车。此外改款通常(但不总是)把第一个数字加 1。

    为什么收录时刻意剔除了 13 份报文文件?

    因为上游 107 份总线 YAML 中含有防盗或安全访问相关术语的 13 份被判定为不宜纳入,未进入本次归档。同时仓库 README 警告数据可能有误,并承认部分材料来自无法追溯的泄露,原始数据权利未完全确立,因此留存报文仍需与被动抓包做独立的适配性与缩放核对。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/prototux-psa-re/README.md(项目目标、AEE2001/AEE2004/AEE2010 架构范围、覆盖声明与免责警告)
    • 项目 01 —— public-can-dbc-datasets/additional/prototux-psa-re/dbmuxev/doc/README.md(DBMUXEv v0.1 规范:术语定义、目录结构、符号链接复用规则与待完成项)
    • 项目 01 —— public-can-dbc-datasets/additional/prototux-psa-re/cars/README.md(PSA 车型代号命名规则与车身形式编码)
    • 项目 01 —— public-can-dbc-datasets/additional/prototux-psa-re/SOURCE.md(94 份报文文件、110 份车型映射、13 份剔除说明与权利状态)

    免责声明

    本文内容整理自公开开源仓库,属社区逆向工程成果,不代表标致、雪铁龙或 DS 的官方数据。原仓库明确警告信息可能不正确,且部分材料来源无法追溯,权利未完全确立。留存报文未经独立抓包验证,不同车型、年款与 ECU 版本可能存在差异,应以实际测量与官方资料为准。

    更新记录

    • 2026-10-14 初稿

  • DBC 规范索引:8 段关键字与 7 份可下载文件

    结论:nberlette-canbus 这个仓库的价值不在报文数量,而在它把 DBC 规范拆成 8 个可查段落并挂出 7 份可直接下载的 DBC。真正该先核对的是版本与来源:7 份里两份(Mazda 2017、Lexus RX350)版本栏是「–」,另外五份才有版本号;同目录的 license.md 是许可证文本,不是技术素材。

    DBC 是什么:一份把广播翻译成信号的字典

    CAN 总线上,每个控制器节点把自己所有数据广播出去,由监听节点自行过滤出需要的流量。原始报文对人不可读,因此由 Vector GmbH 发展出一种半标准化格式,把传感器与模块的原始值翻译成带名称和单位的可读量——这就是 .dbc。仓库自述也说明了这类字典的现实来源:各家整车厂都有自己的私有字典(含调整因子、偏移、标签与单位),有时会泄露到网上或被内部人员出售,而大多数情况是爱好者在自己的车上花大量时间逆向出来。

    换句话说,拿到一份 DBC,第一件要做的事不是数它有多少报文,而是确认它属于哪一类来源:官方泄露、社区逆向,还是从其他格式转换而来。这决定了它的可信度等级。

    七份可下载 DBC 的版本与来源

    仓库提供七份文件,混合了自有逆向成果与来自其他项目的转载。下表按「能不能追溯版本」整理,这是判断可维护性的第一层筛选。

    车型 / 用途 文件名 版本 来源性质
    BMW E90 bmw-e90.dbc 2021.6.8 仓库自有逆向,带明确日期版本
    BMW E39 bmw-e39.dbc 2021.6.6 由 .kcd 格式转换而来,非原生 DBC
    Mazda(2017) mazda_2017.dbc — 转载自 opendbc,未标版本
    Lexus RX350 lexus_rx350.dbc — 转载自 opendbc,未标版本
    Tesla Model 3 tesla_model3.dbc 2020.40.1 转载自 onyx-m2 项目的 DBC 仓库
    OBD2(通用) obd2.dbc 0.0.1 转载自 csselectronics.com
    J1939(通用) j1939.dbc 7.6 来源未知,转载自 haskell.org

    版本栏为「–」意味着无法判断这份文件与上游当前状态的距离:opendbc 的 Mazda 与 Lexus 文件在各自仓库里是持续更新的,转载快照一旦脱离上游就会静默过期。带日期版本的两份 BMW 文件虽然量级未必更大,但至少可以判断新旧。

    另一条容易被忽略的信息是 BMW E39 那一份由 .kcd 转换而来。跨格式转换会引入字节序、因子与信号命名的二次解释,因此它的原始证据链比原生 DBC 多一层,核对时应回到 .kcd 源。

    八段规范:从文件头到枚举值

    仓库把 DBC 规范按关键字拆成八节,配 wiki 逐节说明语法、属性与示例。这八节既是写作顺序,也是阅读一份陌生 DBC 的检查顺序。

    关键字 含义 阅读时该看什么
    VERSION 版本 文件头,先确认是否与上游一致
    NS_ 新符号 声明用到的符号集合,缺失会导致部分工具解析失败
    BU_ 节点(Board Units) 定义了哪些 ECU,是判断发送方归属的基础
    BO_ 报文(Messages) ID、DLC 与发送节点,含属性定义
    SG_ 信号(Signals) 起始位、位长、字节序、有无符号、因子与偏移、单位;含复用(Multiplexers)
    BA_ 属性(Attributes) 属性定义与默认值,承载周期一类的元信息
    CM_ 注释(Comments) 全局、节点、报文、信号四个层级的说明,是逆向记录的主要载体
    VAL_ 取值(Values) 枚举值表,把数字映射成文字状态

    其中 SG_ 的复用机制值得单独留意:它解决的是同一条报文在不同场景下承载不同信号的问题。若解析器不支持复用,这类报文会被解成错误的信号组合。

    配套资源:从规范到工具链

    仓库另附两组外部链接。工具与规范类包括 CANpy 的 DBC 规范文档、opendbc 开源 DBC 项目、BMW KCAN / KBUS / IBUS 参考项目、BMW K-CAN 文档站,以及 canmatrix(用于把 DBC 转成其他格式)。参考类包括 PiSnoop 的 DBC 帮助页、Racelogic 面向 VBOXII 与 PRO v4 的 CAN 格式说明、来自 haskell.org 的 J1939 DBC,以及 CANtool 手册。

    这套组合的实用意义在于:读规范解决「字段怎么写」,canmatrix 解决「格式怎么转」,BMW 专项资料则示范了单一品牌多总线(KCAN / KBUS / IBUS)的文档化方式。拿到一份陌生 DBC 时,按八节顺序过一遍也能快速定位问题:先看 VERSION 判断新旧,再看 BU_ 确认节点是否齐全,随后在 BO_ 与 SG_ 上核对 ID、DLC 与字节序,最后读 CM_ 注释寻找作者留下的逆向依据。

    还要留意仓库自述本身把这项工作描述为进行中的状态。因此即便带版本号的文件,也应理解为某一时点的快照,而不是最终结论。

    常见问题

    这个仓库能直接当车型数据库用吗?

    不能。它只提供 7 份可下载的 DBC 文件与规范文档,覆盖 BMW E90、BMW E39、Mazda 2017、Lexus RX350、Tesla Model 3 以及通用的 OBD2 与 J1939,规模远小于整车网络定义。它的主要用途是规范速查与少量可下载样本,车型级数据仍应回到 opendbc 这类专门项目。

    同目录的 license.md 是什么,能当素材读吗?

    它是仓库的许可证文本,不是技术内容,不应作为报文或信号的资料来源。阅读该仓库时应把 readme.md 与 wiki 当作内容,把 license.md 当作使用边界——引用或再分发这 7 份 DBC 前必须先确认各自的许可条款,尤其是转载自 opendbc、csselectronics 与 haskell.org 的那几份。

    BMW E39 的 DBC 是怎么来的?

    它是从 .kcd 格式转换而来的,仓库明确标注了这一点,版本号为 2021.6.6。跨格式转换会引入字节序、因子与命名的二次解释,因此核对信号定义时应回到原始 .kcd 文件,而不是把转换结果当作一手证据。

    DBC 里的 multiplexer(信号复用)解决什么问题?

    它解决同一条报文在不同场景下承载不同信号的问题:报文里用一个复用选择器决定其余位的含义,从而在不增加 CAN ID 的前提下表达更多状态。仓库的规范文档把 Multiplexers 单列为 SG_ 信号一节的子主题。需要注意若解析器不支持复用,这类报文会被解成错误的信号组合。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/nberlette-canbus/readme.md(DBC 格式定义、8 段规范索引、7 份可下载 DBC 的车型与版本、外部资源与参考链接)

    免责声明

    本文内容整理自公开开源仓库的自述文档,所述文件、版本号与来源标注均以该仓库快照为准,未经独立验证。转载类 DBC 可能已与其上游产生差异,使用前请核对上游当前状态与各文件的许可条款。

    更新记录

    • 2026-10-14 初稿

  • Suzuki Swift ZC32S 的 CAN 地图:6 条报文与 9 个信号

    结论:Suzuki Swift Sport ZC32S 的公开 CAN 地图只有 6 条报文、9 个信号,且刹车压力仍是无物理单位的裸值、转向角只是近似量。它足够驱动一块 ESP32 + MCP2515 的车载 OLED 仪表,但不能当整车网络定义或标定依据——派生出的 DBC 明确假设 Motorola 字节序、DLC 8 与 Unknown 发送方,全部未经实车抓包复核。

    六条报文能做什么:一份为显示服务的地图

    这份地图来自一个车载显示项目,硬件是 ESP32 WROOM 加 MCP2515 CAN 控制器,输出到 SSD1306 OLED,另有 8 颗 WS2812 组成换挡灯、旋转编码器切换页面、ESP32 内置 BLE 被动接收 4 个原厂 TPMS 传感器。它的目标不是整车解析,而是把七个显示页面需要的数据取出来,因此覆盖面天然很窄:转速、四轮轮速、水温、油门、转向角、刹车压力,加上蓝牙胎压。

    CAN ID 信号 字节位置 换算 证据强度
    0x124 发动机转速 data[1]、data[2] raw 为 data[1] 高字节、data[2] 低字节合成的 16 位值;RPM = raw / 4 高,README 与固件一致
    0x1B8 四轮轮速 FR 0–1、FL 2–3、RR 4–5、RL 6–7 km/h = raw × 0.0276923 高,四角各 16 位
    0x310 冷却液温度 data[1] TempC = data[1] − 40 高,单字节偏移
    0x122 油门踏板 data[1] Pedal% = data[1] × 100.0 / 255.0 高,单字节比例
    0x119 转向角 data[2]、data[3] 居中约 32768,满舵约 ±495°(左约 37792、右约 27808) 中,作者标注为近似
    0x1AF 刹车压力 data[6]、data[7] 无换算,保留有符号裸值 低,未声明物理单位

    真正决定这份地图可用性的不是 ID 数量,而是最后一列。前四行的公式是可以直接搬进固件的;转向角只能用于「左打还是右打」这类定性显示;刹车压力连单位都没有,只能画相对变化趋势。

    TPMS 走的是蓝牙,不是 CAN

    四个原厂胎压传感器通过 BLE 广播被 ESP32 被动接收,按固定 MAC 地址区分左前、右前、左后、右后。压力换算为 ((data[3] << 8 | data[4]) / 10.0 * 0.0689476) - 1.0(单位 bar),温度为有符号字节 data[2]。扫描跑在独立的 FreeRTOS 任务里,以免阻塞 CAN 接收。这意味着胎压与 CAN 数据是两条独立链路,做数据融合时必须各自打时间戳,不能假设同源同周期。

    派生 DBC 的四条假设:用之前必须知道

    归档方从这份公开地图生成了一份派生 DBC(6 条报文、9 个信号),但它同时明确列出了自己做过的假设。这四条假设就是使用边界。

    假设项 取值 为何这样假设 校验方式
    字节序 Motorola(高字节在前) 固件表达式为高字节在前 抓包后按两种字节序分别解码比对
    帧长度 DLC 8 README 未给出实际帧长 抓包读取实际 DLC
    发送方 Unknown,消费者标记 Display 发送 ECU 身份未知 按 ID 反查总线活动与断电隔离
    单位与标定 刹车保持裸值,转向角近似且被固件截断为整数 固件显示公式未声明物理单位 需与制动压力传感器、转角台架对照

    把假设显式写出来,比把不确定项悄悄填成确定值要安全得多。派生文件本身也被声明为独立整理的研究草稿,既不是上游产物也不是原厂 DBC;车型适配、总线段归属、单位与缩放都未经抓包核对。

    100 Hz 与 10 Hz:为什么轮速帧要单独分配缓冲

    这一条是整份文档里最有工程价值的细节。轮速帧 0x1B8 的速率是 100 Hz,水温帧 0x310 是 10 Hz,两者速率相差一个数量级。MCP2515 的硬件滤波器把接收缓冲 RXB0 单独留给水温 ID,避免高频轮速帧把尚未读取的水温帧覆盖掉。

    同一条经验对任何 MCU 方案都成立:当同一总线上混装不同周期的报文时,接收缓冲与中断优先级的分配要按「最慢的那一帧」来设计,而不是按平均速率。否则表现不是报错,而是某个慢信号偶发跳变——这类问题在后期极难定位。

    另外还需注意权利状态:归档说明指出该修订版本未找到仓库许可证,因此派生文件与来源 README 被作为私有离线研究副本保留,在权利确认前不宜再分发或集成。

    常见问题

    这份 ZC32S 的 CAN 地图能直接用于整车网络解析吗?

    不能。它只有 6 条报文、9 个信号,目标是为车载显示取数,不是整车网络定义。派生 DBC 也明确声明车型适配、总线段归属、单位与缩放未经抓包核对,未找到上游许可证,只能作离线研究参考。

    为什么 0x1B8 轮速帧要单独处理接收缓冲?

    因为速率相差一个数量级:轮速帧 0x1B8 为 100 Hz,水温帧 0x310 为 10 Hz。作者用 MCP2515 的硬件滤波器把接收缓冲 RXB0 单独分配给水温 ID,使高频帧无法覆盖尚未读取的低频帧,否则故障表现是水温偶发跳变而非报错。

    转向角 0x119 的 ±495° 能直接当作标定值用吗?

    不能。归档说明指出转向角是近似值,且固件把它截断为整数处理。它只能支持定性显示(居左、居中、居右)与粗略角度趋势,要做转向角的定量分析需要在转角台架上重新标定,并确认左约 37792、右约 27808、居中约 32768 这三个锚点。

    派生 DBC 里刹车压力为什么没有单位?

    因为来源固件的显示公式没有声明物理单位,归档方据此保留了有符号裸值 raw = (data[6] << 8) | data[7]。在获得制动压力传感器的对照测量之前,这个值只能用于观察相对变化,不能换算成 bar 或 MPa,更不能作为制动强度的判断依据。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/8rea-suzuki-swift-zc32s/README.upstream.md(6 个 CAN ID 的字节位置、换算公式、帧率与 MCP2515 缓冲分配)
    • 项目 01 —— public-can-dbc-datasets/additional/8rea-suzuki-swift-zc32s/SOURCE.md(派生 DBC 的 6 报文 9 信号、Motorola 与 DLC 8 假设、权利状态)
    • 项目 01 —— public-can-dbc-datasets/additional/8rea-suzuki-swift-zc32s/README.md(硬件清单、TPMS 蓝牙换算与显示页面结构)

    免责声明

    本文所述 CAN ID、字节位置与换算公式均来自公开开源仓库的说明文件,属社区逆向工程产物,不代表车辆制造商的官方数据,未经独立实车抓包验证。不同车型年款、市场与 ECU 版本可能存在差异。涉及行车安全的改动请以实际测量与官方资料为准。

    更新记录

    • 2026-10-14 初稿

  • DBC 到固件的版本校验:T26 用 64 位 SHA-256 心跳

    结论:T26 的 DBC 工作流把版本一致性做成了一条 CAN 心跳:cantools 生成 C 代码的同时,脚本把每个 DBC 的 SHA-256 截断为前 8 字节(64 bit)写成宏,各 ECU 用专用 ID 0x055、DLC 8 周期广播并互相比对。截断到 64 bit 不是为了省事,而是为了塞进一帧经典 CAN 的 8 字节载荷——代价是碰撞概率从 2⁻²⁵⁶ 升到约 2⁻⁶⁴,对这个用途完全够用。

    DBC 字段与固件解码的一一对应

    DBC 的价值在于把十六进制报文翻译成带名字和单位的信号。T26 的流程从 Kvaser Database Editor 建库开始:先建节点(如 ECU_Principal),再建报文(Name、ID、DLC、Transmitter),最后逐条加信号。每个字段的填写错误都会直接变成固件里的读数错误。

    DBC 字段 要填什么 填错后的固件表现
    ID 与 DLC CAN 标识符与字节长度(如 0x101、8) 收不到该帧,或按错误长度解包直接越界
    Start bit 与 Length 起始位与位长度(如 0、16) 取到相邻信号的位,数值整体偏移
    Byte order Intel(小端)或 Motorola(大端) 高低字节互换,数值随量级剧烈跳变
    Value type Signed / Unsigned 负值变成极大正数,温度、转矩类信号尤其明显
    Factor 与 Offset 缩放因子与偏移(如 factor = 0.1,则 100 表示 10.0 km/h) 量程整体缩放错误,趋势对但绝对值全错
    Unit 单位(如 km/h) 不影响解码,但跨团队协作时是主要误读源

    这张表也是版本校验为何必要的直接解释:上述任何一格被改动,固件都不会报错,只会安静地输出错误数据。

    自动生成:DBC 到 C 代码与 Excel

    仓库配了一个 GitHub Actions 工作流,每当 DBC 变更被推送,就用 python3 -m cantools generate_c_source Autonomous.dbc --output autonomous_c_output 重新生成 C 代码,产物落在 generated/。同一个工作流还会导出 xls,每个 DBC 一个页面、每个 ID 一张表,方便非固件成员审阅。

    把生成环节放进 CI 的意义在于消除「本地改了 DBC、忘了重新生成」这类偏差。手工维护的解码头文件几乎必然与 DBC 漂移,而漂移本身不可见。

    版本校验怎么做

    工作流同时执行 embed_dbc_sha256.py,计算每个 .dbc 的 SHA-256,并把结果作为宏写进生成的头文件:

    #define DATA_T26_DBC_SHA256 0x3ee5339f1dc658c6ULL

    为塞进经典 CAN 单帧最大 8 字节的限制,哈希被截断为 SHA-256 的前 8 字节(64 bit)。文档给出的取舍依据是:两个不同版本碰撞的概率约 2⁻⁶⁴;要累积到约 43 亿个版本才有 50% 的碰撞概率;而加密哈希的前 64 位仍保留完整的雪崩效应,改一个字节就会改变该值。

    方案 承载报文 载荷长度 碰撞概率 适用网络
    截断 64 bit 经典 CAN 2.0,DLC 8 8 字节 约 2⁻⁶⁴,约 43 亿版本才有 50% 概率 CAN 2.0 网络
    完整 256 bit CAN FD 单帧 32 字节 2⁻²⁵⁶ 需 CAN FD(单帧至多 64 字节)

    文档给的实现示例是 STM32 HAL + CAN 2.0:每个 ECU 用专用 ID 0x055(文中示例为每 1 秒一次)发送 8 字节版本帧,其余 ECU 收到后与自身宏比对,不一致即判定为版本落后并告警或拒绝该节点。拷贝时所有 ECU 必须统一使用 Intel 小端字节序,否则比对本身会失效。

    不做校验会发生什么

    文档把风险写得很直白:运行旧版 DBC 的 ECU 会按错误的 bit order、factor、offset 或信号位置去解释报文,可能导致传感器读数错误、发动机与制动等系统误动作、以及难以诊断的安全故障——而这些症状在运行时没有任何可见错误。加上版本常量比对后,版本分歧在第一帧收到时就能被发现。

    在 Teensy 4.1 上的落地形态

    仓库给出的 MCU 示例用 FlexCAN_T4,CAN.setBaudRate(500000),接收队列 RX_SIZE_256、发送队列 TX_SIZE_16。解码时直接包含生成的头文件,例如 autonomous_dv_driving_dynamics_1.h,调用 autonomous_dv_driving_dynamics_1_unpack 读入 speed_actual、speed_target、steering_angle_actual;回包时用 _pack 打包,示例把 speed_target 改为 150 后写回同一 ID。

    这条链路把「DBC 是唯一事实源」落到了实处:固件里不应再出现手写的位运算,所有位定义都来自生成产物,而生成产物与 DBC 哈希绑定。

    常见问题

    为什么 SHA-256 要截断到 64 位?

    为了塞进一帧经典 CAN。CAN 2.0 单帧最多 8 字节,因此只取 SHA-256 的前 8 字节(64 bit)作为宏。文档给出的依据是碰撞概率约 2⁻⁶⁴、需约 43 亿个版本才有 50% 碰撞概率,且前 64 位保留完整雪崩效应,改一个字节即变化。

    DBC 版本不一致在实车上会表现出什么症状?

    不会报错,只会输出错误数据。运行旧版 DBC 的 ECU 会按错误的 bit order、factor、offset 或信号位置解包,导致传感器读数错误、执行系统误动作以及难以诊断的安全故障,运行期没有可见错误提示。因此需要版本心跳在第一帧就比对出来。

    版本心跳必须用 0x055 吗?

    不必。0x055 只是文档示例里为版本心跳专门分配的 ID,任何未被占用的标准 ID 都可以,关键是全网络约定一致、DLC 固定为 8,且所有 ECU 拷贝常量时使用相同的 Intel 小端字节序。

    没有 CAN FD 的网络还能做版本校验吗?

    能。经典 CAN 用截断到 64 bit 的方案即可,把 8 字节常量放进 DLC 8 的帧里周期广播。若网络支持 CAN FD(单帧至多 64 字节),则可以一帧发送完整的 32 字节 SHA-256,无需截断。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/fslart-t26-dbc/README.md(DBC 字段定义、cantools 自动生成、SHA-256 截断与 0x055 心跳示例、Teensy 4.1 用例)

    免责声明

    本文内容整理自公开开源仓库的自述文档,其中的宏值、ID、波特率与概率估算均为该仓库给出的示例或说明,未经独立实测验证。不同工具链、编译器与网络拓扑下的实现细节可能不同,工程落地请以实际测试为准。

    更新记录

    • 2026-10-14 初稿

  • feberkeley-sn4 数据集:99 报文、1305 信号与 11 段帧 ID 分区

    结论:feberkeley-sn4 数据集的核心是一份由 Python 定义生成的 DBC,含 99 条 BO_ 报文与 1,305 条 SG_ 信号。它的可复用之处在于一套清晰的帧 ID 分区策略:11 段地址区间按板卡/子系统划分并预留扩展空间。但有两个必须记住的边界——README 自称 SN4 库却描述为 SN5 车辆,且快照中未发现仓库许可证。

    数据集的构成:从 Python 定义到 DBC 与 C 代码

    这个库的工作方式不是手写 DBC,而是用 Python 的 cantools 对象描述报文,再由脚本生成 DBC 与 C 编解码代码。生成脚本 generate_can.sh 会自动创建虚拟环境、安装指定版本 cantools(39.4.13)、校验定义、生成 DBC、再由 DBC 生成 C 源文件,并归一化时间戳以保证 diff 稳定。

    产物 路径 作用
    DBC 数据库 gen/FEB_CAN.dbc 99 条 BO_ 报文、1,305 条 SG_ 信号
    C 头文件 gen/feb_can_db.h 编解码函数与最新值数据库
    C 实现 gen/feb_can_db.c 上述两者的实现

    external_dbc/ 目录里放供应商 DBC,其中的 inverter.dbc(Cascadia PM100 逆变器)与 elcon.dbc(Elcon/HK 充电机)会被自动合并进生成结果。这意味着 99 条报文里包含第三方设备的定义,使用时需要知道哪些信号来自自有板卡、哪些来自外部设备。

    帧 ID 分区:这套数据集最值得抄的部分

    帧 ID 按板卡划段,每段都预留了扩展余量。这种分配方式让「新增一条报文」变成一个可判定的问题——先看所属板卡区间还有没有空位,而不是全局找一个没用过的 ID。

    区间 归属 当前报文数 用途
    0x00-0x08 BMS 5 电池管理
    0x09-0x0F PCU 2 安全关键(制动、BSPD)
    0x10-0x15 DASH 1 仪表盘 I/O
    0x16-0x1D LVPDB 3 配电
    0x1E-0x2C Sensors 8 胎温、轮速、线性电位计
    0x2D-0x33 DART 2 风扇控制
    0x34-0x3F TPS 4 电源监控芯片
    0xC0-0xCF RMS 2 逆变器通信
    0xD0-0xDF Heartbeats 6 板卡健康监测
    0xE0-0xEF Debug 4 测试与调试报文
    0xFF PCU 1 原始 ADC 值

    注意地址空间并非连续填满:0x40 到 0xBF 之间是一大片未分配区域,Heartbeats 与 Debug 被放到了高位。这种「功能段上移、控制段下沉」的排布,让低地址区留给数量可能增长的子系统。

    新增一条报文要改三处

    流程是固定的:先在对应板卡的 *_messages.py 里写一个返回 cantools.db.Message 的函数,再在 generate.py 的 MESSAGE_REGISTRY 字典里用可用帧 ID 注册,最后重新运行 generate_can.sh 并用 --list 与 --dump 核验。校验阶段会拦两类错误:同一函数被注册到多个帧 ID(报 Duplicate function),以及帧 ID 超出标准 CAN 的 0x000-0x7FF 范围(报 Frame ID out of range)。

    信号定义的统一约定

    整个库统一使用小端字节序,这一点在排障提示里被单独强调:解包后数值不对,第一件事就是检查字节序与有无符号。位位置按小端排列,8 字节报文的位编号从 0 到 63,与字节序一一对应。

    信号类型 典型长度 有无符号 用途
    16 位电压/电流 16 无符号 以 mV、mA 为单位传输
    16 位温度 16 有符号 摄氏度
    单比特故障标志 1 无符号 故障位
    8 位状态枚举 8 无符号 状态机取值
    32 位计数器 32 无符号 计数与心跳

    心跳报文有一套标准模式:64 个独立的错误标志位,实现见 lvpdb_messages.py 中的 get_lvpdb_heartbeat()。把板卡健康状态压成 64 个比特放进周期性心跳,是这套库里最通用的设计模式之一。

    CI 里的 check 模式

    GitHub Actions 工作流用 ./generate_can.sh --check 验证生成文件是否最新,确保 Python 定义与提交进仓库的 C 代码一致。这条检查把「改了定义忘了重新生成」变成一次 CI 失败,而不是运行期的错位解码。本地若遇到该检查失败,重新生成并提交 gen/ 目录即可。

    使用边界:车款归属与权利状态

    数据集有两处明确的边界,引用前必须确认。

    边界项 实际情况 影响
    车辆归属 仓库名为 SN4,README 却描述为 FEB SN5 方程式电动车 确切车款与赛季未定,复用需自行确认
    许可证 快照中未发现仓库许可证 仅可作为私有离线研究副本
    第三方定义 合并了 Cascadia PM100 与 Elcon/HK 的供应商 DBC 供应商定义的权利未单独声明,需另行确认
    归档范围 仅归档生成的 DBC 与 README 两个供应商源文件未单独拷贝,但定义可能已在生成的 DBC 内

    综合来看,这份数据集适合作为「如何组织一个多板卡 CAN 库」的参考实现——分区策略、生成流水线、心跳模式、CI 校验都可直接借鉴;但作为某辆具体赛车的权威信号定义来用则证据不足。

    常见问题

    这份 DBC 有多少报文和信号?

    生成的 DBC 有 99 条 BO_ 报文与 1,305 条 SG_ 信号行。其中包含自动合并进来的第三方设备定义:external_dbc/ 目录下的 Cascadia PM100 逆变器 DBC 与 Elcon/HK 充电机 DBC 会被自动并入生成结果。

    新增一条 CAN 报文的正确步骤是什么?

    三步:先在对应板卡的 *_messages.py 里定义返回 cantools.db.Message 的函数;再在 generate.py 的 MESSAGE_REGISTRY 里用一个可用帧 ID 注册;最后重新运行 generate_can.sh,并用 –list 与 –dump 核验。校验会拦截同函数重复注册与帧 ID 超出 0x000-0x7FF 两类错误。

    怎么知道哪些帧 ID 还没被占用?

    运行 ./generate_can.sh –ids 查看帧 ID 分配图。帧 ID 按板卡分区并预留扩展空间,例如 BMS 为 0x00-0x08(已用 5 条)、Sensors 为 0x1E-0x2C(已用 8 条)、Heartbeats 为 0xD0-0xDF(已用 6 条)。

    解包出来的数值不对,先查什么?

    先查字节序与有无符号。这个库统一使用小端字节序,若定义与实际不符,解包结果就会错。其次确认 C 侧的 pack 函数名——报文名会被规范化成 C 标识符,实际函数名需在 gen/feb_can_db.h 中确认(小写、下划线)。

    这份数据集能用于我自己的赛车吗?

    作为组织方式的参考可以,作为权威信号定义则证据不足。仓库名为 SN4 但 README 描述为 FEB SN5 方程式电动车,确切车款与赛季未定;快照中未发现仓库许可证;合并的供应商定义权利也未单独声明。建议仅作私有离线研究副本。

    延伸阅读

    参考资料

    • 项目 07 —— public-can-dbc-datasets/additional/feberkeley-sn4/SOURCE.md(固定提交、99 报文 1,305 信号规模、车款归属疑问与权利状态)
    • 项目 07 —— public-can-dbc-datasets/additional/feberkeley-sn4/README.md(生成流水线、帧 ID 分区表、信号定义模式与 CI 校验)

    免责声明

    本文内容来自公开仓库的说明文件与生成产物统计,未对信号定义做逐条验证。数据集的车款归属与赛季在来源中存在不一致,且未发现仓库许可证,供应商定义的权利亦未单独声明。请仅作为私有离线研究副本使用,实际车辆应用前请以原始来源的权利确认与自有验证为准。

    更新记录

    • 2026-10-14 初稿

  • IFS08 uDV 节点:6 报文 DBC 与预编译 libmicroros 子模块

    结论:IFS08 的 uDV 节点是一套跑在 STM32H7 上的 micro-ROS 固件,随仓库发布的 IFS08_FSG26_datalogger.dbc(标注为 IFS08_FSG26_DL_v1.0)只有 6 条报文、45 条信号,用途单一——把行驶动力学、自动驾驶系统状态与安全遥测发给数采。它是一份部分节点地图,不是整车总线定义;真正决定这套固件能否顺利构建的,是那个预编译了 libmicroros.a 的子模块。

    DBC 的规模与覆盖范围

    这份 DBC 位于 docs/IFS08_FSG26_datalogger.dbc,是六报文、45 信号的规模。内容按三类组织:行驶动力学、自动驾驶系统状态、安全遥测,目标接收方是数采设备。

    维度 内容 边界
    规模 6 条报文、45 条信号 仅覆盖发给数采的部分
    版本标识 IFS08_FSG26_DL_v1.0 对应 FSG26 赛季数采配置
    内容分类 行驶动力学、自动驾驶系统状态、安全遥测 不含其他节点间通信
    验证状态 未独立核查哪些报文实际在车上有过流量 需实车核对后使用

    「未核查哪些报文实际在车上有过流量」这一条很关键。DBC 里写了不等于车上发了,尤其在赛季前配置频繁变动的阶段。用这份文件做离线解码是安全的,但拿它推断整车的总线负载就会出错。

    micro-ROS 子模块为什么是构建的关键

    固件依赖一个名为 micro_ros_stm32cubemx_utils 的子模块,固定在 isc-fs 自己的 humble-isc 分支上,而非上游 micro-ROS 组织的主线。这个 fork 相对上游有两处差异,其中第一处直接决定了开发体验。

    差异项 上游 micro-ROS 做法 本 fork 做法 对开发的影响
    预编译库 libmicroros.a 与 microros_include/ 被 gitignore 在工作树中跟踪这两个产物 克隆带 –recurse-submodules 即可构建,无需 Docker 步骤
    自定义接口 仅标准接口 把自定义 ROS 接口包编译进 libmicroros 当前固件只用 std_srvs/std_msgs,用标准重建也可以

    把预编译库纳入版本跟踪,本质上是把「构建环境」变成「仓库内容」。代价是仓库体积,收益是任何装了 ARM 工具链的机器都能直接 make。对一支成员轮换频繁的学生车队来说,这个取舍是合理的——它消除了最常见的「在我机器上能编」类问题。

    当前固件的 ROS 接口面有多窄

    仓库注明固件目前只用到 std_srvs 与 std_msgs,因此即使用上游标准方式重建 libmicroros 也能工作。这一点写在 Core/Src/ros_task.c 里。反过来说,一旦引入自定义消息类型,就必须按 firststeps.md 里记录的流程重建库,而不能沿用现成的预编译产物。

    持续集成:双平台门控

    仓库的 .github/workflows/build.yml 在每次推送到 main、dev、feat/**、fix/** 以及每个 PR 时运行一次固件构建。

    检查项 配置 作用
    工具链 arm-none-eabi-gcc 14.3.Rel1 锁定编译器版本,避免工具链漂移
    运行平台 ubuntu-latest 与 macos-latest 双跑 排除只在单一平台能编的偶发通过
    构建方式 make -j 并行构建,缩短反馈时间
    产物断言 检查 uDV.elf / uDV.bin / uDV.hex 存在 防止「编译无错但没出产物」
    产出 上传为 uDV-firmware 构件 每次提交都有可下载固件

    dev 分支设有保护规则:两个 runner 都必须为绿才允许合并 PR,因此 CI 红了合并按钮直接变灰。这条规则把「CI 通过」从建议变成了硬门槛。

    分支模型:把分支历史挪进 Issue

    这套流程的设计目标很明确:让仓库保持干净,同时不丢失任何一次改动的历史。仓库只有 main 与 dev 两条常驻分支,且都不允许直接提交。

    分支 定位 写入方式
    main 生产分支,只含可刷车的已验证代码 由 dev 经完整固件验证(HIL/台架)后 PR 合入
    dev 集成分支 只接受来自 feature 分支的 PR
    feat/编号-短标题 新功能 从 dev 创建,合并后删除
    fix/编号-短标题 缺陷修复 从 dev 创建,合并后删除

    feature 分支合并后即被删除,历史靠 GitHub Issue 保留:每个分支对应一个带 feat 或 fix 标签的 Issue,标题里写完整分支名。要查当前在做什么就按标签过滤「open」,要查全部历史就过滤「closed」;下一个分支编号取同类最后一个已关闭 Issue 的编号加一。

    三个自动化细节

    推送分支时工作流会自动开 Issue,标题镜像分支名并打上正确标签,还带一个填写说明的模板与创建者名字。如果编号不是预期的下一个,Issue 里会显示警告并提示删除重建。开发者第一次提交并推送后,Issue 的描述区会被该提交信息自动填充一次——若开发者事先手动编辑过则不会被覆盖,且后续提交不再修改。这几处设计把「编号靠自觉」变成了「编号错了会被提示」。

    常见问题

    这份 DBC 能代表 IFS08 整车的 CAN 总线吗?

    不能。它是六报文、45 信号的数采专用定义,只覆盖行驶动力学、自动驾驶系统状态与安全遥测这三类发给数采的内容,属于部分节点地图而非整车总线定义。上游也未独立核查哪些报文实际在车上有过流量。

    为什么克隆时必须带 –recurse-submodules?

    因为 micro-ROS 支持库在子模块里,且该 fork 把预编译的 libmicroros.a 与 microros_include/ 直接跟踪在工作树中。带上这个参数后,任何装了 ARM 工具链的机器都能直接构建,不需要额外的 Docker 步骤。若忘了带,可在仓库内执行 git submodule update –init –recursive 补救。

    CI 为什么要同时在 Ubuntu 和 macOS 上跑?

    为了排除只在单一平台能编译通过的偶发情况。dev 分支保护规则要求两个 runner 都为绿才允许合并 PR,因此任一平台失败都会让合并按钮变灰,把 CI 通过从建议变成硬门槛。

    固件现在用了自定义 ROS 消息类型吗?

    没有。仓库注明固件目前只使用 std_srvs 与 std_msgs,因此用上游标准方式重建 libmicroros 也能工作,相关信息写在 Core/Src/ros_task.c 里。一旦引入自定义消息类型,就必须按 firststeps.md 记录的流程重建库。

    如何知道下一个 feature 分支该用几号?

    取同类最后一个已关闭 Issue 的编号加一。在 GitHub Issues 里按 feat 或 fix 标签过滤并按最新排序,读出最后一个编号即可;feat 与 fix 两个计数器互相独立。编号不对时自动创建的 Issue 会显示警告并提示删除重建。

    延伸阅读

    参考资料

    • 项目 06 —— public-can-dbc-datasets/additional/isc-ifs08-udv/SOURCE.md(DBC 路径、六报文 45 信号规模、版本标识与权利状态)
    • 项目 06 —— public-can-dbc-datasets/additional/isc-ifs08-udv/README.md(子模块 fork 差异、CI 配置、分支模型与自动化流程)

    免责声明

    本文内容来自公开仓库的说明文件,描述的是一支学生方程式车队在特定赛季的开发配置,其工具链版本、分支策略与 CI 配置随时间可能变动。DBC 规模与覆盖范围均依据该仓库说明,未做实车核查。文中方法可直接参考,但具体参数请以实际项目状态为准。

    更新记录

    • 2026-10-14 初稿

  • 商用车 DBC 知识包的许可证链:16 条报文与四类来源分级

    结论:拿到一份商用车 DBC 知识包,第一件事不是数报文,而是核对许可证链。这份包的 6 份 heavy-duty OEM DBC 合计只有 16 条报文,只覆盖 6 个制造商的部分 J1939 PGN;真正决定它能否进入产品的,是 21 个已收录来源里 2 个强制署名、3 组 GPL-3.0 与 2 份 CC-BY-SA-4.0 的传染性条款,以及 9 份被明确拦在 curated 目录之外的文件。

    为什么许可证链比报文数更先决定可用性

    DBC 是数据而非代码,但它的来源决定了分发边界。这份知识包的 LICENSES.md 开篇就写明了定位:它不授予任何访问许可,只保留公开来源本身的许可证。也就是说,把别人的 DBC 拷进自己的包,不会让许可证消失,只会把义务继承下来。

    因此合理的处理顺序是:先按许可证把来源分档,再决定哪些能进 curated/、哪些只能留在 raw/、哪些在闭源分发时必须整体剔除。报文数量在这条链里是最后才看的东西——16 条报文和 2000 条报文,合规成本可能完全一样。

    许可证档位 义务 代表来源 分发处理
    MIT / Apache-2.0 保留版权声明 commaai/opendbc(57 静态 + 39 生成器输出)、canboat/canboat、projectgus/kona-ev-dbc 可直接随包分发
    CC-BY-4.0 强制署名 berumiya/CAN_DBC_6thGenMazda(Mazda 6th-gen HSCAN/MSCAN) 分发须带署名串
    CC-BY-SA-4.0 署名 + 相同方式共享 fsfarmscaper/jaguar-xf-x250-can(MS/HS 总线各一份) 闭源分发须剔除
    GPL-3.0-only 传染性,须保留许可证文本 dalathegreat/leaf_can_bus_messages、qwec01/ARCFOX_dbc、gbt27930_2023.dbc 运行期动态加载或整体剔除
    无许可证 / 权利存疑 不可判定 见 DO-NOT-INTEGRATE 列表 停留在 raw/ 作研究记录

    六份商用车 OEM DBC 的实际覆盖面

    目录里的六份 DBC 来自上游 data/dbc/heavy_duty/,合计 16 条报文,按制造商分布为 Mercedes-Benz Actros 3 条、Caterpillar 2 条、Cummins 2 条、Detroit 3 条、Scania 3 条、Volvo 3 条。每份文件只覆盖选定的制造商私有 J1939 PGN,既不是完整的整车网络定义,也不构成车型年款的适配承诺。

    制造商 报文数 性质 证据边界
    Mercedes-Benz Actros 3 制造商私有 J1939 包内自产,非 SAE 标准
    Caterpillar 2 制造商私有 J1939 包内自产,非 SAE 标准
    Cummins 2 制造商私有 J1939 包内自产,非 SAE 标准
    Detroit 3 制造商私有 J1939 包内自产,非 SAE 标准
    Scania 3 制造商私有 J1939 包内自产,非 SAE 标准
    Volvo 3 制造商私有 J1939 包内自产,非 SAE 标准

    这六份文件在上游被描述为「由项目自身的 OEM decoder 定义生成」。这句话本身就是一条重要的证据边界:DBC 文件不确立底层测量方式,也不确立每个字段的校验依据。用它们做离线解码参考可以,拿来做 ASIL 相关功能的信号依据则超出其能力。

    同包内的其他来源量级

    同一个 LICENSES.md 还登记了若干量级明显更大的来源:ISOBUS 数据字典(isobus.net 的 AEF/ISO 11783-11 公开导出)生成出 102 条报文、1341 条信号的 isobus_dd11783.dbc;BogGyver 的 opendbc 分支贡献 28 份已提交 DBC,其中静态 7 份(hyundai_kia_generic、stellantis_dasm、tesla_can_pre1916、vw_golf_mk4、vw_mqb_2010、chrysler_pacifica_2017_hybrid、tesla_radar),生成 21 份(Lexus 6、Honda 6、Toyota 9)。把它们和 16 条报文的商用车部分放在一张表里看,才能判断这份包的重心到底在哪里。

    DO-NOT-INTEGRATE:九份被拦下的文件

    包里专门维护了一张「禁止整合」表,列出 9 个停留在 raw/ 的条目。它们的共同点是许可证状态未解决,因此不能拷进 curated/ 或 data/dbc/。

    风险类型 判定依据 处理动作
    未声明许可证 仓库未给出任何许可证 仅作研究记录,不进 curated
    内容未下载但已知无许可证 上游未标注,权利不可判定 不纳入任何分发包
    格式不兼容 是 Markdown 表格而非 DBC 不作为 DBC 来源整合
    标准组织版权风险 标注 MIT 但内容派生自 SAE J1939 标准,存在版权主张 整条排除,不进 curated

    这张表的价值在于把「不知道」显式化。多数 DBC 收集项目的问题不是抄错了文件,而是把许可证不明的产物直接混进了可分发目录,事后无法追溯。

    SAE 版权风险为什么单独列一档

    表中有一条的判定很典型:它被标注为 MIT,但内容派生自 SAE J1939 官方标准,上游仓库存在公开的版权主张记录。许可证标签与实际权利不一致时,以权利为准。这也是为什么来源表里会出现「标注 MIT 但仍排除」这种看似矛盾的处理。

    copyleft 的隔离方式:运行时数据载荷

    包内对 GPL-3.0 与 CC-BY-SA-4.0 采用了一套明确的隔离策略,核心是让这些 DBC 不构成软件代码的组成部分:

    1. 数据分离:这些文件不静态嵌入、不编译进二进制,而是在运行时由 cantools 以数据载荷方式动态读取。
    2. 闭源分发清理:在严格的商业或闭源分发中,可直接从 data/dbc/ 删除或排除这些文件;核心诊断、J1939、OBD-II 等 MIT/Apache-2.0 授权的 DBC 仍能独立工作。
    3. 合规登记:所有许可证与署名映射统一登记在仓库根目录的 REUSE.toml,符合 REUSE 3.0 / SPDX 规范。

    这套「气隙」设计的意义在于把传染性风险收敛到一个可删除的目录,而不是扩散到整个构建产物。是否需要真正删除,取决于分发形态;能不能删得干净,则取决于前期有没有做隔离。

    常见问题

    这份商用车 DBC 包能直接用于整车网络解析吗?

    不能。六份文件合计 16 条报文,每份只覆盖选定制造商的私有 J1939 PGN,上游明确说明它不是完整整车网络定义,也不保证车型年款适配。它适合作为特定 PGN 的解码参考与比对基准。

    为什么有些来源标注 MIT 却被排除在整合之外?

    因为许可证标签与真实权利可能不一致。DO-NOT-INTEGRATE 表中就有一项虽标注 MIT,但内容派生自 SAE J1939 官方标准,上游存在公开的版权主张记录。遇到这种情况以实际权利为准,整条排除。

    闭源产品里能不能保留 GPL-3.0 的 DBC 文件?

    可以保留但需要隔离:这些文件不得静态嵌入或编译进二进制,只能由 cantools 在运行时作为数据载荷读取,并且分发包要附带 GPL-3.0 许可证文本。若要彻底消除传染性影响,则须从 data/dbc/ 删除这些文件,其余 MIT/Apache-2.0 授权的 DBC 不受影响。

    CC-BY-4.0 与 CC-BY-SA-4.0 的差别在实际处理上是什么?

    CC-BY-4.0 只要求署名,分发时带上指定的署名串即可;CC-BY-SA-4.0 在署名之外还要求相同方式共享,因此在闭源分发中必须整体剔除。本包里前者对应 Mazda 6th-gen 的两份 DBC,后者对应 Jaguar XF X250 的 MS/HS 两份 DBC。

    DBC 里的信号定义能不能当作安全相关功能的依据?

    不能。包内免责声明写明,DBC 内容由社区逆向工程产生,不是车辆制造商的官方数据,在安全相关(ASIL)用途中只能作为参考。上游对这些文件的说明也指出,底层测量方式与各字段校验并未由 DBC 文件确立。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/ucanlab-heavy-duty-oem/SOURCE.md(六份 DBC 的 16 条报文、制造商分布与权利边界)
    • 项目 01 —— public-can-dbc-datasets/additional/ucanlab-heavy-duty-oem/LICENSES.md(21 个来源的许可证映射、copyleft 隔离策略与 DO-NOT-INTEGRATE 表)
    • 项目 01 —— public-can-dbc-datasets/additional/ucanlab-heavy-duty-oem/README.md(上游产品定位、协议覆盖与 data/PROVENANCE.md 的登记机制)

    免责声明

    本文所述的 DBC 内容均为社区逆向工程产物,不代表车辆制造商的官方数据。文中数字均来自上述公开仓库的说明文件,未经独立实车验证;不同车型年款、市场与 ECU 版本可能存在差异。涉及安全相关用途时请仅作参考,并以实际测量与官方资料为准。

    更新记录

    • 2026-10-14 初稿