参考资料(想详细了解务必自己阅读参考资料):
包括倍福学院的相关视频
倍福 ads 通讯技术-数据包结构及组件_哔哩哔哩_bilibili
TwinCAT 的 ADS(Automation Device Specification)协议是 Beckhoff 公司开发的自动化设备通信协议,用于在 TwinCAT 系统中实现控制器与外部设备或应用程序之间的数据交换和控制。
ADS 基于 AMS(Automation Messaging Specification)协议,提供了一套标准化的通信接口,允许不同设备和应用程序之间进行数据交换。是一个服务/客户端模式的通信机制。有两个模型——请求&响应模型和订阅&发布模型。
AMS 其实和 TCP/IP 很像,用于设备之间进行寻址和通信,主要有 AMS NetID 和 AMS Port 参数。AMS NetID 其实和 IP 地址很类似,但是和本机 IP 是多少没有任何关系。他是一个 6 段字符串,前 4 段可以自由定义,最后两段用于识别不同的设备,默认 TwinCAT 为“.1.1”。AMS Port 就类似于端口号了,每个应用或者叫物理设备下的虚拟设备分配唯一端口号。还有就是 ADS Router,是 ADS Client 与 TwinCAT 实时核交互的接口,TwinCAT 系统各模块均作为独立的设备,每个任务均存在一个服务模块,服务端或客户端,然后统一由 Router 交换数据。
整体架构如图

所以在 TwinCAT 中的各个任务之间数据的交互也都是使用 ADS Router 进行数据交换
对于 ADS 来说只是一个上层而已,他可以支持多种传输层协议:

同时 ADS 有两种有两种通信方式:同步和异步。其实就在于程序在等待响应时是阻塞还是非阻塞的,因为不管什么方式,ADS 都会有响应包去回应。
注意:Ads 通讯不是一个实时的通讯协议,其通讯过程受到系统和网络状况的多重影响,无法保证一个稳定的通讯时间。只不过因为如果在一个实时操作系统下,通信时间较短,各个进程间使用进程间通信,所以实时性能满足。
对外(硬件层面)
主要使用 TCP/IP 协议对外打交道,TwinCAT 默认使用 48898 端口,使用 TCP/IP 协议进行对外通信,使用 UDP 协议通过广播的方式查找路由(其他设备)。
但是对外也并不只局限于这两个协议:

本质上都支持那个传输层协议的所有。
对内(硬件层面)
还记得我们说的 TwinCAT 系统各模块均作为独立的设备。所以其实我们 EtherCAT 在 TwinCAT 也是一个独立的设备存在,他调用的我们的网口,而我们的网口是不是跑在 PCI 总线下面的,所以其实在这里实现 ADS 就跑在了 ISA 总线下面,如图:(AoE)

但像是 PLC 的应用程序不会注册成为一个有独立 AmsNetId,而是在现在 TwinCAT 的 AmsNetId 基础上建立了一个端口(默认从 851 开始每新增一个加一)。
然后就是我们用户自己写的一些程序,其都是使用的 TCP/IP 协议进行和 ADS Router 进行交互。
所以官方也有说明“理论上:如果这门语言可以实现 tcp,就能支持 ads。但是,我们一般没有对这些语言提供专门的 ads 库,需要自己基于 tcp 来实现。网上有一些第三方的 ads 库,可以作为参考。比如 pyhon 和 node.js 都有第三方的 ads 库”
所以其实在整个 TwinCAT 中处处都是 ADS。
对内和对外的总结
官方有这样一句话“标识一个设备上的不同软件模块是通过端口号”。我在这里深化一下这个概念,对内和对外我是为了在第一次读这个的读者去理解 ADS Router 这个东西,以 ADS Router 为界限来区分了对内和对外,方便后续软件开发的理解。
在这里请忘掉对内和对外,我们只以 AmsNetId 来区分。
像是与其他主机的通信,包括我们与实现 EtherCAT 的通信,所以他们有自己独立的 AmsNetId 去识别他们,包括后面会说的为了定位到数据的 Index-Group 等。因为其实他的下面每个从站都需要占用一个端口,我们通过 AmsNetId+prot 去访问每个从站,每个从站的都有独立的 Index-Group 等。(支持 AoE)

