欢迎光临
我们一直在努力

05-J1939-22 的 FD Transport Protocol 与 J1939-21/22 选型对比

J1939 系列 05|J1939-22 的 FD Transport Protocol 与 J1939-21/22 选型对比

如果说 Multi-PG 是 J1939-22 在“小消息高效聚合”方向上的代表设计,那么 FD Transport Protocol,也就是 FD.TP,就是 J1939-22 在“大消息传输”方向上的核心升级。上一页更像在讲怎么拼车,这一页则是在讲:拼不下了,别硬塞,老老实实走物流通道。

在 J1939-21 里,经典 TP 的逻辑大家都比较熟:

  • BAM
  • RTS/CTS
  • TP.CM
  • TP.DT
  • 每包 7 字节

到了 J1939-22,这些思想没有消失,但实现方式已经明显升级了:

  • 数据段从 7 字节提升到 60 字节
  • 引入 Session Number
  • 结束阶段拆成 EOMS 和 EOMA
  • Assurance Data 可以在会话结束阶段承载
  • 并发能力大幅增强

这一篇就专门把 FD.TP 讲透。

一、先回答一个根本问题:什么时候必须进入 FD.TP

很多人会下意识觉得:

  • J1939-22 不是都到 64 字节了吗
  • 那是不是只有“超过 64 字节”才需要传输协议

这个理解不对。64 这个数字很醒目,但它不是万能通行证,更不是“只要没超过 64 就肯定能单帧搞定”的免死金牌。

FD.TP 的判定边界不是单纯看 PG data 长度,而是看:

  • PG data + assurance data 的组合长度

只要这个组合长度 超过 60 字节,就已经不能再做成一个 C-PG,必须进入 FD.TP。

这也是为什么标准里会出现一种看起来有点反直觉的情况:

  • 某个 PG 的业务数据本身只有 53 bytes
  • 但如果再加上 8 bytes assurance data,总共 61 bytes
  • 这时虽然 PG data 没超过 60,仍然必须走 FD.TP
  • 最终只会有 1 个 FD.TP.DT 段,而 assurance data 则放在 EOMS 里

把这个发送决策画成图,会非常清楚:

#mermaid-svg-94sVtZ61wZ9vnbs6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-94sVtZ61wZ9vnbs6 .error-icon{fill:#552222;}#mermaid-svg-94sVtZ61wZ9vnbs6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-94sVtZ61wZ9vnbs6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .marker.cross{stroke:#333333;}#mermaid-svg-94sVtZ61wZ9vnbs6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-94sVtZ61wZ9vnbs6 p{margin:0;}#mermaid-svg-94sVtZ61wZ9vnbs6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster-label text{fill:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster-label span{color:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster-label span p{background-color:transparent;}#mermaid-svg-94sVtZ61wZ9vnbs6 .label text,#mermaid-svg-94sVtZ61wZ9vnbs6 span{fill:#333;color:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .node rect,#mermaid-svg-94sVtZ61wZ9vnbs6 .node circle,#mermaid-svg-94sVtZ61wZ9vnbs6 .node ellipse,#mermaid-svg-94sVtZ61wZ9vnbs6 .node polygon,#mermaid-svg-94sVtZ61wZ9vnbs6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .rough-node .label text,#mermaid-svg-94sVtZ61wZ9vnbs6 .node .label text,#mermaid-svg-94sVtZ61wZ9vnbs6 .image-shape .label,#mermaid-svg-94sVtZ61wZ9vnbs6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-94sVtZ61wZ9vnbs6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .rough-node .label,#mermaid-svg-94sVtZ61wZ9vnbs6 .node .label,#mermaid-svg-94sVtZ61wZ9vnbs6 .image-shape .label,#mermaid-svg-94sVtZ61wZ9vnbs6 .icon-shape .label{text-align:center;}#mermaid-svg-94sVtZ61wZ9vnbs6 .node.clickable{cursor:pointer;}#mermaid-svg-94sVtZ61wZ9vnbs6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .arrowheadPath{fill:#333333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-94sVtZ61wZ9vnbs6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-94sVtZ61wZ9vnbs6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-94sVtZ61wZ9vnbs6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster text{fill:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 .cluster span{color:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-94sVtZ61wZ9vnbs6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-94sVtZ61wZ9vnbs6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-94sVtZ61wZ9vnbs6 .icon-shape,#mermaid-svg-94sVtZ61wZ9vnbs6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-94sVtZ61wZ9vnbs6 .icon-shape p,#mermaid-svg-94sVtZ61wZ9vnbs6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-94sVtZ61wZ9vnbs6 .icon-shape rect,#mermaid-svg-94sVtZ61wZ9vnbs6 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-94sVtZ61wZ9vnbs6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-94sVtZ61wZ9vnbs6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-94sVtZ61wZ9vnbs6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

