标签: CAN总线

  • 车电接入:为什么 ESP32 的 TWAI 不等于 OBD 接口

    结论:TWAI 只是 ESP32 片内的 CAN 控制器,负责按 CAN 协议收发帧;它既不含物理收发器,也不是 OBD 接口。从芯片引脚到车上那个 OBD 口,中间还缺收发器、隔离与车电保护、接插件、车型协议栈四层,任何一层没做,都不算「支持汽车 OBD」。

    TWAI 是控制器,不是收发器,也不是接口

    因为 TWAI 在芯片内部只做到协议层,它输出的是逻辑电平的 CAN 帧,而不是能挂到双绞线上抗干扰的差分信号。芯片文档把它列为 CAN 控制器外设;要真正接上总线,必须在外面再加一颗 CAN 收发器。也就是说,TWAI 解决的是「怎么组帧、怎么仲裁、怎么应答」,收发器解决的是「怎么把 0/1 变成 CAN_H/CAN_L 的电压差」——这是两块硅片干的活。内部调研文档对此的表述很直接:芯片的 TWAI 不是 OBD 线束或车电接口;也不能把 ESP 芯片的 TWAI 外设等同于「可以直接接车载 CAN」。

    这个区分不是抠字眼。很多演示能跑通,是因为桌面上用的是现成收发器模块加固定线束;一旦换成真车,变量立刻从「代码能不能跑」变成「电气和协议能不能活下来」。

    从 TWAI 到 OBD 口,中间缺的四层

    因为缺的是四层而不是一层,所以「加了收发器就完事」的判断往往是错的。把每一层单独拆开看,缺口会很清楚:

    层级 ESP32 芯片里有没有 还缺什么 判断依据
    协议控制器(帧收发与仲裁) 有,即 TWAI 外设 — 芯片内置 CAN 控制器
    物理层收发器 没有 外部 CAN 收发器(如 CA-IS3050G,官方标称最高 1 Mbps、1000V 隔离) 内部调研:TWAI 需外部 CAN 收发器
    电气隔离与车电保护 没有 隔离 / 保护设计;稳压输入范围不等于车规结论 6–36V 是稳态输入范围,不证明能抗负载突降、反接或冷启动
    接插件与线束 没有 OBD 接头、电源取电、终端电阻、总线接入方式 需单独确认连接器与总线接入兼容性
    车型协议栈 没有 OBD-II 诊断请求,或按 DBC 解码的原始 CAN 帧 两条协议路径不同,不能互相替代

    四层里最容易被低估的是最后一层。物理上接通、帧也收到了,并不代表理解了内容——这取决于车型,也取决于你走的是哪条协议路径。

    「能收到 CAN 帧」不等于「支持 OBD」

    因为原始 CAN 帧解码和 OBD-II 诊断请求是两条不同的协议路径,收得到帧只是拿到了开场。OBD-II 走的是标准化的诊断请求与响应:你按标准向 ECU 问一个 PID,比如车速 PID 0x0D,ECU 按约定格式回一个值——这个值以整数 km/h 报告。而原始 CAN 帧走的是另一条路:总线上本来就有的报文,你需要有一份 DBC 或等价描述,才知道某个字节的某几位代表什么。

    两者的覆盖范围不同。标准 OBD-II 只能拿到法定那一批通用 PID;档位、油温、油压、增压这类字段,只有对应车型或外接传感器被确认之后,才有有效值可显示。所以不能用一个「TWAI + DBC」的后端宣称覆盖所有 OBD 功能。如果做数据记录,合理的做法是同时保留三样东西:原始帧、解码值、时间戳——保留原帧是为了以后换一份 DBC 能重算,时间戳是为了还原时序。站内另一篇讲车速 PID 取值的文章对这件事有更细的展开,见 OBD-II PID 入门:车速 0x0D 为什么是整数。

    电这一层:6–36V 是稳态范围,不是装车结论

    因为汽车电环境在启动和负载切换时会剧烈波动,一个标着宽压输入的模块并不能证明它能上车。M5Dial 后端子标称 DC 6–36V,但这是稳态输入范围,它不证明该板能抗汽车负载突降、反接或冷启动时的电压跌落。这类验证需要在车上按实际工况测,而不是看参数区间推导。

    同样的道理适用于任何「能供电」的表象。供电接通、CAN 收发器也接上了,仍然可能因为一次冷启动、一次搭电、一次反接而失效。车电保护是要单独设计的部分,不是买板子时附带的赠品。

    引脚预算:1.75 上真正可用的通用 GPIO 只有 16/17/18

    因为外设要靠引脚接出来,而这块板的引脚早就被板载器件分掉了大半,所以「计划外接多少东西」必须在画线之前先算。以已购的 ESP32-S3-Touch-AMOLED-1.75 为例:8Pin 排针只有 VBUS/GND/3V3、UART0 和 GPIO16/17/18,其中 43/44 是 UART0,可能还要承担调试输出;-G GPS 版本还可能占用 17/18;I2C 14/15 是板载多器件共用的总线。

    这意味着如果走 MCU 的 TWAI 控制器外接 CAN 收发器,GPIO 分配要和 GPS、TPMS 接收器、串口日志同时规划——三者会抢同一批引脚。另外要注意,P4 那几块板的 Wiki 概览页既没有列板载 GPS,也没有列车载 CAN 收发器;不能因为屏幕大就默认它自带车源接口。显示链路本身的差异另见 车载 HMI 的 30 FPS:SPI 与 MIPI-DSI 显示链路差在哪。

    常见问题

    ESP32 自带的 TWAI 能直接接汽车 CAN 总线吗?

    不能直接接。TWAI 是片内 CAN 控制器,输出的是逻辑信号,必须外接 CAN 收发器才能变成总线上的差分电平;除此之外还要解决隔离、车电保护、接插件和车型协议。缺任何一层都不算可用,「芯片支持 CAN」和「产品支持 OBD」之间隔着整条链路。

    加一块 CAN 收发器模块,是不是就等于支持 OBD 了?

    不等于。收发器只解决物理收发的一部分。收得到帧之后,你要么发出标准 OBD-II 诊断请求并按 PID 解析响应,要么按 DBC 解原始帧——这是两条不同路径,覆盖的字段也不同。此外还要确认 OBD 接头、电源取电、终端电阻和总线接入方式,这些都不是收发器模块自带的。

    只有 OBD-II,没有 DBC,能读到油温、增压这些字段吗?

    多数情况下读不到有效值。标准 OBD-II 只覆盖法定那批通用 PID,档位、油温、油压、增压这类字段需要对应车型或外接传感器被确认之后才能显示。没有 DBC 或等价描述,总线上即便有这些报文,也无法知道某个字节代表什么。缺失时应写「待实测」,而不是用猜的数值填表。

    为什么说 6–36V 供电不代表能装车?

    因为 6–36V 描述的是稳态输入范围,而车上更危险的是瞬态:冷启动跌落、负载突降、反接。宽压输入模块通常不包含这些防护。要上车,得按实际车电工况单独设计和验证保护电路,不能靠参数区间推导结论。

    本文数据来自星核火花赛车科技内部「车载小仪表开发板调研」项目的两份核查文档:《小仪表开发板详细调研与路线建议》(调研日期 2026-10-03)与《五块赛道产品候选板:硬件事实表》(核查日期 2026-10-03)。文中引脚编号、SKU、标称参数均以微雪官方 Wiki 概览页与项目内核查记录为准;项目文档明确说明本阶段为桌面资料核查,未做实机测试或供应商询价。TWAI 与 OBD 的层级差异、DBC 解码与 OBD-II 诊断的协议路径区分、引脚占用与车电保护要求,均引自上述两份文档的原始表述。涉及车载电压环境的判断(如 6–36V 为稳态范围)为文档给出的限定说明,不作为实测结论。相关产品形态与显示链路的讨论,见 圆屏还是方屏:车载仪表的显示形态该怎么选 与 OBD AI 插件化平台:端侧解析为什么必须插件化;数据采集形态可参考 SR-RaceBox 车载数据采集器。

  • 竞品功能点数据库:怎么量化 Car Scanner 的字段覆盖度

    结论:量化竞品覆盖度不能靠数功能菜单,而要按证据等级分层。Car Scanner 的 APK 2.1.50 快照有 1304 个配置、126217 条 PID 定义,但功能库只确认 226 个功能点(静态 80 / 界面 146);其中 106198 条定义没有任何公开线索,本地实车能算出值的只有 130 条。定义存在、车辆响应、物理标定,是三件需要分别举证的事。

    为什么「数功能菜单」量化不出真实的覆盖度

    因为菜单里有这一项,和这一项在你车上能读出正确数值,完全是两回事。竞品拆解最容易犯的错,是把界面截图里出现的条目、或者配置库里存在的定义,直接当成「已经支持」的能力去计数。

    一份可核查的功能点数据库应该把每条功能拆成「功能点 → 来源证据 → 验证等级」三段。在这份 Car Scanner(Android 包名 com.ovz.carscanner)的拆解里,功能点总计 226 条,挂接的来源关联 533 条,去重后不同的来源文件 305 个;如果只按 UI 截图计,会漏掉大量只有代码路径、没有界面去向的条目——实测有 94 个功能点没有直接界面产物,其中 76 个本属静态类。

    验证等级只有两档,是刻意保守的:static(静态证据)80 条与 ui(界面证据)146 条。它不包含「实车响应验证」这一档,因为实车数据只覆盖极少车型,不足以支撑功能级结论。

    226 个功能点拆到模块,才知道竞品把钱花在哪

    因为总量相同不代表结构相同。把 226 条按模块归类后可以看到,Car Scanner 的重心明显压在「编码与适配」和「入门与连接」上,而不是实时数据可视化:

    模块 功能点数 模块 功能点数
    编码与适配 33 仪表板 10
    入门与连接 27 统计 10
    故障诊断 22 平台集成 9
    所有传感器 20 设置 8
    自定义传感器 20 ECU 识别 7
    数据记录 19 设置与备份 6
    实时数据 13 车辆管理 / 生态集成 各 5
    商业与账户 / 联网与更新 各 4 性能测量 3

    这个分布解释了一件事:竞品的护城河不在「能显示几个数字」,而在适配与配置体系的规模。同一目录下的来源台账记录 1004 条来源记录、合计 181,649,025 字节,直接引用表 77 张、引用发生 187,314 次;来源类型里 ui_dump 322 个、binary 410 个、list 236 个、screenshot 33 个、report 3 个。绝大多数证据是二进制产物与界面转储,而不是「一张截图说明一个功能」。

    APK 里有 12 万条 PID 定义,但 10.6 万条没有公开线索

    因为「配置里写了一条定义」和「有公开证据指向它被真的发出并被响应」是两个数字。APK 2.1.50 快照含 1304 个配置、126217 条车型 PID 定义;面向应用 2.1.0 的更新包(配置版本 2.2.21)为 1323 个配置、127126 条定义。手机端的品牌选择列表有 178 项,但品牌项 ≠ 车型数 ≠ 完整标定数。

    把定义按「是否有公开线索」归并后,缺口非常直观:

    覆盖状态 定义条数 说明
    无任何公开 PID 线索 106198 既没有公开测试文件,也没有实车案例指向
    仅有公开肯定响应候选 14880 有请求/响应线索,但未经物理标定
    公开精确请求候选 2160 请求头与命令可对,响应物理含义未定
    已发表数值等式候选 1906 算出的数值与公开值相等,仍属候选
    本地实车已得肯定响应(未物理标定) 130 本地日志能复算,缺独立仪表同步

    整体画像见公开证据汇总:候选 PID 文件关联 86810 条、不同公开测试文件 15190 个、不同公开响应案例 89112 个,其中严格匹配的肯定请求案例 84803 个。看起来数字很大,但真正落到「数值等式」的只有 1916 条定义,且其中限定在明确年款内的仅 450 条。也就是说,可算 ≠ 可信。

    六道验证门槛:从「有定义」走到「可展示」

    因为每一步都可能失真,所以要把「一条 PID 是否可用于产品展示」拆成六个必须逐级通过的关口,任何一级缺失都只能停在候选状态:

    关口 要确认的内容 缺失时会怎样
    1 定义 固定应用/更新包版本、车型年款、配置索引、请求头、命令与公式 无法复现,跨版本会串味
    2 发出 原始会话中确认实际请求头、命令与发送顺序 静态 CMD/HDR 不等于真的发过
    3 响应 ECU 响应头、肯定/否定状态、ISO-TP 重组与数据窗口 把否定响应或残帧当作数值
    4 计算 字节序、符号、比例、偏移、单位与无效值规则 除数为 0 或窗口越界仍出数
    5 标定 不同工况 + 同步仪表或独立测量,确认物理含义 只有算术自洽,没有物理依据
    6 展示 时效、范围、缺失数据处理与跨字段同步性 把过期值当当前采样

    三个实车案例说明「有响应」也不等于「标定成立」

    因为公开的实车日志往往只证明了链路走通,证明了数值「算得出来」,却缺少独立仪表同步这一环。

    斯柯达 Octavia 车主在 WiCAN 议题 771 上传的 Car Scanner 2.1.25 日志里,457 条 Mode 22 请求中有 267 条完整肯定响应、148 条 NRC 0x31、42 条 NO DATA。落到定义层,592 行肯定响应覆盖 117 条定义;其中 DPF 子集的 96 行肯定响应里只有 15 行能按简单公式复算,22114F 的六次烟炱响应原始值为 0861/0862,但静态除数为 0,不能据此显示烟炱克数。这就是第 4 道关口没过。

    另一侧,KGM Torres EVX 的日志里 7E0/22FD0D 共 1232 次请求、1230 次完整多帧肯定响应,绝对/相对 SOC 算出 30.0% / 27.8%,补测 57.0% / 56.1%,后者与车主报告的车机 56.1% 一致。数值对上了,但车主车型、显示时点与物理 SOC 未独立核实,重复轮询也不构成独立标定,因此仍只能记为「作者显示值匹配、未标定」。

    本地哈弗 H6 混动日志则是国内车型的直接样本:78B/22E0DD → 7CB/62E0DD0000180C 是真实实车响应,但 H6 配置把这条定义为 BMS 上次休眠时长,所以 180C 不能当电池电流;0104 可算出计算负荷约 29.8%,也不能乘额定功率就冒充发动机实际功率。本地日志共涉及 170 条定义,其中 130 条得到肯定响应、全部会话累计 148 条——但那 130 条的状态明确写着「local_positive_response_not_physically_calibrated」,即未物理标定。这一点与站内 OBD-II PID 入门:车速 0x0D 为什么是整数 讲的「样本必须带元数据才能判断可信」是同一条原则。

    顺带一个反面样本:2024 Tata Nexon 汽油版车主公布的 19 组 SavvyCAN 请求/响应截图,与当前 APK 的 Tata 配置没有任何一组请求头加命令精确相交。这提醒我们,外部来源的「有响应」不能直接并入竞品覆盖率。

    做自己的产品时,这份数据库能直接拿来干什么

    因为拆解的价值不在「抄功能」,而在知道哪些结论有证据、哪些只是存在定义。对自研 OBD 仪表而言,这份库能提供三样东西:一是分母(12 万条定义里有多少是真有公开线索的),二是分层口径(六道关口),三是不可迁移清单——共享同一配置的车型(如 Hyundai / Kia / Genesis,或 SsangYong)不会因为其中一个车型验证过就跟着升级验证等级;跨年款的作者报告也不能扩展配置的实车验证范围。

    目前公开库索引的 178 个品牌里,仍有 40 个品牌处于无 PID 索引来源候选状态。这意味着行业里「某车型能读某字段」的说法,大多停留在单一作者报告,缺少可复现的原始帧。如果你打算对外宣称字段覆盖度,分母口径必须比竞品更保守,否则迟早被实车打脸。自研数据链路的设计思路,另见 OBD AI 插件化平台:端侧解析为什么必须插件化 与 EdgeForge:嵌入式侧端框架的自编译方案;采集侧硬件可参考 SR-RaceBox 车载数据采集器。竞品的市场定价与形态对照,见同批发布的 仪表市场对照:ScanGauge / Beeline / CHIGEE / Wahoo / Karoo。

    常见问题

    Car Scanner 到底支持多少车型,126217 条定义算多吗?

    126217 是 APK 2.1.50 快照里的车型 PID 定义条数,不是车型数、更不是已标定字段数。它分布在 1304 个配置里,其中 106198 条没有任何公开 PID 线索。判断「算不算多」要看有效分母——真正有公开数值等式对照的只有 1916 条定义。

    界面里能看到的功能,能直接算作已支持吗?

    不能。226 个功能点里 146 条只有界面证据、80 条只有静态证据,两者都不等于实车可用。94 个功能点连直接界面产物都没有。要判断可用性必须看链路是否有实车响应,以及是否完成物理标定。

    为什么公开的实车日志很多,却仍说「未标定」?

    因为实车日志通常只证明请求发出、ECU 响应和公式算得出值这三步。真正的标定需要不同工况下与同步仪表或独立测量比对。多数公开案例只有单一车主的显示值,且车型年款、电池版本或显示时点未核实,重复轮询同一命令也不构成独立采样。

    共享同一配置的其他品牌车型,可以跟着算验证过吗?

    不可以。拆解文档对每一个案例都单独声明了适用范围,例如共享配置的 Kia / Genesis / SsangYong 不因某一款车验证而升级;跨年款的作者报告(如把 2021 款结论套到 2016–2019 配置)也不被接受。协议可迁移的假设必须由目标车自己的原始帧来支撑。

    本文数据来自星核火花赛车科技内部「Car Scanner 功能点数据库」拆解项目(对象为 Android 包名 com.ovz.carscanner,索引更新至 2026-10-05),全部数字以该目录现有索引为准,属某一版本快照,不代表软件当前最新版本。文中所有公开案例均标注为「候选 / 未物理标定」,仅代表作者报告与算术对照,不构成 Car Scanner 或任何车辆的实测标定结论;共享配置的关联品牌与跨年款报告未纳入验证范围。篇幅所限未逐一列出案例来源文件名,完整引用见该目录下的《拆解总览》《数据脉络与软件架构》与 public_pid_research/ 台账。

  • OBD AI 插件化平台:端侧解析为什么必须插件化

    结论:端侧解析必须插件化,因为车辆私有协议、界面布局与派生算法都属于高频变化项,用整机固件去覆盖它们,等于每改一条规则就要重编译、重烧录一次主机。可行做法是把变化频率不同的职责拆成五层,让协议包、规则包、界面包独立签名发布,固件只保留低频 OTA 通道。但插件不等于万能:数据若不经过 OBD 网关,装什么插件都读不到,这一点必须在上架前就声明清楚。

    为什么「整机重编译」模式撑不住车型差异

    因为一旦把应用逻辑编译进固件,任何一个信号解码的改动都会变成一次固件发布,而品牌、年款、地区、动力类型与 ECU 软件版本的差异是持续出现的。

    源方案书把「哪些能力可以动态升级」逐项列了出来,判断依据不是功能大小,而是宿主是否已提供对应的底层原语:

    改动类型 能否通过插件完成 必要条件
    新页面、布局、颜色、单位、辅助阈值提醒 通常可以 使用宿主提供的界面组件和信号
    新衍生指标、过滤、统计、异常检测 通常可以 算力、内存、数据源与准确性满足要求
    新 PID / DID 的解码定义 有条件可以 传输方式已支持,来源合法,请求模板经验证
    新诊断传输、加密接入、复杂状态机 可能需要固件升级 宿主缺少相应底层原语或安全接口
    新 CAN 控制器、引脚、显示驱动 通常需要固件及可能的硬件改动 插件不能补齐缺失的电气接口
    ECU 写入、制动或动力控制 不在本方案插件权限内 不通过普通用户插件开放

    这里必须纠正一个常见误解:插件化不等于「未知车型插上就能自动破解全部协议」。未知数据可能根本不经过 OBD 接口,可能受安全网关限制,也可能没有合法可用的定义;硬件能力、驱动、运行时漏洞和新宿主接口仍然可能需要固件升级。所以方案书给出的正确承诺是「多数应用功能无需重编译整机固件」,而不是「以后永远不更新底层软件」。

    插件化把职责拆成五层,各自按不同频率更新

    因为不同职责的变化频率相差几个数量级,把它们绑在同一次发布里才是问题的根源。方案按更新频率重新切分,低频层保留固件通道,高频层走签名包:

    层次 长期职责 主要更新方式
    硬件与稳定底座 电源保护、CAN 驱动、诊断调度、看门狗、安全存储、升级恢复 低频固件 OTA;硬件变更仍需重新设计
    协议与数据层 标准 OBD、经过验证的私有信号定义、单位与数据质量 签名协议包;超出解释器能力时更新固件
    功能插件层 计算指标、辅助提醒、记录策略、仪表布局 声明式规则为主,按平台增加 Lua 或 Wasm
    AI 与交互层 理解需求、组合已知能力、生成候选插件、解释限制 手机、Linux 或云端模型服务;可独立升级
    治理与分发层 协议权利来源、验证证据、发布签名、授权、灰度、撤回 手机应用与可选服务平台

    首个产品的建议形态是「ESP32-S3 仪表 + 手机伴侣应用 + 声明式插件运行时」:仪表负责稳定采集与执行,手机负责自然语言交互、插件编辑、验证编排和分发;联网时可选云端 AI,离线时仍可执行已安装插件和手工创建规则。首期交付限定为:标准 OBD 数据、少量授权车型协议包、用户自定义页面、基于已知信号的规则提醒、插件签名与权限检查、故障回退与基础固件 OTA。首期暂缓包括任意 C/C++ 动态代码、行驶中主动探测未知诊断服务、由模型直接发送 CAN 帧、刷写 ECU、清故障码与执行器测试。

    六个核心模块,以及它们明确不授予的能力

    因为安全边界不能只在文档里写「不开放」,而要在模块职责上就切掉能力。方案把整机拆成六个模块,每个模块都写明它不拥有什么:

    模块 负责内容 不授予的能力
    Vehicle Gateway CAN 收发、ISO-TP、标准 OBD、经批准的诊断读取、请求预算 不接受插件直接传入任意 CAN 帧
    Signal Service 标准名称、单位、时间戳、来源、质量、订阅与缓存 不把缺失或超时值伪装为零
    Plugin Runtime 规则执行、状态隔离、超时控制、受限算法 不直接访问驱动、密钥、任意地址
    Plugin Manager 校验、依赖解析、兼容性、原子激活、回退、卸载 不接受无来源认证的安装包
    AI Orchestrator 需求转配置、引用协议资料、候选实现和测试 不修改策略、签名根或自行授予权限
    Release Service 审核、签名、车型发布、灰度与撤回 不把模型输出直接当作可信版本

    配套的稳定信号接口规定:每个信号至少携带 signal_id、数值、单位、来源 ECU / 协议包、采集时间、单调时钟时间、有效期、质量状态与错误原因;质量至少区分 valid、stale、unavailable、error,分析候选数据另标 experimental。标准信号与厂商信号使用不同命名空间,例如 obd.engine_rpm 与 vendor.example.transmission_oil_temp,避免同名不同义。这与站内 OBD-II PID 入门:车速 0x0D 为什么是整数 里讲的「样本必须带元数据才能判断可信」是同一套约束。

    为什么「只读」业务仍然会向车辆发送报文

    因为被动监听在 OBD 接口上通常只能看到很少数据,要拿到标准 PID 就必须主动发请求,而请求本身会占用总线并消耗 ECU 的处理时间。

    产品标称「只读」意味着不允许状态改变类业务,不意味着物理上不发送 CAN 帧。因此宿主必须统一执行请求合并、每 ECU 并发限制、重试上限、总线与响应时间监测和休眠控制。方案特别提醒:总线平均占用率低并不代表 ECU 负载安全,所以「请求预算必须经过具体车型验证,不能用一个全车型统一比例作为安全证明」。遇到超时、bus-off、异常响应、供电下降或诊断冲突迹象时,应停止新增请求并退避;外部诊断仪并不总能被可靠识别,产品还需要提供明确的维修停用模式。

    不是所有缺失数据都能靠插件补上

    因为「没有数据」有多种成因,只有其中一部分属于插件的能力范围。方案把成因和对应限制列成一张表,避免把工程限制伪装成产品能力:

    情况 可采用的方法 必须呈现的限制
    标准 OBD 已定义且车辆支持 查询受支持项,按标准解析 支持情况与刷新频率因车辆而异
    已有合法厂商定义 整理为协议包,测试车型与 ECU 版本 协议适用范围和权利范围受限
    数据可从已知信号推算 提供估计值与适用条件 明确标注估计,不能冒充传感器实测
    仅有可访问的未知报文 授权记录、离线分析、对照验证 相关性不代表信号含义被证实
    数据不经过 OBD 网关 获取正式接口、授权网关支持或专用硬件 单靠插件无法创造物理访问路径
    需要安全网关或受保护会话 走厂商允许的接入机制 用户同意不等于获得解锁或绕过权限

    此外,方案区分了三种彼此独立的「同意」:安装功能的同意、访问车辆的授权、以及协议与数据权利(协议资料的使用与再分发权,采样、上传、保留与训练数据的许可)。车主允许安装,不自动覆盖厂商协议权利,也不自动允许绕过安全网关。

    插件靠什么被约束住:宿主管线、资源预算与权限交集

    因为仅靠签名无法限制插件行为,所以约束分三层落地:清单声明、宿主独立拒绝、资源配额。方案给出的清单数据契约里,一条冷却液提醒插件声明 state_bytes: 16384、max_rule_nodes: 64、max_eval_ops: 256、min_interval_ms: 1000;宿主实际授权取「用户批准、发布者权限上限、设备策略、车型能力、清单请求」的交集,清单里的 false 或上限声明不是自我证明,宿主必须独立拒绝所有未开放操作。

    ESP32-S3 档的资源起始预算写得很克制,且被明确标注为实验上限候选值,必须结合显示、无线、TLS、CAN 与 OTA 同时运行的峰值收紧或调整:同时启用 3–5 个简单插件;单个规则包不超过 128 KB;每个插件的规则状态先限制为 16–64 KB;所有插件计算占用总 CPU 的预算先设为不超过 10%。界面侧建议 UI 数据刷新目标先按 5–10 Hz 设计、慢变化的温度信号按约 1 Hz 评估,但实际请求频率受车型能力限制,不能机械套用。

    验收门槛同样给了可核查的数字:安装、试运行、激活和迁移阶段注入断电,首轮累计至少覆盖 100 次故障注入,量产前扩展为自动化长期测试;并完成至少 72 小时组合功能稳定性测试。该测试不替代量产寿命试验。分阶段计划按约 5 人核心团队估算,总历时约 16–20 周达到受控试点;核心投入约 80–100 人周(约 18.5–23 人月),按每人月 3–6 万元全成本假设粗算,核心研发人力约 56–138 万元——方案书注明这是预算模型示例,不是报价,且不含硬件试制、协议许可、认证与云服务。

    四档硬件参考配置从 ESP32-S3(双核最高 240 MHz、片内 SRAM 512 KB,建议选配 16 MB Flash 与 8 MB PSRAM)一路延伸到手机级(建议 8–16 GB RAM、64 GB 以上存储)。方案强调「中高性能 MCU」不是单纯比主频更高,而应比较片内可用 RAM、MPU、CAN FD、缓存与 DMA 限制、图形加速和实时性;外部 RAM 也不自动等价于实时任务可用的片内 RAM。采集侧若需要对照方案,可参考 SR-RaceBox 车载数据采集器;数据回传与云端分析可对照 SR-Telemetry 实时遥测云。计时链路本身为什么不能用 GPS 替代 OBD 车速,另见 OBD 零百加速计时:为什么手机测不准,仪表该怎么算。

    常见问题

    「AI 插件化」是不是意味着未知车型插上就能自动破解?

    不是。方案明确不宜承诺「未知车型插上即自动破解全部协议」。未知数据可能不经过 OBD 接口、可能受安全网关限制,也可能没有合法可用的定义;插件无法创造物理访问路径,缺失时必须明确提示不可用,或走经授权的适配申请。

    插件能升级到什么程度,哪些还必须刷固件?

    页面、布局、单位、阈值提醒、衍生指标、窗口统计和经过验证的 PID / DID 解码通常可以通过插件完成;而新诊断传输、加密接入、复杂状态机、新 CAN 控制器 / 显示驱动、驱动与内核漏洞修复,通常需要固件升级。因此平台必须长期保留固件 OTA 通道。

    为什么标称「只读」的仪表还会向车辆发报文?

    因为被动监听拿到的数据很少,读取标准 PID 必须主动发请求。标称「只读」指的是不允许状态改变类业务,不代表物理上不发送 CAN 帧。请求需经宿主统一调度,且请求预算必须按具体车型验证。

    AI 在平台里能决定什么,不能决定什么?

    AI 可以做需求理解、生成结构化候选规则、解释数据为何不可用、生成边界测试;但不能决定车辆请求白名单、信任根、权限上限、密钥使用和协议量产签名。AI 的输出必须经过独立确定性校验器,不能靠另一个模型说一句「安全」就通过。

    本文数据来自星核火花赛车科技内部 OBD 仪表 AI 插件化平台方案的 V1.0 稿(2026-09-13,架构规划与立项评审状态)。文中的内存、Flash、CPU 占用、插件数量与界面刷新频率均为方案给出的选型建议或实验上限候选值,不代表已完成样机验证;约定「首期暂缓」的能力不在本方案插件权限内。分阶段历时、人力与费用口径为题述假设下的预算模型示例,不是报价,也不构成任何交付承诺。

  • OBD-II PID 入门:车速 0x0D 为什么是整数

    结论:OBD-II 标准 PID 0x0D(车速)返回的是整数 km/h,最小刻度就是 1 km/h,所以基于它做零百计时天然带约 1 km/h 的量化误差。真正决定成绩的不是界面刷新率,而是状态机在收到响应的那一刻锁定的时间戳——起点、60 km/h、100 km/h 三个点,都是「首次收到满足条件的样本」的接收时刻。

    为什么 0x0D 返回的是整数

    0x0D 是 OBD-II 的标准车速 PID,源文档口径明确写为「返回整数 km/h」。这意味着读回来的永远是整数,不会出现 60.5 km/h 这样的值。按 OBD-II 标准的通用定义,该 PID 为单字节量,以 1 km/h 为步长,值域覆盖 0–255 km/h(此值域属行业通识,非本项目实测数据)。

    整数输出带来的直接后果是:任何比 1 km/h 更细的门槛,都无法「直接读到」,只能靠推导。这一点决定了后面所有计时逻辑都要围绕「整数刻度」来设计,而不是围绕理想中的连续速度曲线。

    一次车速读数要走完的链路

    从主机发出请求,到拿到一个可用于计时的车速样本,中间要经过网关与总线,每一环都会给时间戳添上延迟。因此本项目要求每条车速样本保存六项元数据,缺一项就无法判断该样本是否可信。

    样本字段 用途
    原始响应 保留网关返回的原始字节,便于事后回溯
    解码值 把原始响应按协议换算成 km/h 后的数值
    请求发出时间 与接收时间一起算出单次请求的往返延迟
    响应接收时间 作为计时时间戳的基准
    网关状态 判断该样本是否来自可用、可信的链路
    单调时钟时间戳 避免系统时间被调整时影响计时差值

    必须强调:记录下的时间戳是 OBD 响应接收时刻,不是 ECU 的实际采样时刻。从 ECU 采样到主机收到响应之间,存在请求往返延迟和网关额外延迟,主机无从得知 ECU 精确的采样瞬间。所以计时精度首先受链路延迟约束,而不是受显示系统约束。

    数据源上还有一条硬边界:首选「经受保护车载网关读取标准 PID 0x0D」;若某车型使用专用车速信号,必须在车型配置里明确协议、单位与量化精度,不能默认它和 0x0D 一样。

    为什么「0.5 km/h 起步阈值」在 0x0D 上做不到

    因为 0x0D 只返回整数,没有 0.5 km/h 这个刻度,源文档因此直接写明:「0.5 km/h 起步阈值」无法直接实现。

    理论上可以用 0→1 与 99→100 两点插值,把整数跳变反推成更细的时间点。但插值是否成立,取决于轮询周期、请求往返延迟和车型信号特性——这三项必须先实测记录,才能评估误差量级。因此首版方案的结论是:不插值,也不用 IMU 或 GPS 去填补样本。起点判定只能落在「首次收到大于 0 km/h 的有效样本」上,其误差上限与实际有效更新率直接相关。

    计时状态机:两个锁存点,一次异常即作废

    状态机的作用是把「什么时候算开始、什么时候算结束」写成可复核的规则,避免用显示刷新或人为判断来计时。首版状态机如下:

    状态 触发条件 动作
    IDLE 收到连续有效的 0 km/h 样本,覆盖至少 1 秒 进入 ARMED
    ARMED 首次收到有效且大于 0 km/h 的车速 记该样本接收时刻为 t0,进入 RUNNING
    RUNNING 首次收到车速 ≥ 60 km/h 记 t60;继续计时
    RUNNING 首次收到车速 ≥ 100 km/h 记 t100,锁存 t100 − t0 与 t60 − t0,进入 COMPLETE
    任意计时状态 网关断连、PID 不支持、响应超时、样本乱序或不可信 标记本次无效,保存原因,不显示成功成绩

    只有 t100 出现时才锁存成绩;中途出现任何一种异常,本次都判为无效并记录原因,不会输出一个「看起来正常」的秒数。这样做的代价是弃权率升高,收益是每一条显示出来的成绩都能追溯到具体样本。

    还有一个容易踩的坑:「连续 0 km/h」必须由多个有效样本构成,不能把网关断连期间保持的旧值算进那 1 秒。否则车辆其实没动,也可能因为缓存值而被误判为已就绪。

    采样频率不等于刷新频率

    界面上数字跳得快,不代表车速采样得快。界面刷新频率只是渲染频率,车速采样频率由 PID 的轮询周期决定,两者不是一回事。把二者混为一谈,就会用「看起来很流畅」掩盖「样本其实很稀疏」的事实。

    显示层需要提供五种状态:待连接、待起步、计时中、成绩、无效记录。并且历史最佳只收录有效、且带车型与数据源元信息的成绩——否则一次异常样本就可能被当成纪录留存下来。相关界面形态可参考 圆屏还是方屏:车载仪表的显示形态该怎么选,其中说明了为什么 1.64 寸这类 280×456 竖屏适合做成计时器。

    验收前必须实测的三组数据

    在把任何精度写进规格之前,以下三组数据是硬前提,缺任何一组都无法声称精度:

    1. 注入测试:向同一套解析与状态机灌入速度曲线,覆盖缓慢起步、瞬时跳值、重复帧、乱序、超时和中途失联,逐项核对状态迁移与时间戳是否符合预期。
    2. 实车链路记录:在目标车型上记录 PID 支持情况、有效车速更新率、请求往返延迟分布、网关额外延迟,以及计时期间的丢包率。
    3. 独立参照比对:用独立参考设备同步采集多次 0–100 加速,统计偏差与离散程度。

    最后必须说清楚:源文档中 ±0.05s 与「优于手机」是待验证目标。在没有实测证据之前,它们既不能写成已达到的精度,也不能作为宣传文案。计时链路的原理与数据源约束,另见 OBD 零百加速计时:为什么手机测不准,仪表该怎么算;采集侧的实现可对照 SR-RaceBox 车载数据采集器。

    常见问题

    0x0D 能读出小数点后的车速吗?

    不能。0x0D 返回整数 km/h,最小刻度就是 1 km/h。更细的分辨率只能靠插值推导,而插值是否可用取决于轮询周期与链路延迟,首版方案不做插值。

    为什么不能用 GPS 或 IMU 辅助计时?

    本项目里 GPS 不参与计时、插值或丢包补偿;QMI8658 只记录峰值 G 和 G 曲线,不参与起点、60 km/h、终点的时间戳判定。计时输入唯一来自 OBD 车速,以保证每一条成绩都能追溯到具体数据源。

    为什么时间戳不是 ECU 采样时刻?

    因为记录的是 OBD 响应接收时刻。从 ECU 采样到主机收到响应之间有请求往返延迟和网关额外延迟,主机无法得知 ECU 精确的采样瞬间,所以计时精度先受链路延迟约束。

    一次零百成绩什么时候才算有效?

    要同时满足两点:状态机按顺序经过 IDLE → ARMED → RUNNING,并在收到 ≥ 100 km/h 的样本时锁存成绩;且全程没有出现网关断连、PID 不支持、响应超时、样本乱序或不可信。任一异常都判为无效并保存原因。

    本文数据来自星核火花赛车科技内部车载仪表研究项目的《1.64 寸 OBD 零百计时规格》(2026-10 版)。PID 0x0D 的精度、延迟与插值可行性均以实车标定为准;文中的 ±0.05s 与「优于手机」为源文档标注的待验证目标,非已达成的精度指标。文中 0–255 km/h 值域为 OBD-II 行业通识,未经本项目实测,仅供理解整数刻度之用。