1. 为什么需要 TDC?(核心矛盾:物理延迟 vs 高速位宽)

在 CAN 协议中,发送节点有一个雷打不动的规矩:Bit Monitoring(位监控)

规矩: 我(发送方)发出去一个位,我必须同时从 Rx 引脚读回来。如果读回来的跟发出去的不一样(且不是因为仲裁),我就认为总线出错了(Bit Error)。

在低速/仲裁域(Prop_Seg 还能撑住)

在 500kbps 下,一个位长 2000ns。物理环路延迟(Loop Delay)假设是 200ns。

  • 发送方发出去 跑一圈 回来。
  • 我们在 87.5% 处采样(大约 T=1750ns)。
  • 这时候 200ns 的延迟早就结束了,电平已经稳得像石头一样。
  • 结论: Prop_Seg 只要设得比延迟大,就能解决问题。

在高速 Data Phase(Prop_Seg 撑不住了)

到了 CAN FD,比如 5Mbps,一个位只有 200ns

  • 物理环路延迟依然是 200ns(物理定律,光速不变,线长没变,收发器延迟没变)。
  • 尴尬了:
    • T=0ns:你发出了这一位。
    • T=160ns(80%位置):你的普通采样点(SP)到了,你去读 Rx。
    • 但是! 信号刚跑出去还没回来呢!你读到的可能是上一位的残留电平,甚至是未知的中间态。
  • 后果: 发送方会误报 Bit Error,通讯直接崩溃。

矛盾点: 想要高速,位宽必须短;想要位宽短,采样点就会落在回采延迟时间内。普通的采样点(SP)已经失效了。


2. TDC 的工作原理:开“后门”

既然普通的采样点(SP)来不及读到正确的数据,CAN FD 的设计者想出了一个办法: “对于发送方,我们搞一个专门的、延迟的采样点,只用来做位监控。”

这个专门的采样点叫做 SSP (Secondary Sample Point,辅助采样点)

TDC 的过程分三步走:

第一步:测量延迟 (Measurement)

当数据段开始,发送方发出第一个隐性-显性跳变(通常是 FDF 位或 res 位后的那个边缘)时,控制器内部启动一个计数器。

  • Start:Tx 引脚出现跳变。
  • Stop:Rx 引脚收到这个跳变。
  • 结果: 测量出了实际的 Transceiver Loop Delay (收发器环路延迟)。这个值通常存放在 TDCV (TDC Value) 寄存器中。

第二步:加上偏移 (Offset)

光知道延迟还不够,因为信号刚回来时可能还在抖动(Ringing)。我们需要在信号稳定后再去采。

  • 我们需要配置一个由用户定义的偏移量,叫 TDCO (TDC Offset)
  • 这个 TDCO 类似于经典 CAN 里的 Prop_Seg + Phase_Seg1,目的是定位到位的中间位置。

第三步:在 SSP 处采样

控制器计算出 SSP 的位置 = TDCV + TDCO

  • 普通的 SP 该在哪就在哪(比如 80%),用来处理接收逻辑。
  • 但是在进行 Bit Error Check 时,控制器忽略 SP,而是去查看 SSP 那个时刻的 Rx 电平。
  • SSP 的位置实际上可能已经跨越到了下一位的位时间内(Delayed)。
    • 比如:我在发第 5 位,但我的 SSP 其实是在第 6 位的时间段里才去检查第 5 位的回读值。

3. 图解 TDC 机制

假设波特率 5Mbps (位宽 200ns),延迟 200ns。

时间轴 (ns): 0    100   200   300   400   500
TX (发送):   [  BIT N  ] [ BIT N+1 ] [ BIT N+2 ]
             ^
             | 发送开始
             
             (经过漫长的物理延迟...)
             
RX (回读):               [  BIT N  ] [ BIT N+1 ]
                         ^         ^
                         |         |
普通SP (80%): -----------+ (T=160ns)
             在RX上读到的是"空"或者旧数据 -> 报错!
             
开启 TDC 后:
1. 测量到延迟 = 200ns。
2. 加上 TDCO (比如 100ns,即半个位宽)。
3. SSP = 200 + 100 = 300ns。
 
SSP 位置:    ----------------+ (T=300ns)
                            |
                            正好读到 RX 上 BIT N 的中间! -> 校验通过!

4. 关键参数详解

在 Linux 或芯片手册配置 TDC 时,你会遇到这几个概念:

  1. TDCV (TDC Value):

    • 含义: 实时测量到的环路延迟值。
    • 来源: 硬件自动测量,每一帧都可能微调。
    • 作用: 基准值。
  2. TDCO (TDC Offset):

    • 含义: 补偿偏移量。这是你需要配置的核心参数。
    • 推荐值: 通常设置为数据段位时间(1 Data_Bit_Time)的一半,也就是让 SSP 对齐到回读位的 50% 处。
    • 例如:5Mbps,位宽 200ns,TDCO 设为 100ns (对应的 Tq 数)。
  3. TDCF (TDC Filter / Window):

    • 某些控制器有这个参数。因为 SSP 可能跑得很远,如果 SSP 还没发生,新的 Glitch 来了怎么办?
    • 这是一个窗口机制,用来忽略 SSP 窗口之外的干扰。

5. 关于 TDC 的三个灵魂拷问

Q1: 接收节点(Receiver)需要 TDC 吗?

不需要。

  • 接收节点不需要“回读自己发的东西”。
  • 接收节点只需要紧跟 Rx 引脚的跳变沿,利用 Phase_Seg 调整同步即可。TDC 是专门给发送节点用来解决“我发出的和我读回来的有时差”这个问题的。

Q2: 为什么仲裁域(低速)不用 TDC?

  • 因为仲裁域必须保证全网逻辑同步。每个节点必须在同一时刻(SP)看到相同的逻辑状态才能决定谁赢谁输。
  • 如果用了 TDC(延迟采样),那就意味着“先斩后奏”,仲裁机制就失效了。
  • 所以: 仲裁域靠 Prop_Seg 硬扛物理延迟,限制了波特率;数据域靠 TDC 绕过物理延迟,解放了波特率。

Q3: 我的 TDC 参数配错了会怎样?

  • TDCO 太小: SSP 落在信号边缘的抖动区,导致发送方误报 Bit Error,丢包。
  • TDCO 太大: SSP 跑太远,甚至采到了下一位甚至下下位的电平,导致 Bit Error。
  • 通常表现: ifconfigip -d link show 中看到 berr-counter tx 疯狂增加,总线处于 ERROR-PASSIVEBUS-OFF 状态。

总结

  • TDC 是什么: 是 CAN FD 高速数据阶段,发送方为了解决“发快读慢”的时差问题,引入的第二采样点技术
  • 核心动作: 测量延迟 (TDCV) + 加上偏移 (TDCO) = 在延迟的时刻 (SSP) 检查自己发的数据对不对。
  • 一句话记忆: 经典 CAN 靠 Prop_Seg 回音;CAN FD 靠 TDC 回音。