A_PDU

PG data + assurance data <= 60

构造成 C-PG

地址语义和打包规则允许吗

进入 Multi-PG

进入 FD.TP

PDU1 且发往特定 DA

RTS/CTS

BAM

所以,FD.TP 的本质不是“超过 64 字节才用”,而是“一旦超出 C-PG 能力边界,就由 FD.TP 接管”。别被那个 64 字节表面数字骗了,真正卡你的往往是 C-PG 那条 60 字节红线。

在这里插入图片描述

二、FD.TP 由哪两个 PG 组成

J1939-22 定义了新的两个核心 PG:

  • FD.TP.CM:PGN = 0x004D00
  • FD.TP.DT:PGN = 0x004E00

它们的职责划分非常明确:

  • FD.TP.CM 负责建连、流控、结束、Abort
  • FD.TP.DT 负责真正的数据段传输

2.1 FD.TP.CM 的公共框架

FD.TP.CM 的标准长度是 12 bytes,只有 EOMS 在带 assurance data 时可以扩展到最多 64 bytes。

它的公共字段可以先记成这样:

字段位置含义
Control Type Byte1 低 4 bit 当前是哪种控制消息
Session Number Byte1 高 4 bit 会话编号
Bytes 2..4 3 bytes 总字节数或保留
Bytes 5..7 3 bytes 总段数、下一段号或保留
Byte 8 1 byte 最大段数、允许段数、AD size 或 role
Byte 9 1 byte AD type、request code 或 abort reason
Bytes 10..12 3 bytes 目标 PGN
Bytes 13..64 可选 Assurance Data,仅 EOMS 使用

也就是说,FD.TP.CM 虽然有很多消息类型,但骨架其实是一致的。

2.2 FD.TP.DT 的公共框架

FD.TP.DT 的数据场结构更直接:

字段位置含义
DTFI Byte1 低 4 bit Data Transfer Format Indicator,目前标准值为 0
Session Number Byte1 高 4 bit 会话编号
Segment Number Bytes2…4 3 字节段号
Segment Data Bytes5…64 最多 60 字节 PG data

这和 J1939-21 的 TP.DT 对比很强烈:

  • -21:1 字节包号 + 7 字节数据
  • -22:4 字节控制头 + 60 字节数据

三、FD.TP.CM 里有哪些控制消息

FD.TP.CM 主要有六类控制消息:

控制类型值发送方作用
RTS 0 发送方 发起 destination-specific 会话
CTS 1 接收方 控制流量、暂停、请求重发
EOMS 2 发送方 告知所有段已发完,并带可选 assurance data
EOMA 3 接收方 确认整条消息已正确接收
BAM 4 发送方 发起广播式 FD.TP 会话
Abort 15 任一方 关闭或拒绝会话

如果只想先抓主线,可以这么记:

  • RTS/CTS 负责“开始并控制会话”
  • DT 负责“搬运分段数据”
  • EOMS/EOMA 负责“完成和闭环”
  • Abort 负责“中止”

四、Session Number 为什么是 FD.TP 的关键

4.1 它让会话不再只能靠隐式上下文去猜

在 J1939-21 里,TP.DT 没有显式会话号,因此接收方通常要靠:

  • SA
  • DA
  • 当前上下文

去推断一串 TP.DT 属于哪个会话。

在 J1939-22 里,标准明确要求用:

  • SA
  • DA
  • Session Number

来唯一关联一条 FD.TP 会话。你也可以把它理解成:每条长报文终于有了自己的号码牌,不用再靠“我大概记得刚才是谁在说话”这种模糊印象去猜。

可以直接把连接键写成:

FD.TP Session Key = (Source Address, Destination Address, Session Number)

4.2 它带来的能力提升是什么

这件事会直接带来几种改观:

  • 同一对节点之间可以并发多条长报文会话
  • 同一个发送方可以同时跑多个 BAM 会话
  • Abort 也能更明确地指向某一个会话

标准允许的上限是:

  • 每个源地址到同一目标地址,最多 8 个 RTS/CTS 会话
  • 每个源地址最多 4 个 BAM 会话

同时还有会话号使用范围约束:

  • BAM 只用 0..3
  • RTS/CTS 只用 0..7
  • 8..15 预留

五、FD.TP 的段为什么是 60 字节

FD.TP.DT 的数据场最多 64 字节,但前 4 字节要拿来放:

  • DTFI
  • Session
  • Segment Number

所以真正能装 PG data 的就是:

  • 60 bytes

这就形成了 FD.TP 最核心的传输单位:

  • 一个 FD.TP.DT = 最多 60 bytes PG data

段号范围也明显大得多:

  • BAM:最多 255 段
  • RTS/CTS:最多 279621 段

相比 J1939-21 的 255 x 7 = 1785 bytes,J1939-22 的容量和效率都已经是另一档了。

六、RTS/CTS:FD.TP 的点对点传输长什么样

6.1 一条正常会话的主流程

FD.TP 的 RTS/CTS 主流程可以先看成这样:

接收方发送方接收方发送方#mermaid-svg-kd6UNGxCj2AomY6p{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kd6UNGxCj2AomY6p .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kd6UNGxCj2AomY6p .error-icon{fill:#552222;}#mermaid-svg-kd6UNGxCj2AomY6p .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kd6UNGxCj2AomY6p .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kd6UNGxCj2AomY6p .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kd6UNGxCj2AomY6p .marker.cross{stroke:#333333;}#mermaid-svg-kd6UNGxCj2AomY6p svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kd6UNGxCj2AomY6p p{margin:0;}#mermaid-svg-kd6UNGxCj2AomY6p .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kd6UNGxCj2AomY6p text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kd6UNGxCj2AomY6p .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kd6UNGxCj2AomY6p .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kd6UNGxCj2AomY6p .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kd6UNGxCj2AomY6p .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kd6UNGxCj2AomY6p #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kd6UNGxCj2AomY6p .sequenceNumber{fill:white;}#mermaid-svg-kd6UNGxCj2AomY6p #sequencenumber{fill:#333;}#mermaid-svg-kd6UNGxCj2AomY6p #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kd6UNGxCj2AomY6p .messageText{fill:#333;stroke:none;}#mermaid-svg-kd6UNGxCj2AomY6p .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kd6UNGxCj2AomY6p .labelText,#mermaid-svg-kd6UNGxCj2AomY6p .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kd6UNGxCj2AomY6p .loopText,#mermaid-svg-kd6UNGxCj2AomY6p .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kd6UNGxCj2AomY6p .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kd6UNGxCj2AomY6p .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kd6UNGxCj2AomY6p .noteText,#mermaid-svg-kd6UNGxCj2AomY6p .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kd6UNGxCj2AomY6p .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kd6UNGxCj2AomY6p .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kd6UNGxCj2AomY6p .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kd6UNGxCj2AomY6p .actorPopupMenu{position:absolute;}#mermaid-svg-kd6UNGxCj2AomY6p .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kd6UNGxCj2AomY6p .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kd6UNGxCj2AomY6p .actor-man circle,#mermaid-svg-kd6UNGxCj2AomY6p line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kd6UNGxCj2AomY6p :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}loop[当前窗口内的 segments]loop[下一窗口内的 segments]FD.TP.CM_RTS(session, total bytes, total segs, max segs, ADT, PGN)FD.TP.CM_CTS(session, next seg, xfr segs, rqst=0)FD.TP.DT(session, segment number, 60-byte data)FD.TP.CM_CTS(session, next seg, xfr segs, rqst=0)FD.TP.DT(session, segment number, 60-byte data)FD.TP.CM_EOMS(session, total bytes, total segs, AD size, AD type, PGN)FD.TP.CM_EOMA(session, total bytes received, total segs received, PGN)

这和 J1939-21 的主流程很像,但有三个明显不同:

  • 会话里有 Session Number
  • 数据段单位变成 60 字节
  • 结束阶段拆成 EOMS -> EOMA

6.2 RTS 的关键字段

RTS 至少会告诉接收方:

  • 这条大消息的总字节数
  • 总共会分成多少段
  • 每条 CTS 最多允许请求多少段
  • assurance data 将来会按什么类型提供
  • 当前使用哪个 Session
  • 被传输的目标 PGN

其中最容易被忽略的是 Maximum Number of Segments:

  • 它是发送方给接收方设的上限
  • 接收方后面所有 CTS 的 xfr segs 都不能超过这个值