但是 PLC 这种就是单独的一个个设备,下面不会再有其他的需要占用端口的了,只有程序,所以他就注册在 TwinCAT 这个大的 AmsNetId 这个下的端口了。
所以,其实本质有没有独立的 AmsNetId 还是注册为一个端口是看下面还会不会挂其他的设备占用端口。他与 ADS Router 没有关系,一个 ADS Router 可以管理有几个 AmsNetId,他只负责信息的传递。
看到这里需要注意,TwinCAT 内部虽然每个“设备”都是有独立的可索引的 ADS 通信方式的。但是我们就并不能直接假设在 TwinCAT 软件中的他们一定都是使用的 ADS 通信。我们可以知道 PLC 代码和我们的 HMI 是 ADS 的或者不同任务间是通过 ADS 进行通信的,但是官方没有明确说我们 PLC 和 EtherCAT 设备中链接的数据是通过 ADS 进行的,这个本身就是 TwinCAT 的一些核心机制了,我们不过多揣测。
我们只分析 TwinCAT 为我们提供的 ADS 接口和他的原理。
服务端程序和客户端程序
因为我们 ADS 是服务/客户端模式的通信机制。所以本质要像 TCP/IP 开发一样开发两端的程序。
- 客户端
本质的架构如下图,需要依赖于 ADS Router。因为他只是一个客户端,不用注册一个端口。他直接依赖 ADS Router 的接口去访问服务就行了,所以没有 AMS NetId 和 AMS Port 一说,只有目标的 ID 和端口。我们使用动态链接库去调用就行了,然后进行数据的读写。

软件开发的小指南
因为 ADS 通信结构的构建一定是需要 ADS Router 进行数据交换的。每一个 TwinCAT 中就有一个 ADS Router。所以按道理来说 ADS 通信强依赖于 TwinCAT,虽然使用 TCP/IP 协议,但是不管应用程序在本地还是在外地,当前设备没有安装 TwinCAT 的根本就无法实现 ADS 通信。(现在倍福官方也考虑到这个问题了,把 TC3 的通信组件独立了出来,大约 130MB)
其实问题只是出在闭源库上,因为闭源库默认你安装了 TwinCAT,应用程序使用 TCP/IP 协议与 ADS Router 应用交互,真实调用网卡的是 ADS Router。
这种情况有两种思路,一种是自己用 TCP/IP 在本机开发客户端,在另一个主机开发服务端,然后用服务端去和 ADS Router 交互。(不合理)
第二种就是官方说可以编译开源的 ADS 库(这也确保了可以在 linux 下实现 ADS,倍福自己开源的 https://github.com/Beckhoff/ADS)。下面放出 ADS Router 多机交互原理和官方对安不安装 TwinCAT 的建议。
- 服务端
服务端的结构其实我们很常见了,我们 TwinCAT 里面看见的像是 PLC 就是一个服务端程序,他使用高级语言注册了一个在 TwinCAT 上面的端口,然后 TwinCAT 来使用这个端口进行数据收发。
当然,说着是可以使用高级语言,但其实为了有 TwinCAT 的图形化链接的方式,我们基本上只能选择 TwinCAT 自带的 C++。
数据的索引
识别到对应 NetId 和 Port 后,数据由 Index-Group 和 Index-Offset 来定位,下面 PPT 把原理讲的很详细了,这里不再过多解释:

但是在外面程序中并不需要关心 Index-Group:F00x 的操作,只需要找到对应数据直接对应的 Index-Group 和 Index-Offset 或者变量名并创建或者释放对应句柄就行了,底层的 ADS 库会帮我们解决。
数据包格式
较为清晰,不做分析。用 Wireshark 就能抓到


因为这个是个汇总文档,这里放大量篇幅只会导致文档可读性变差,需要了解具体含义请从这里开始:倍福 ads 通讯技术-数据包结构及组件_哔哩哔哩_bilibili(会直接跳转到讲解分钟数)
EAP
在看完相关 ADS 的资料后大概率你会看到 EAP 这个东西,在看后续 EAP 相关知识之前要注意。EAP 是 EtherCAT 协议族的一部分。定义在 ETG 1020 中,属于 EtherCAT Protocol Enhancement 部分所以并不是说 EAP 和 EtherCAT 是并列关系,属于包含关系。
但至于为什么会在 ADS 相关的资料中看见 EAP 相关的信息,是因为 EAP 虽然支持实时通信,但也支持异步的非实时通信。异步的非实时通信只能使用 EtherCAT 中 AoE(ADS over EtherCAT)的邮箱通信实现的,但是 AoE 又是和 ADS 相关的,所以才有了关联性描述。
EtherCAT 协议是主从通信,如果是需要两个主站之间进行实时通信,那就不存在主从的说法,这种情况下就不可以使用 EtherCAT 协议进行通信,针对这种需求,开发了 EAP 协议,EAP 协议用于两个或多个主站之间进行实时通信。
EAP 是实时通信协议,但是不是同步的,多个主站不能同步收到数据,只能说点对点通信的时候因为延迟低,以数据到达时间来实现“软同步”,如果希望降低延迟可以使用 EL6614 等交换机来保证,当然也可以使用普通的交换机。
当然 EL66xx 主要是是用来实现在 EtherCAT 中走 EoE 然后拓展回 EtherNet 接口接 EtherNet 设备的交换机。
实际应用拓扑可以如下:

现在理清楚了概念,来对比一下:

然后具体的可以查看 EAP 手册和以下相关资料:

