上一篇文章,我们从 EtherCAT 的 INIT、PREOP、SAFEOP、OP 四个状态出发,进一步进入了 IgH EtherCAT Master 的状态机体系。
我们看到,一个 EtherCAT 从站从“被发现”到“进入 OP”,并不是简单修改几个寄存器,而是由 Master FSM、Slave FSM、SII、PDO、CoE、Slave Configuration 等多个状态机共同完成。
但到这里还有一个更关键的问题没有回答:
这些状态机到底是怎么和 EtherCAT 从站真正通信的?
例如:
Master FSM 怎么读取从站状态?
SII FSM 怎么读取从站信息?
PDO FSM 怎么配置 PDO?
CoE FSM 怎么发送 SDO?
应用程序每 1 ms 更新一次的过程数据,又是怎么真正发到伺服驱动器的?
一个 EtherCAT 控制周期里面到底经过了多少层?
为什么 EtherCAT 不需要像传统 TCP/IP 通信那样,为每个设备单独建立一次通信?
IgH 中的
Datagram到底是什么?Working Counter又为什么如此重要?
这些问题最终都会汇聚到一个非常核心的数据结构:
EtherCAT Datagram。
如果把 IgH EtherCAT Master 比作一个工业控制系统中的“交通调度中心”,那么状态机负责决定“要做什么”,Domain 负责组织“实时数据是什么”,而 Datagram 则负责把这些操作真正变成可以在 EtherCAT 网络上传输的数据。
从 IgH 1.6 的源码来看,datagram.c、datagram.h专门负责 EtherCAT Datagram;而master.c中则负责将队列中的 Datagram 组织进 EtherCAT Frame、发送到网卡,并在收到 Frame 后重新解析其中的 Datagram 和 Working Counter。官方源码可以直接看到这一发送与接收路径。
所以,如果上一篇解决的是:
EtherCAT 主站如何把从站“启动起来”?
那么这一篇要解决的就是:
EtherCAT 主站启动之后,数据究竟是怎么跑起来的?
一、先搞清楚:EtherCAT Frame、Datagram 和普通网络数据包有什么区别?
第一次学习 EtherCAT 时,最容易混淆的三个概念就是:
Ethernet Frame EtherCAT Datagram Process Data三者并不是同一个东西。
可以先建立这样一个关系:
┌────────────────────────────────────┐ │ Ethernet Frame │ │ │ │ ┌────────────────────────────┐ │ │ │ EtherCAT Datagram │ │ │ │ │ │ │ │ Header + Data + WKC │ │ │ └────────────────────────────┘ │ │ │ │ ┌────────────────────────────┐ │ │ │ EtherCAT Datagram │ │ │ │ │ │ │ └────────────────────────────┘ │ │ │ └────────────────────────────────────┘也就是说:
一个 EtherCAT Frame 可以承载一个或多个 EtherCAT Datagram。
这也是 IgH Master 中一个非常重要的设计。
在master.c的发送代码中,可以看到 IgH 会遍历待发送的 Datagram,把每个 Datagram 的:
type index address data_size data写入 Frame,然后最终形成完整的 EtherCAT Frame。源码同时在 Frame 末尾处理填充,并调用设备发送函数将其交给网卡驱动。
所以从软件结构来看,可以把数据通路理解成:
Application │ ▼ Domain / FSM │ ▼ Datagram │ ▼ EtherCAT Frame │ ▼ NIC Driver │ ▼ Ethernet PHY │ ▼ EtherCAT Network这和传统网络程序中:
Application ↓ Socket ↓ TCP/UDP ↓ IP ↓ Ethernet是完全不同的组织方式。
二、什么是 Datagram?
在 IgH 中,Datagram 可以理解成:
一次 EtherCAT 通信操作的基本封装单位。
例如主站想做一件事情:
读取某个从站的某个寄存器那么就可以形成一个 Datagram。
如果想:
向某个从站写寄存器也可以形成 Datagram。
如果想:
读取一组过程数据同样可以通过 Datagram 完成。
所以,Datagram 并不等于“某一个固定的数据”。
它更像是一张:
“我要对 EtherCAT 总线做什么操作”的工作单。
1. Datagram 里面有什么?
从 IgH 的源码结构来看,ec_datagram_t包含多个关键字段,其中就包括:
type index address data data_size working_counter state官方文档也将working_counter定义为 Datagram 的 Working Counter。
可以抽象成:
┌──────────────────────────────┐ │ EtherCAT Datagram │ ├──────────────────────────────┤ │ Type │ ├──────────────────────────────┤ │ Index │ ├──────────────────────────────┤ │ Address │ ├──────────────────────────────┤ │ Data Size │ ├──────────────────────────────┤ │ Data │ ├──────────────────────────────┤ │ Working Counter │ └──────────────────────────────┘其中几个字段尤其值得关注。
Type
表示:
这次 Datagram 想执行什么类型的 EtherCAT 操作。
例如源码中可以看到:
APWR FPWR BWR LWR等不同操作类型。
这些访问方式对应不同的寻址和读写语义。
因此,Datagram 并不是简单的:
地址 + 数据而是:
操作类型 + 地址 + 数据Index
Index 可以帮助主站在多个 Datagram 同时运行时识别不同 Datagram。
这对于异步处理尤其重要。
例如:
Datagram #1 Datagram #2 Datagram #3即使它们最终被封装在一个 Frame 里,主站收到返回数据之后仍然需要知道:
这个返回结果属于哪个 Datagram?因此 Index 是数据处理链路中的重要标识。
Address
Address 就是:
这一次操作最终针对 EtherCAT 网络中的什么地址。
这也是 EtherCAT 地址访问机制的重要部分。
EtherCAT 并不是简单使用:
IP 地址 MAC 地址来定位一个从站寄存器。
它拥有自己的地址访问方式。
后续在学习:
Auto Increment Address Configured Station Address Logical Address时,这个概念会进一步展开。
Data
Data 就是真正需要发送或者接收的数据。
例如:
寄存器值 状态信息 PDO 数据 SDO / Mailbox 数据 配置参数等等。
Working Counter
这个字段非常关键。
它不是简单的:
发送成功 = 1 发送失败 = 0而是用于反映:
EtherCAT 从站对 Datagram 的处理情况。
后面我们会专门解释为什么 EtherCAT 可以通过 WKC 判断:
过程数据到底有没有被正确处理三、EtherCAT 为什么需要 Working Counter?
这是理解 EtherCAT 实时性的关键概念之一。
传统网络通信中,我们可能习惯:
发送 ↓ 收到 ACK ↓ 判断成功但工业控制场景需要的信息更加具体:
这一次过程数据交换,到底有多少设备真正参与了?
假设总线上有:
Slave 1 Slave 2 Slave 3 Slave 4主站周期性发送一个过程数据 Datagram。
EtherCAT 从站在处理这个 Datagram 的过程中,会根据操作类型对 Working Counter 进行相应处理。
最终主站可以从返回 Datagram 中读取:
Working Counter然后判断这次数据交换是否符合预期。
在 IgH 中,ecrt_domain_process()会评估收到的过程数据 Datagram 的 Working Counter,并据此更新 Domain 状态;官方 API 将 Domain 的 WKC 状态定义为:
EC_WC_ZERO EC_WC_INCOMPLETE EC_WC_COMPLETE分别表示没有注册的过程数据被交换、部分过程数据完成交换,以及全部注册过程数据完成交换。
这非常重要。
因为对于一个实时控制系统来说:
“网卡收到了一个 Frame”并不等于:
“这次过程数据交换成功了”真正需要关注的是:
Frame ↓ Datagram ↓ Working Counter ↓ Domain State ↓ Application四、为什么 EtherCAT 不需要给每一个从站发送一个独立 Frame?
这正是 EtherCAT 和普通工业以太网应用模式之间非常重要的区别。
假设有:
1 个 Master 8 个 Servo 4 个 IO 2 个 Encoder如果按照传统“一个设备一个请求”的方式进行通信,那么一个控制周期可能需要:
Frame 1 → Servo 1 Frame 2 → Servo 2 Frame 3 → Servo 3 ... Frame 14 → Encoder这样做当然可以通信。
但控制周期越短,通信效率和调度开销就越值得关注。
EtherCAT 的设计思路则完全不同。
可以把它简化理解为:
Master │ ▼ ┌───────────────────────────────┐ │ EtherCAT Frame │ │ │ │ Datagram / Process Data │ └───────────────────────────────┘ │ ▼ Slave 1 → 读取/写入属于自己的数据 │ ▼ Slave 2 → 读取/写入属于自己的数据 │ ▼ Slave 3 → 读取/写入属于自己的数据 │ ▼ Slave 4 → 读取/写入属于自己的数据 │ ▼ Master这里的关键不是“把所有设备的数据简单拼在一起”。
而是:
EtherCAT 从站可以在 Frame 经过时直接处理其中与自己相关的数据。
因此,数据并不需要:
Master → Slave 1 等待 Master → Slave 2 等待 Master → Slave 3 等待而可以在一个连续的通信过程中被多个从站处理。
这正是 EtherCAT 高效通信机制的重要基础。
五、EtherCAT 的“实时”到底来自哪里?
说到这里,就必须纠正一个非常常见的误解:
“EtherCAT 实时,是因为它用了以太网。”
或者:
“EtherCAT 实时,是因为它用了 Datagram。”
这两种说法都不准确。
EtherCAT 的确定性来自多个机制共同作用。
可以把它拆成几个层次。
第一层:通信协议设计
EtherCAT 并不是把传统 TCP/IP 直接用于运动控制。
它采用专门针对工业实时通信设计的机制,使得从站能够对经过的 Frame 进行硬件级、链路级的数据处理。
这减少了传统网络协议栈中大量不必要的处理路径。
第二层:Frame 中的数据组织方式
一个 EtherCAT Frame 可以包含多个 Datagram。
这样可以把多个通信操作组织到较少数量的 Ethernet Frame 中。
IgH 的ec_master_send_datagrams()就负责将队列中的 Datagram 组织进待发送的 EtherCAT Frame。官方源码可以看到,IgH 会依次写入 Datagram Header、Data 和 Footer,然后构造 EtherCAT Frame Header,最后调用设备发送函数。
第三层:从站在线处理
EtherCAT 从站不是收到完整数据以后,再像普通网络设备一样交给一个复杂协议栈慢慢处理。
其设计允许从站在 Frame 经过时完成相应的数据处理。
因此通信链路本身非常适合:
周期性 固定数据 多节点 确定性这也是为什么 EtherCAT 特别适合:
运动控制 伺服 机器人 数控 高速 IO 同步采集等场景。
第四层:Working Counter
WKC 又进一步提供了一种:
“这次通信是否真正完成”的反馈机制。
这对于实时控制非常重要。
因为控制系统需要知道:
这一周期的数据到底有没有到?而不是只知道:
这一周期我调用 send() 了。第五层:控制器和操作系统
这里尤其容易被忽略。
EtherCAT 本身提供了高确定性的通信机制,但最终系统的周期性执行仍然依赖:
CPU IRQ NIC Driver Scheduler Task Memory Application等多个因素。
EtherLab 官方文档在讨论实时周期时也明确指出,EtherCAT Frame 必须在下一次实时周期开始之前完成发送和接收;如果周期频率过高,上一周期发送的 Frame 可能尚未收到,之后可以通过过程数据 Datagram 的 Working Counter 没有增加来发现这一问题。
这句话非常值得记住:
EtherCAT 总线本身可以很快,但如果主站不能按时执行周期任务,整个控制系统仍然无法获得理想的确定性。
六、从 IgH 源码看:Datagram 是怎么被发送出去的?
现在进入真正的源码。
上一篇文章中我们看到:
fsm_master fsm_slave fsm_pdo fsm_coe等模块最终都会产生 Datagram。
这些 Datagram 不会立即各自发送,而是进入 Master 的发送队列。
可以抽象成:
FSM │ ▼ Datagram │ ▼ Master Queue │ ▼ ec_master_send_datagrams() │ ▼ EtherCAT Frame │ ▼ Device Driver │ ▼ NIC官方master.c中存在:
ec_master_send_datagrams()专门负责将指定设备上的 Datagram 队列发送出去。
而源码中实际发送 Frame 时,会先遍历待发送 Datagram。
核心逻辑可以概括为:
取 Datagram ↓ 写 Datagram Header ↓ 写 Datagram Data ↓ 写 Working Counter ↓ 继续下一个 Datagram ↓ 形成完整 Frame ↓ 发送官方源码中可以看到,IgH 会把 Datagram 的type、index、address、data_size和data写入 Frame,并在 Datagram 尾部预留 Working Counter;之后构造 EtherCAT Frame Header,再将 Frame 交给ec_device_send()。
这就非常清楚了:
Datagram 是逻辑通信操作,Frame 是实际在 Ethernet 链路上传输的封装。
七、为什么一个 Frame 可以放多个 Datagram?
这也是 IgH 源码值得研究的地方。
假设应用程序或者多个状态机产生:
Datagram A Datagram B Datagram C并不一定需要:
Frame A Frame B Frame C而可以组织为:
┌───────────────────────────────────┐ │ Ethernet Frame │ │ │ │ ┌──────────┐ ┌──────────┐ ┌────┐ │ │ │Datagram A│ │Datagram B│ │ D C│ │ │ └──────────┘ └──────────┘ └────┘ │ │ │ └───────────────────────────────────┘这样做的一个直接好处就是:
减少 Frame 数量,提高链路利用率。
但这里要注意一个工程上的重要问题:
Frame 并不是越少越好。
因为一个 Frame 越大,它在物理链路上的传输时间也会增加。
如果:
Frame 太大那么可能导致:
周期占用时间增加如果:
Frame 太多又可能带来:
包处理开销 中断/轮询开销 驱动开销 CPU 开销因此最终系统需要在:
Frame 数量 Frame 长度 控制周期 从站数量 过程数据大小 CPU 性能 网卡性能之间进行平衡。
这也是后面讨论 EtherCAT 周期和实时抖动时非常重要的一点。
八、接收数据时,IgH 又做了什么?
发送只是前半部分。
真正的实时控制必须形成:
Send ↓ Slave Processing ↓ Receive ↓ Application闭环。
IgH 中:
ec_master_receive_datagrams()负责处理收到的 Frame。
官方文档明确说明,该函数由网络驱动在每次收到 Frame 时调用,并负责处理接收到的 Frame。
可以把接收过程理解成:
NIC │ ▼ Received Frame │ ▼ ec_master_receive_datagrams() │ ▼ 解析 Frame │ ├── Datagram A ├── Datagram B └── Datagram C │ ▼ 匹配 Index │ ▼ 更新 Datagram 状态 │ ▼ 读取 Data │ ▼ 读取 WKC这里有一个非常重要的对应关系:
发送时:
Datagram ↓ Frame ↓ NIC接收时:
NIC ↓ Frame ↓ Datagram所以整个 Master 的核心实际上是:
Datagram Queue ↕ EtherCAT Frame ↕ Ethernet Device九、Datagram 的状态为什么很重要?
IgH 的 Datagram 不只是保存:
data它还会记录自身的状态。
可以把它理解成:
EC_DATAGRAM_INIT ↓ EC_DATAGRAM_QUEUED ↓ EC_DATAGRAM_SENT ↓ EC_DATAGRAM_RECEIVED如果出现问题,则可能进入:
TIMEOUT INVALID ERROR之类的异常处理路径。
这对于状态机尤其重要。
例如 CoE FSM 发送一个请求之后,并不是:
send() ↓ 假设成功而是:
发送 Datagram ↓ 等待 ↓ 判断 Datagram state ↓ 判断 WKC ↓ 解析返回数据 ↓ 进入下一个 FSM state官方 CoE FSM 源码中就可以看到非常典型的处理逻辑:
Datagram timeout ↓ retry ↓ 仍然失败 ↓ error同时它还会检查:
datagram->working_counter如果 WKC 不符合预期,就进入错误状态。
这就是我们上一篇文章讲到的:
为什么 IgH 要使用大量状态机。
因为工业通信不是简单的:
发送 → 完成而是:
发送 ↓ 等待 ↓ 判断状态 ↓ 判断 WKC ↓ 判断数据 ↓ 成功 / 重试 / 错误十、一个 SDO 请求经过 IgH 到底发生了什么?
用一个具体例子就更容易理解。
假设应用程序希望读取某个伺服对象:
0x6064:00也就是常见的实际位置对象。
注意:
SDO 并不是直接等于一个 EtherCAT Frame。
它通常经过:
Application ↓ SDO Request ↓ CoE FSM ↓ Mailbox ↓ EtherCAT Datagram ↓ EtherCAT Frame ↓ Slave从站返回之后:
Slave ↓ EtherCAT Frame ↓ Datagram ↓ Mailbox ↓ CoE FSM ↓ SDO Response ↓ Application因此:
SDO CoE Mailbox Datagram Frame实际上是不同层次的概念。
这个区别非常重要。
十一、过程数据 PDO 又是什么情况?
如果把 SDO 比作:
“我现在问设备一个参数。”
那么 PDO 更像:
“设备每一个控制周期都要和我交换的数据。”
例如一个伺服系统:
Master → Servo Controlword Target Position Target VelocityServo → Master:
Statusword Actual Position Actual Velocity这些数据需要:
1 ms 1 ms 1 ms 1 ms持续周期性传输。
所以 PDO 的通信路径更加直接:
Application ↓ Domain ↓ Process Data ↓ Datagram ↓ EtherCAT Frame ↓ Slave接收方向:
Slave ↓ EtherCAT Frame ↓ Datagram ↓ Domain ↓ Process Data ↓ Application这也是为什么上一篇文章介绍Domain时特别强调:
Domain 并不是一个普通的数据结构,而是 IgH 对实时过程数据进行组织的重要抽象。
官方 API 中,ecrt_domain_queue()的作用就是把 Domain 的 Datagram 重新放入 Master 的 Datagram 队列,以便在下一次ecrt_master_send()时进行交换。
所以我们现在可以把:
Domain Datagram Frame三者的关系完整串起来:
Domain │ │ 管理过程数据 ▼ Datagram │ │ 管理一次 EtherCAT 通信操作 ▼ Frame │ │ 真正进入 Ethernet 链路 ▼ Slave十二、一个 1 ms EtherCAT 控制周期到底发生什么?
这是工程人员最关心的问题。
假设:
Control Period = 1 ms那么应用程序可能按照这样的逻辑运行:
while (running) { ecrt_master_receive(); ecrt_domain_process(domain); /* read PDO */ control_algorithm(); /* write PDO */ ecrt_domain_queue(domain); ecrt_master_send(); wait_next_cycle(); }这个代码看起来非常简单。
但真正执行时,背后发生的是:
1 ms Cycle ───────────────────────────────────── Receive Frame ↓ Parse Datagram ↓ Update WKC ↓ Process Domain ↓ Read PDO ↓ Control Algorithm ↓ Write PDO ↓ Queue Datagram ↓ Build EtherCAT Frame ↓ NIC Send ↓ EtherCAT Slaves Process ↓ Frame Return ↓ Next Cycle如果把时间轴展开:
t0 │ ├── Receive │ ├── Domain Process │ ├── Control │ ├── Domain Queue │ └── Send │ ├──────── EtherCAT transmission ────────┤ │ │ t1 t2其中真正需要关注的是:
整个过程必须在规定的控制周期内完成。
否则:
下一周期开始时,上一个周期的 EtherCAT Frame 可能还没有完成接收。
官方 EtherLab 文档在 Timing Aspects 中就明确讨论了这一问题:如果周期频率设置过高,上一周期发送的 Frame 可能还没有完成接收,ecrt_domain_process()可以通过过程数据 Datagram 的 Working Counter 没有增加来发现这种情况。
十三、为什么“1 ms 周期”不等于“1 ms 实时”?
这里需要特别澄清一个概念。
很多宣传材料喜欢说:
1 ms EtherCAT然后让人感觉:
“系统就是 1 ms 实时。”
其实不是。
假设:
目标周期 = 1 ms但实际周期可能变成:
0.99 ms 1.01 ms 1.00 ms 1.20 ms 0.98 ms平均值可能依然接近:
1 ms但是:
1.20 ms可能已经造成控制问题。
所以实时系统真正关注的不是:
平均值是多少?
而是:
最坏情况下会延迟多少?
这就是后面我们要重点讨论的:
Latency Jitter Worst-case latency Determinism几个概念。
EtherCAT 本身解决的是通信链路上的确定性问题,但整个控制周期仍然受:
Scheduler IRQ CPU Driver NIC Memory Application影响。
因此:
EtherCAT 快和:
系统硬实时不是同一个命题。
十四、WKC 为什么可以帮助我们判断“这个周期有没有问题”?
假设一个 Domain 注册了:
Slave 1 PDO Slave 2 PDO Slave 3 PDO每一个周期:
Master ↓ EtherCAT Frame ↓ Slave 1 ↓ Slave 2 ↓ Slave 3 ↓ Master正常情况下:
WKC = expected如果某一个从站没有正确参与:
WKC < expected那么 Domain 的状态可能从:
EC_WC_COMPLETE变成:
EC_WC_INCOMPLETE甚至:
EC_WC_ZERO官方 API 就是通过这种 Working Counter 状态来描述过程数据交换完整程度。
这对于工程排查非常有价值。
例如:
控制算法没问题 CPU 也没超载 但是 WKC 经常不完整那么优先应该检查:
EtherCAT 链路 从站状态 PDO 配置 Frame 网络硬件 周期设置而不是第一时间修改控制算法。
十五、WKC 异常应该怎么排查?
假设现场出现:
EtherCAT working counter change或者 Domain 状态出现:
INCOMPLETE可以按照下面的逻辑逐层检查。
第一层:从站状态
首先看:
ethercat slaves确认从站是否仍然:
OP如果已经退回:
SAFEOP PREOP那么 WKC 异常只是结果,真正的问题可能发生在从站状态层。
第二层:PDO 配置
检查:
ethercat pdos确认:
RxPDO TxPDO PDO Mapping是否符合设备实际配置。
第三层:Domain
检查应用程序注册的 PDO Entry:
Index Subindex Bit Position Data Type是否正确。
如果应用程序认为:
0x6041位于某个位置,而实际 Domain Mapping 并不是这样,那么即使 EtherCAT Frame 正常,也可能产生错误的数据解释。
第四层:周期
检查:
Control Period是不是过短。
如果系统目标:
250 μs但硬件和软件实际只能稳定支持:
1 ms那么降低周期并不一定会解决问题,反而可能让系统频繁出现:
WKC incomplete因为上一周期数据还没有完成。
第五层:CPU 和实时调度
如果:
WKC 偶发异常尤其是:
CPU 高负载 IRQ 干扰 实时线程被延迟那么问题可能已经不在 EtherCAT 协议本身,而在主站执行环境。
这也是后面“EtherCAT + 实时 Linux”的重要切入点。
十六、为什么 Datagram 和实时 Linux 最终一定会联系起来?
到这里可以看到一个很有意思的事实。
EtherCAT 本身已经非常关注:
周期 Frame Datagram WKC但是:
谁来调用 ecrt_master_receive()? 谁来调用 ecrt_master_send()?答案是:
操作系统上的任务。
如果这个任务:
每 1 ms 执行一次那么系统真正需要的是:
1 ms 1 ms 1 ms 1 ms而不是:
0.7 ms 1.2 ms 0.8 ms 2.5 ms所以整个实时控制链实际上是:
Application │ ▼ Control Task │ ▼ Real-time Scheduler │ ▼ IgH EtherCAT │ ▼ Datagram │ ▼ EtherCAT Frame │ ▼ NIC / PHY │ ▼ EtherCAT Slave其中:
EtherCAT解决的是:
通信的确定性和效率。
而:
实时 Linux / RTOS解决的是:
控制任务什么时候能够运行,以及运行时受到多少干扰。
这两者必须结合起来看。
十七、为什么这也是理解“硬实时”的入口?
假设一个机器人控制周期:
1 ms控制任务每次需要:
100 μs那么理论上:
100 μs 控制计算 + EtherCAT 通信 + 系统调度 + 中断处理 + 其他系统开销 < 1 ms才有可能稳定运行。
但是更重要的是:
不能只看平均值。
假设:
平均调度延迟 = 10 μs看起来非常优秀。
但偶尔:
Worst Case = 800 μs那么对于 1 ms 控制周期来说,系统仍然存在明显风险。
所以真正需要建立的是:
平均延迟 ↓ 抖动 ↓ 最坏情况延迟 ↓ 确定性逐层深入的认识。
这也是为什么下一阶段讨论实时 Linux 时,我们不能只拿一个:
cyclictest average就宣布:
“系统已经硬实时。”
这是工程上非常危险的简化。
十八、从 IgH Datagram 机制重新理解 EtherCAT 的优势
现在回头看最初的问题:
EtherCAT 为什么适合实时工业控制?
答案就清晰很多了。
它不是因为:
Ethernet三个字就天然实时。
也不是因为:
速度快就天然实时。
真正重要的是一整套机制:
EtherCAT Protocol │ ├── Datagram │ ├── Frame Processing │ ├── Logical / Physical Addressing │ ├── Working Counter │ ├── Distributed Clocks │ └── Cyclic Process Data而 IgH 则在 Linux 环境中实现了这一整套 EtherCAT Master 机制。
从源码来看:
FSM │ ▼ Datagram │ ▼ Master Queue │ ▼ EtherCAT Frame │ ▼ Device Driver │ ▼ NIC接收方向再反过来:
NIC │ ▼ EtherCAT Frame │ ▼ Datagram │ ▼ WKC │ ▼ Domain │ ▼ Application于是整个系统形成了一个完整的数据闭环。
十九、把一个 EtherCAT 控制周期画出来
如果要用一张图总结今天的内容,可以画成:
1 个控制周期 ┌──────────────────────────────────────────────┐ │ │ │ Real-time Task │ │ │ │ │ ▼ │ │ ecrt_master_receive() │ │ │ │ │ ▼ │ │ Parse EtherCAT Frame │ │ │ │ │ ▼ │ │ Datagram / WKC │ │ │ │ │ ▼ │ │ ecrt_domain_process() │ │ │ │ │ ▼ │ │ Read PDO │ │ │ │ │ ▼ │ │ Control Algorithm │ │ │ │ │ ▼ │ │ Write PDO │ │ │ │ │ ▼ │ │ ecrt_domain_queue() │ │ │ │ │ ▼ │ │ ecrt_master_send() │ │ │ │ │ ▼ │ │ Datagram → EtherCAT Frame │ │ │ │ │ ▼ │ │ NIC → EtherCAT Network → Slaves │ │ │ │ │ └──────────────→ Next Cycle │ │ │ └──────────────────────────────────────────────┘这张图非常重要。
因为它把前面几篇文章的内容真正串起来了:
第 2 篇:Master / Slave / Domain / Datagram ↓ 第 3 篇:IgH 源码结构 ↓ 第 4 篇:FSM / INIT / PREOP / SAFEOP / OP ↓ 第 5 篇:Datagram / Frame / WKC ↓ 第 6 篇:Domain / PDO下一篇就可以自然进入:
PDO 到底是什么?为什么 EtherCAT 实时控制几乎离不开 PDO?
二十、总结:Datagram 是理解 IgH 实时通信的关键入口
如果只用一句话概括今天的内容:
Datagram 是 IgH 对 EtherCAT 一次通信操作进行抽象的基本单位,而多个 Datagram 可以被组织进 EtherCAT Frame,通过网卡进入 EtherCAT 网络,并在接收端根据 Datagram Index、状态和 Working Counter 等信息完成处理。
从源码角度,可以记住这条主线:
FSM ↓ Datagram ↓ Master Queue ↓ EtherCAT Frame ↓ Device Driver ↓ NIC ↓ EtherCAT Slave ↓ Return Frame ↓ Datagram ↓ WKC ↓ Domain / FSM ↓ Application这条链路实际上就是 IgH EtherCAT Master 最核心的数据通路之一。
同时还应该记住三个非常重要的结论。
第一,Datagram 不等于 Frame。
Datagram 是 EtherCAT 通信操作的逻辑单位,而 Frame 是实际进入 Ethernet 链路传输的封装单位。
第二,EtherCAT 实时性不等于低延迟。
真正的实时控制还需要考虑:
周期 抖动 最坏情况延迟 WKC CPU IRQ Driver Scheduler第三,EtherCAT Master 本身也不是完整的实时控制系统。
IgH 解决的是:
Linux + EtherCAT Master而最终工业控制系统还需要:
实时任务 实时调度 确定性执行环境 EtherCAT 通信 控制算法共同工作。
这也是为什么到了后面的文章,我们会越来越频繁地看到:
PDO Domain Distributed Clocks CPU IRQ CPU Affinity Core Isolation Scheduler Jitter这些概念。
因为真正的工业控制问题从来不是:
“EtherCAT 快不快?”
而是:
“从控制任务产生数据,到数据经过 EtherCAT 到达执行机构,再到反馈数据返回控制任务,这整个闭环能不能在规定时间内稳定完成?”
这才是实时工业控制真正值得研究的问题。
下一篇,我们就继续往上层走,重点拆解PDO、Domain、PDO Mapping 以及过程数据内存映射。
标题可以继续采用:
《PDO 到底是什么?从 IgH Domain 理解 EtherCAT 实时数据交换》
届时会重点回答一个工程问题:
为什么 EtherCAT 的实时数据不应该每个周期都通过 SDO 读取,而是要通过 PDO + Domain 建立一条固定的过程数据通道?
这也会正式进入 IgH EtherCAT Master 最核心的实时数据部分。