用户

协议

qianmoQqianmoQ· 更新于 2026-10-01· 阅读 8 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

下面的表格列出了每种语言实现中实际随附发布的驱动程序。只有当某个协议存在驱动程序并已在该实现的驱动管理器中注册时,才会被标记为支持——仅有一份协议规范本身是不够的。

协议CC#GoJavaPython
AB-Ethernet
ADS /AMS
BACnet/IP
CAN(原始)
CANopen
CBus
ctrlX
DF1
EtherNet/IP
EtherNet/IP - Logix
Firmata
IEC-60870
KNXnet/IP
Modbus(TCP/RTU/ASCII)
OPC-UA
Open-Protocol(Torque-Tools)
PLC4X(代理协议)
Profinet
S7
Simulated
SLMP(MELSEC)
UMAS

图例:

- 已实现且可用 - 部分实现——参见下方说明 - 未实现

关于部分实现的驱动程序的说明:

  • AB-Ethernet 在 Java 和 Go 中均可读取并提供轮询订阅,但两者都不支持写入。
  • BACnet/IP(Java)被动接收广播流量,并将其作为订阅暴露出来;它既不读取也不写入属性。Go 驱动才是功能完整的:它能读写属性、发现设备并订阅 COV 通知。
  • CAN(raw)(Java)支持写入和订阅,不支持读取。
  • CBus(Java)只是一个骨架,能建立连接但未实现任何操作。Go 驱动才是功能完整的。
  • ctrlX(Java)能响应 ping,这是它唯一完成的操作。驱动提供了发现功能,但 CtrlXPlcDiscoverer.discoverWithHandler 是一个未实现的 TODO,返回的是 null 而不是一个 future,因此发现请求只会失败,什么也找不到。它的读取、写入和订阅构建器同样未实现,而且尽管连接中带有浏览代码,浏览目前也无法工作。
  • Firmata 在 Java 和 Go 中均可写入和订阅,但两者都不支持读取。它只用于驱动和监控一块开发板,而不做轮询。
  • IEC 60870-5-104 在 Java 和 Go 中都仅支持订阅,因为该协议是推送驱动的:会话一旦建立,RTU 就会主动发送 ASDU,因此既没有东西可读,也没有东西可写。Go 驱动在每个值旁边保留了 IEC 质量描述符,因此 RTU 标记为无效、被阻塞、被替换或非当前的读数,不会以良好读数的样子呈现出来。
  • KNXnet/IP(C#)是 plc4net 中唯一的驱动,没有跟上其他实现的进度。
  • OPC-UA(Go)可以在未加密的通道上进行读取、写入和订阅,但仅此而已:只有 securityPolicy=None 真正可用,浏览未实现,消息也不分块,因此超过单个分块的请求或响应会失败。Java 驱动实现了六种安全策略、浏览和分块。
  • Open-Protocol(Java)只是一个骨架,能建立连接但未实现任何操作。
  • Profinet(Java)能发现设备并浏览已连接设备的子模块;两个 Java 驱动都不支持读取和写入。只有较新的 profinet-ng 驱动属于 plc4j-driver-all;较旧的 profinet 驱动仍在代码库中,但未被打包发布。在 profinet-ng 中,订阅请求会完成 PROFINET 连接握手,但订阅响应的 future 被刻意留为未完成状态,且 onRegisterConsumer 会抛出 UnsupportedOperationException,因此周期性数据永远不会到达应用。未打包的 profinet 驱动确实实现了这条路径——它会完成订阅响应、按订阅句柄注册消费者,并为每一个到来的周期性帧分发一个 PlcSubscriptionEvent——所以下面描述实际发布内容的订阅条目并不适用于它。
  • SLMP 在 Java 和 Go 中都仅访问字设备 D、W 和 R。这是驱动设计时的目标范围,而非移植上的缺口——位设备和更完整的 MELSEC 命令集在两种语言中都未实现。
  • UMAS(Go)对 DATE 和 TIME_OF_DAY 标签拒绝响应而非作出应答:Go 的数据项解析器还没有针对这些字段名的分支,否则这些字节会解析不出任何值。其他所有数据类型都支持读写。还要注意,UMAS 在任何语言中都没有附带测试数据,因此两个驱动是相互验证的,而不是与抓取到的真实报文交互进行验证。

DF1 在仓库中提供了协议规范,plc4go 还额外附带了由此生成的消息模型,但没有任何语言实现提供了对应的驱动:没有任何组件能够打开 DF1 连接。DF1 命令消息也会出现在 AB-Ethernet 模型中,该协议实际上正是在今天这个位置被使用的。

功能特性

下表列出了每个驱动实际实现了哪些操作。它描述的是 plc4j,因为这是最完整的实现;其他语言只支持其中的一个子集。当驱动实现了某项操作时,该操作就会被列为已支持——驱动对自身元数据的报告并不一致,因此本表遵循的是代码而非元数据。

ProtocolDiscoveryBrowseReadWriteSubscribePing
AB-Ethernet
ADS /AMS
BACnet/IP
CAN (raw)
CANopen
CBus
ctrlX
EtherNet/IP
EtherNet/IP - Logix
Firmata
IEC-60870
KNXnet/IP
Modbus TCP
Modbus RTU / ASCII
OPC-UA
Open-Protocol (Torque-Tools)
PLC4X (Proxy-Protocol)
Profinet (profinet-ng)
S7
Simulated
SLMP (MELSEC)
UMAS

图例:

- 由驱动实现 - 模拟:该协议没有原生支持,因此由 PLC4X 提供 - 未实现

Modbus 之类协议没有订阅的概念——客户端只能轮询。这些协议的驱动会扩展 PollingSubscriptionConnectionBase,它把订阅请求转化为轮询循环,并从中产生变更事件,从而使应用程序代码在任何地方都能使用同一套订阅 API。这正是上文黄色订阅条目所表示的含义;线路上的流量仍然是一连串的读取操作。AB-Ethernet、EtherNet/IP(包括 Logix)、Modbus、SLMP 和 UMAS 都以这种方式工作。

Logix 驱动复用了 EtherNet/IP 连接,因此它支持相同的操作,但不提供设备发现功能。Modbus 的发现功能同样仅限于 TCP:只有 ModbusTcpDriver 提供了发现请求构造器,所以串口的 RTU 和 ASCII 模式无法发现设备。S7 的发现功能使用 PROFINET DCP,需要安装可选的 pcap4j 运行时(以及主机上的 libpcap)。

读取或写入请求总是携带一组标签,因此不存在单独的"单值"与"多值"支持:能够读取的驱动就可以在一次请求中读取任意数量的标签。差别只在于效率——有些驱动会把一个请求拆分为多个 PLC 请求,再把响应合并起来。

评论

登录后参与评论

正在加载评论…