6.3 CTS 在 FD.TP 里更像一个控制面板

CTS 在 FD.TP 里不只是“继续发”,它至少同时承担四个角色:

  • 流控:本轮允许发多少段
  • 续传:下一段从哪一个段号开始
  • 暂停:用 xfr segs = 0 保持连接但先别发
  • 请求重发 EOMS:用 rqst = 1

把 CTS 的关键字段拆开看,会更清楚:

字段作用
Session 指明属于哪个会话
Next Segment Number 本轮从哪一段开始发
Number of Segments to Send 本轮最多发多少段
Request Code 是否要求重发 EOMS
PGN 当前被传输的是哪个 PG

6.4 Request Code 是 FD.TP 比 J1939-21 多出来的一个细节

在 FD.TP 里,CTS 还多了一个 Request Code 字段。

最重要的标准用法是:

  • rqst = 0:普通 CTS
  • rqst = 1:请求发送方重发 EOMS

当接收方已经收到了所有 FD.TP.DT 段,但没正确收到 EOMS 时,它可以这样做。这个细节很有意思,因为它说明 FD.TP 连“最后那张签收单没收到”都单独留了补救动作:

  • 发一条 CTS
  • rqst = 1
  • next segment number = FFFFFFh
  • xfr segs 这个字段此时会被发送方忽略

这件事很有代表性,因为它说明 FD.TP 的控制面比 J1939-21 更细。

6.5 发送方在窗口之间怎么走

FD.TP 的发送方逻辑其实和你前面问到的 J1939-21 CTS=10 那个问题是一脉相承的,只是现在从“包”变成了“段”。

#mermaid-svg-FcZP4w3SHxlChSEb{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FcZP4w3SHxlChSEb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FcZP4w3SHxlChSEb .error-icon{fill:#552222;}#mermaid-svg-FcZP4w3SHxlChSEb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FcZP4w3SHxlChSEb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FcZP4w3SHxlChSEb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FcZP4w3SHxlChSEb .marker.cross{stroke:#333333;}#mermaid-svg-FcZP4w3SHxlChSEb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FcZP4w3SHxlChSEb p{margin:0;}#mermaid-svg-FcZP4w3SHxlChSEb .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-FcZP4w3SHxlChSEb .cluster-label text{fill:#333;}#mermaid-svg-FcZP4w3SHxlChSEb .cluster-label span{color:#333;}#mermaid-svg-FcZP4w3SHxlChSEb .cluster-label span p{background-color:transparent;}#mermaid-svg-FcZP4w3SHxlChSEb .label text,#mermaid-svg-FcZP4w3SHxlChSEb span{fill:#333;color:#333;}#mermaid-svg-FcZP4w3SHxlChSEb .node rect,#mermaid-svg-FcZP4w3SHxlChSEb .node circle,#mermaid-svg-FcZP4w3SHxlChSEb .node ellipse,#mermaid-svg-FcZP4w3SHxlChSEb .node polygon,#mermaid-svg-FcZP4w3SHxlChSEb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FcZP4w3SHxlChSEb .rough-node .label text,#mermaid-svg-FcZP4w3SHxlChSEb .node .label text,#mermaid-svg-FcZP4w3SHxlChSEb .image-shape .label,#mermaid-svg-FcZP4w3SHxlChSEb .icon-shape .label{text-anchor:middle;}#mermaid-svg-FcZP4w3SHxlChSEb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FcZP4w3SHxlChSEb .rough-node .label,#mermaid-svg-FcZP4w3SHxlChSEb .node .label,#mermaid-svg-FcZP4w3SHxlChSEb .image-shape .label,#mermaid-svg-FcZP4w3SHxlChSEb .icon-shape .label{text-align:center;}#mermaid-svg-FcZP4w3SHxlChSEb .node.clickable{cursor:pointer;}#mermaid-svg-FcZP4w3SHxlChSEb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FcZP4w3SHxlChSEb .arrowheadPath{fill:#333333;}#mermaid-svg-FcZP4w3SHxlChSEb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FcZP4w3SHxlChSEb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FcZP4w3SHxlChSEb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FcZP4w3SHxlChSEb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FcZP4w3SHxlChSEb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FcZP4w3SHxlChSEb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FcZP4w3SHxlChSEb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FcZP4w3SHxlChSEb .cluster text{fill:#333;}#mermaid-svg-FcZP4w3SHxlChSEb .cluster span{color:#333;}#mermaid-svg-FcZP4w3SHxlChSEb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FcZP4w3SHxlChSEb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FcZP4w3SHxlChSEb rect.text{fill:none;stroke-width:0;}#mermaid-svg-FcZP4w3SHxlChSEb .icon-shape,#mermaid-svg-FcZP4w3SHxlChSEb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FcZP4w3SHxlChSEb .icon-shape p,#mermaid-svg-FcZP4w3SHxlChSEb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FcZP4w3SHxlChSEb .icon-shape rect,#mermaid-svg-FcZP4w3SHxlChSEb .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FcZP4w3SHxlChSEb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FcZP4w3SHxlChSEb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FcZP4w3SHxlChSEb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

否且超时

收到 CTS

rqst 是否为 1

重发 EOMS

等待 CTS 或 EOMA

xfr segs 是否为 0

暂停发送并保持连接

等待下一条 CTS

按 next segment 和 xfr segs 发送本轮 FD.TP.DT

是否已发完最后一段

发送 EOMS

等待 EOMA 或新的 CTS

等待是否超时

发送 Abort

是否收到 EOMA

连接正常结束

这张图里最关键的判断有两个:

  • 一次 CTS 只授权一轮段发送
  • 发完最后一段并不代表连接结束,发送方还必须进入 EOMS -> EOMA 闭环

七、BAM:FD.TP 的广播大报文路径

FD.TP 的 BAM 和 RTS/CTS 在“发段”这件事上相似,但在连接控制上差别很大。

7.1 BAM 主流程

接收节点发送方接收节点发送方#mermaid-svg-YIf7VAmKkPw9EzlU{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YIf7VAmKkPw9EzlU .error-icon{fill:#552222;}#mermaid-svg-YIf7VAmKkPw9EzlU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YIf7VAmKkPw9EzlU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YIf7VAmKkPw9EzlU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YIf7VAmKkPw9EzlU .marker.cross{stroke:#333333;}#mermaid-svg-YIf7VAmKkPw9EzlU svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YIf7VAmKkPw9EzlU p{margin:0;}#mermaid-svg-YIf7VAmKkPw9EzlU .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YIf7VAmKkPw9EzlU text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-YIf7VAmKkPw9EzlU .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-YIf7VAmKkPw9EzlU .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-YIf7VAmKkPw9EzlU #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-YIf7VAmKkPw9EzlU .sequenceNumber{fill:white;}#mermaid-svg-YIf7VAmKkPw9EzlU #sequencenumber{fill:#333;}#mermaid-svg-YIf7VAmKkPw9EzlU #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-YIf7VAmKkPw9EzlU .messageText{fill:#333;stroke:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YIf7VAmKkPw9EzlU .labelText,#mermaid-svg-YIf7VAmKkPw9EzlU .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .loopText,#mermaid-svg-YIf7VAmKkPw9EzlU .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-YIf7VAmKkPw9EzlU .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-YIf7VAmKkPw9EzlU .noteText,#mermaid-svg-YIf7VAmKkPw9EzlU .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-YIf7VAmKkPw9EzlU .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YIf7VAmKkPw9EzlU .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YIf7VAmKkPw9EzlU .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-YIf7VAmKkPw9EzlU .actorPopupMenu{position:absolute;}#mermaid-svg-YIf7VAmKkPw9EzlU .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-YIf7VAmKkPw9EzlU .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-YIf7VAmKkPw9EzlU .actor-man circle,#mermaid-svg-YIf7VAmKkPw9EzlU line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-YIf7VAmKkPw9EzlU :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}loop[每 10..200 ms]无 CTS,无 EOMA,节点自行完成校验和重组FD.TP.CM_BAM(session, total bytes, total segs, ADT, PGN)FD.TP.DT(session, segment number, data)FD.TP.CM_EOMS(session, total bytes, total segs, AD size, AD type, PGN)

7.2 BAM 的几个核心特点

  • 只能发给全局地址
  • 适用于 PDU2,以及发往全局地址的 PDU1
  • 没有接收方流控
  • 接收方不能对 BAM 主动 Abort
  • 发送方在结束时仍然要发 EOMS

这一点和 J1939-21 BAM 有点像,但 -22 把结束阶段也明确化了:

  • 不是“最后一段发完就算结束”
  • 而是“最后一段发完,再发 EOMS 才算会话结束”

八、EOMS 和 EOMA:为什么结束阶段被重新设计

8.1 EOMS 不是一句“我发完了”

EOMS 至少带这些内容:

  • 总字节数
  • 总段数
  • AD Size
  • AD Type
  • 目标 PGN
  • 可选 assurance data

所以它的真实含义更接近:

  • “我这条长消息已经全部发完了”
  • “这是这次完整消息对应的结束状态”
  • “如果有 end-to-end assurance data,也一并在这里给你”

8.2 EOMA 是接收方的正式闭环

EOMA 则是接收方对整条消息的最终确认。一个负责说“我发完了”,另一个负责说“我核完了,确实都收到了”:

  • 已经收到并重组成功
  • 收到的总字节数和总段数是多少
  • 这个会话可以明确关闭了

8.3 它和 J1939-21 的差别

对比经典 EndOfMsgACK,FD.TP 把结束逻辑拆得更清楚:

  • 发送方:EOMS
  • 接收方:EOMA

这样做有两个好处:

  • 把 assurance data 放到完整消息结束状态里统一处理
  • 让“数据发完”和“接收方确认整个会话结束”这两件事分开表达

九、超时、约束和边界值需要单独记一下

9.1 默认超时

参数默认值含义
Tr 200 ms 最大响应时间
Th 500 ms hold 状态下连续 CTS(0,…) 的最大发送间隔
T1 750 ms Transport Segment Interval
T2 1250 ms 接收方在发出 CTS 后等待下一个 DT 的超时
T3 1250 ms 发送方等待下一条 CTS 的超时
T4 1050 ms 发送方在 hold 状态下等待下一条 CTS 的超时
T5 3000 ms 发送方在发出 EOMS 后等待 EOMA 的超时

9.2 容量上限

项目BAMRTS/CTS
最大 PG data 字节数 15300 16777215
最大段号 255 279621
每段数据长度 60 bytes 60 bytes
段间隔 10..200 ms 0..200 ms

9.3 一些容易漏掉的边界

  • DTFI 目前标准值应为 0
  • Segment Number 不能为 0
  • EOMA 如果在最后一个 DT 发完之前就到达,发送方应忽略
  • Abort 收到后,发送方停止继续发该会话的数据和控制消息
  • 同一 PG 可能有时走 Multi-PG,有时走 FD.TP,系统设计上要避免旧数据晚到新数据之后

十、J1939-21 与 J1939-22,工程上怎么选

10.1 继续用 J1939-21 的典型场景

如果你的网络:

  • 大量设备仍是传统 J1939 设备
  • 单帧消息占主流
  • 大报文并不多
  • 更看重兼容性和复杂度可控

那么 -21 依然是非常合理的选择。

10.2 适合转向 J1939-22 的典型场景

如果你的系统:

  • 硬件已经支持 CAN FD
  • 有很多大对象或高频数据
  • 想通过 Multi-PG 提高总线利用率
  • 需要更多并发长报文会话
  • 未来要接功能安全或网络安全机制

那么 -22 的长期价值会明显更高。

在这里插入图片描述

10.3 把差异压成一张对照表

维度J1939-21J1939-22
单帧有效数据能力 <= 8 bytes <= 64 bytes
聚合机制 Multi-PG
大报文段大小 7 bytes 60 bytes
会话标识 无显式 session Session Number
结束阶段 EndOfMsgACK EOMS + EOMA
并发能力 很有限 明显增强
assurance data 无标准入口 标准已预留承载位置

十一、小结

如果用一句话概括 FD.TP 的意义,那就是:

它把 J1939 的大消息传输,从经典 CAN 时代的“补丁式能力”,提升成了 CAN FD 时代的“正式连接管理服务”。

而把 J1939-21 和 J1939-22 放在一起看,最重要的结论也很清楚:

  • -21 是经典 CAN 时代的成熟工程化方案
  • -22 是面向 CAN FD、并发、多消息聚合和 assurance 扩展的数据链路重构版

如果前一篇的 Multi-PG 解决的是“怎样把小消息更高效地装进一个 FD 帧”,那么这一篇的 FD.TP 解决的就是“当消息已经大到无法再靠 C-PG 承载时,怎样把整条大消息稳妥地送到对端”。一个负责拼车省路费,一个负责走正规物流别把货弄丢。

赞(0)
未经允许不得转载:171主机测评 » 05-J1939-22 的 FD Transport Protocol 与 J1939-21/22 选型对比
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址