4. ADS协议原理
ADS(Automation Device Specification)是 Beckhoff 为 TwinCAT 体系定义的自动化设备通信规范。它并不是一个孤立的“新协议”,而是建立在 TCP/IP 或 UDP 之上的应用层协议,通过 AMS(Automation Message Specification)报文完成设备寻址、服务调用与数据读写。理解 ADS,关键要抓住五个概念:协议栈、AMS NetID、端口号、索引组与索引偏移、通信模型。它们分别回答“数据怎么走”“找哪台设备”“找哪个服务”“读写哪个变量”“谁主动发起”这五个问题。
一、ADS 协议栈:从用户程序到物理网络
ADS 通信在软件层面是分层封装的。最上层是用户程序或 ADS 客户端库(如 TwinCAT.Ads、ADS DLL、PyADS);向下是 ADS 服务层,负责 Read、Write、ReadWrite、AddDeviceNotification 等服务命令;再向下是 AMS 报文层,封装源/目标 NetID、源/目标端口、命令号、状态码和数据长度;之后是 TCP 或 UDP 传输层,最后是 Ethernet 物理层。TwinCAT 运行时内部有一个 AMS Router,它负责把 AMS 报文在本地端口、远程设备、不同网络接口之间转发。
因此,一次 ADS 读写并不是“直接访问 PLC 内存”,而是“客户端构造 AMS 报文 → 传输层发送 → 目标 AMS Router 接收 → 路由到目标端口 → 目标服务处理 → 返回响应”。这也是为什么 NetID 和端口号必须同时正确,否则报文会被路由器丢弃或返回目标未找到错误。
二、AMS NetID:设备的逻辑地址
AMS NetID 是 AMS 网络中设备的唯一逻辑标识,通常表示为“IP 地址.1.1”的形式,例如 192.168.1.10.1.1。其中前四段是 IP 地址,后两段是 AMS 子网标识和节点标识。对于本机 TwinCAT 系统,常见本机 NetID 为 127.0.0.1.1.1 或实际网卡 IP 对应的 NetID。NetID 的作用类似“门牌号”,它告诉 AMS Router:这条报文最终应该交给哪台设备上的 AMS 服务。
需要特别注意:NetID 不是 IP 地址的简单别名。一个设备可能有多个网卡,也可能配置多个 NetID;远程路由场景下,目标 NetID 甚至可能不是目标设备的真实 IP,而是路由表中映射的逻辑地址。因此,在跨网段或通过路由访问时,必须同时检查路由表和 NetID 配置。
三、端口号:定位设备内的服务
AMS 端口号不是 TCP/UDP 端口,而是 AMS 网络内部的“服务端口”。它用于区分同一台设备上的不同 ADS 服务。常见端口包括:
| 端口号 | 服务对象 | 典型用途 |
|---|---|---|
| 851 | TwinCAT PLC 运行时 | 读写 PLC 变量、调用 PLC 服务 |
| 852 | TwinCAT NC/运动控制 | 轴参数、运动控制数据访问 |
| 10000 | 系统服务 | 系统信息、设备管理 |
| 16 | ADS 设备通知 | 订阅变量变化通知 |
端口号决定了“找哪个服务”。例如访问 PLC 变量时目标端口通常是 851;如果误写成 852,即使 NetID 正确,也会因为目标服务不存在或变量不匹配而失败。
四、索引组与索引偏移:定位具体变量
在 ADS 中,真正定位一个变量或数据项,靠的是“索引组(IndexGroup)+ 索引偏移(IndexOffset)”。索引组表示数据类别或对象类型,索引偏移表示该类别中的具体位置。对于 PLC 变量,常见做法是通过变量名解析得到对应的索引组和索引偏移;对于符号访问,ADS 还支持按名称读取,但底层仍会转换为索引组/偏移或句柄。
例如,读取 PLC 中某个变量时,客户端可能使用:
IndexGroup = 0x4020
IndexOffset = 0x00000000
Length = 4
目标端口 = 851
目标NetID = 192.168.1.10.1.1
其中 0x4020 常用于 PLC 变量区访问。不同索引组对应不同数据区域,索引偏移则像“数组下标”一样指向具体位置。若索引组或偏移错误,即使 NetID 和端口正确,也会读到错误数据或返回访问拒绝。
五、通信模型:客户端/服务端与通知机制
ADS 采用客户端/服务端通信模型。客户端主动发起请求,服务端响应。典型服务包括 Read、Write、ReadWrite、ReadState、WriteControl 和 AddDeviceNotification。前几种是同步请求/响应模式;AddDeviceNotification 则用于订阅变量变化,服务端在数据变化时主动发送通知,适合数据采集和实时监控。
从数据流看,一次 ADS 读取的路径是:客户端构造 AMS 报文 → 传输层发送 → 目标 AMS Router → 目标端口服务 → 根据索引组/偏移访问数据 → 返回响应。通知模式则是在服务端注册后,由服务端按周期或变化触发上报。理解这个模型,有助于排查“读不到”“读错”“通知不触发”等问题。
六、案例与排障:一次读取失败的复盘
假设客户端要读取 192.168.1.10 上 PLC 的某个变量,配置如下:
目标NetID = 192.168.1.10.1.1
目标端口 = 851
IndexGroup = 0x4020
IndexOffset = 0x00000000
读取长度 = 4
如果返回“目标未找到”,优先检查 NetID 是否与目标设备实际配置一致,以及 AMS 路由表是否已添加。如果返回“端口未找到”,检查目标端口是否写错,或 PLC 运行时是否已启动。如果返回“访问拒绝”或数据异常,检查索引组和索引偏移是否对应正确变量,以及读取长度是否越界。若使用通知模式却收不到数据,检查 AddDeviceNotification 是否注册成功、通知周期是否合理、变量是否真的发生变化。
七、核心要点清单
- ADS 是应用层协议,依赖 TCP/UDP 传输,由 AMS Router 完成路由。
- AMS NetID 是设备逻辑地址,格式通常为“IP.1.1”。
- AMS 端口号定位设备内服务,PLC 常用 851,NC 常用 852。
- IndexGroup 表示数据类别,IndexOffset 表示具体位置。
- 通信模型以客户端/服务端为主,支持同步读写和通知订阅。
- 排障顺序:NetID → 端口 → 索引组/偏移 → 数据长度 → 服务状态。
掌握这五个概念后,再看 ADS 的 API、路由配置和变量访问代码,就能把“地址、服务、数据、方向”四个维度对应起来,而不是停留在“能连上但不知道为什么能连上”的层面。