双模时钟:离线可复现与在线真实感如何兼得

测试平台架构有个绕不开的两难:

多数平台在这道选择题里二选一。Cyclone Core 的答案是不做选择,做时钟:一个双模时钟,让同一套引擎在两种物理里行走。这篇讲清楚这个架构决策。

一、先分清两个旋钮:时钟 × 环境

“离线/在线”其实是两个独立旋钮的组合:

  虚拟时钟 真实时钟
回放数据 ① 离线模式:完全受控的实验室 ③ 很少用(不展开)
实采总线 ④ 没意义(真实数据不等你) ② 在线模式:真实世界的现场

有用的主要是两格:离线模式 = 虚拟时钟 + 回放文件,在线模式 = 真实时钟 + 实时总线。

二、离线模式:时间由平台注入

离线模式下,时间不是流逝的,是注入的。调度器以固定步长(1ms 一个 tick)推动整个世界:发一帧数据、走一步被测逻辑、记一笔日志。传感器数据来自文件回放,整个世界是封闭的。

这换来离线模式的王冠:比特级一致。同一份场景 YAML、同一个 seed,跑一千次,日志逐字节相同,判定结果必然相同。由此得到三个工程红利:

  1. bug 永久可复现——抓到即钉死,不存在”我机器上是好的”;
  2. CI 友好——结果可缓存(内容寻址的 PASS),流水线不抖;
  3. 免费的大规模采样——seed 矩阵跑 300 把做统计判定(见本专栏第 1–3 篇),机器时就是全部成本。

三、在线模式:时间由物理注入

在线模式下,时钟服从物理世界(操作系统时钟、总线真实节拍),数据来自 SocketCAN/以太网上的真实节点。你得到的是离线给不了的东西:

四、诚实的代价:为什么在线 + 真实 ECU 必须放弃比特级

这是本文最重要的一节,因为很多平台在这里说假话。

接上真实 ECU 后,比特级一致在物理上不可能,至少有五个泄漏点:

  1. 传感器与采样噪声:ADC 量化、热噪声,同一物理量两次采样不会逐比特相同;
  2. 时钟漂移:每个节点的晶振有自己的 ppm 级偏差,分布式系统没有”同一个现在”;
  3. 总线仲裁:CAN 仲裁取决于各节点瞬时状态,帧的精确到达次序会漂;
  4. 调度抖动:非硬实时 OS 的调度延迟是随机变量;
  5. 温度等物理效应:硬件行为随温度漂移,实验室空调都是变量。

承认这一点,才能谈在线模式真正保留的三样东西:

一句话:离线给你”同一输入同一输出”,在线给你”不同输出、同一套判定”。前者靠确定性,后者靠统计学。

五、闭环:capture once, replay forever

两种模式不是两座孤岛,它们之间有一条传送带:

在线实采一次 ──► 保存为回放文件 ──► 离线永久回放
      ▲                                  │
      └──────── 修复后在线验证 ◄── 离线回归通过

现场出的 bug,抓包一次,从此它变成离线场景库里的一份回归资产——每次版本迭代,这个 bug 都要被重新处刑一遍。场景库因此越用越厚:不是工程师凭空编出来的,是真实世界一份份”贡献”的。

六、架构含义:模式切换是配置,不是重写

对架构师最关键的一句:同一份场景 YAML、同一个判定引擎、同一种证据格式,横跨两种模式。 切换模式改的是时钟源和数据源两个配置,不是代码。这意味着:

七、落点

双模时钟在 Cyclone Core 里是已实现的核心机制(虚拟时钟 + 1ms 确定性调度,已支持;在线模式适配 SocketCAN/UDP,已支持)。场景包里每个场景都标注了它跑在哪种模式下——下载下来,从离线的一致性跑起,再把同一份场景接到真实总线上。

测试平台最深的架构决策不是选真还是选假,而是想清楚:什么必须确定(判定逻辑与证据链),什么可以随机(物理世界)——然后用时钟把两者隔开。


附:名词解释(按出场顺序)

名词 通俗解释
双模时钟 平台支持虚拟时钟与真实时钟两种时间源的设计
虚拟时钟 时间由平台按固定步长注入(而非物理流逝),世界完全受控
离线模式 虚拟时钟 + 数据回放:封闭世界,比特级可复现
在线模式 真实时钟 + 实时总线:真实时序与真实硬件行为
比特级一致 同输入重跑,日志逐字节相同、判定必然相同
内容寻址的 PASS 输入哈希相同则判定结果可直接复用缓存,CI 不必重跑
seed 矩阵 同一场景用多个随机种子批量执行,供统计判定
泄漏点 真实世界中破坏比特级一致性的物理噪声来源(共五类)
总线仲裁 CAN 总线上多节点同时发帧时按优先级裁决的机制,结果随瞬时状态漂移
ppm 百万分之一;晶振频率偏差的常用单位
capture once, replay forever 在线抓包一次、离线永久回放的资产闭环
SocketCAN Linux 下的 CAN 总线网络接口框架

(产品能力以 Cyclone Core 当前版本为准。)

下一步:

下载场景包亲手跑一遍