开放的MODBUS / TCP 规范

 

 

 

1.0版,1999329

 

 

 

 

 

 

 

Andy Swales

施耐德电气

aswales@modicon.com

 


内容

内容................................................. .................................................. .................................................. ....................... 2

1.本规范的状态............................................ .................................................. ........................................... 3

2.概述............................................... .................................................. .................................................. .................... 3

2.1面向连接.............................................. .................................................. ............................................. 3

2.2数据编码............................................... .................................................. .................................................. .... 4

2.3参考号的解释............................................. .................................................. .................. 4

2.4隐含长度哲学.............................................. .................................................. ................................... 5

3.一致性课堂摘要............................................. .................................................. .................................... 5

3.10 ............................................... .................................................. .................................................. .................. 5

3.21............................................... .................................................. .................................................. .................. 5

3.32............................................... .................................................. .................................................. .................. 6

3.4机器/供应商/网络特定功能.......................................... .................................................. ....... 7

4.议定书结构.............................................. .................................................. .................................................. ....... 7

5.一致性类的协议引用........................................... .................................................. .................. 8

5.10命令详细信息............................................. .................................................. ..................................... 9

5.1.1读取多个寄存器(FC 3........................................ .................................................. ........................... 9

5.1.2写入多个寄存器(FC 16........................................ .................................................. ........................ 9

5.21类命令的详细内容............................................. .................................................. ................................... 10

5.2.1读取线圈(FC 1......................................... .................................................. ............................................. 10

5.2.2阅读输入分立(FC 2........................................ .................................................. ............................. 10

5.2.3读取输入寄存器(FC 4........................................ .................................................. .............................. 11

5.2.4写入线圈(FC 5......................................... .................................................. ............................................... 11

5.2.5写单个寄存器(FC 6........................................ .................................................. ............................... 12

5.2.6读取异常状态(FC 7........................................ .................................................. ......................... 12

5.32类命令详情............................................. .................................................. ................................... 13

5.3.1强制多个线圈(FC 15........................................ .................................................. ............................ 13

5.3.2阅读一般参考资料(FC 20........................................ .................................................. ..................... 14

5.3.3编写一般参考文献(FC 21........................................ .................................................. ..................... 15

5.3.4掩码写寄存器(FC 22........................................ .................................................. ............................. 16

5.3.5/写寄存器(FC 23....................................... .................................................. ............................. 16

5.3.6FIFO队列(FC 24........................................ .................................................. ............................... 17

6.例外代码.............................................. .................................................. .................................................. ...... 17

附录................................................. .................................................. .................................................. ................ 19

A.客户端和服务器实施指南........................................... .................................................. ......... 19

A.1客户设计............................................. .................................................. .................................................. ....... 19

A.2服务器设计............................................. .................................................. .................................................. ...... 20

A.2.1多线程服务器............................................. .................................................. .................................. 20

A.2.2单线程服务器........................................... .................................................. .................................. 21

A.3要求的和预期的绩效........................................... .................................................. ................ 22

B.非字数据的数据编码......................................... .................................................. ............................. 23

B.1单词内的位数.......................................... .................................................. ................................... 23

B.2多字数量........................................... .................................................. ........................................... 24

B.2.1 984数据类型............................................ .................................................. ............................................ 24

B.2.2 IEC-1131数据类型.......................................... .................................................. ..................................... 25


 

1.本规范的状态

初始版本199793

公众审查草案。

1999329日重新发布,修订版1.0

没有技术变化,只有澄清。

添加附录AB以回应常见的实施问题。

 

MODBUS / TCP的这一规范正在通过在万维网上公开显示出版。它旨在为希望将MODBUS / TCP用作工业自动化领域的互操作性标准的开发人员提供帮助。

由于MODBUSMODBUS / TCP实际上是实际标准,因为许多供应商和产品已经实现了这一标准,本规范主要解释了通过互联网上普遍可用的TCP通信协议对MODBUS消息的特定编码。

 

2.概述

MODBUS / TCP是用于监控和控制自动化设备的MODBUS系列简单,供应商中立的通信协议的变体。具体来说,它涵盖了在使用TCP / IP协议的内联互联网环境中使用MODBUS消息。此时最常用的协议是将PLCI / O模块和网关以太网连接到其他简单的现场总线或I / O网络。

MODBUS / TCP协议正在以(自动)自动化标准发布。由于MODBUS已经广为人知,本文件中应该只有很少的信息不能在其他地方获得。然而,人们试图阐明MODBUS中的哪些功能对通用自动化设备的互操作性有价值,以及哪些部分是作为PLC的编程协议的备用MODBUS中的行李

这通过将支持的消息类型分组到有效性类别中来完成,该类别区分那些普遍实现的消息和可选的消息,特别是那些特定于诸如PLC之类的设备的消息。

2.1面向连接

MODBUS中,数据交易传统上是无状态的,因此它们具有很强的抵御噪音干扰的能力,而且要求最小限度地保留恢复信息。

另一方面,编程操作期望面向连接的方法。这是通过一个专用的注册令牌在简单的变体上实现的,并且在Modbus Plus变体上通过明确的程序路径功能实现,该功能在明确分解之前保持双工关联。

MODBUS / TCP处理这两种情况。在协议级别很容易识别连接,并且单个连接可能携带多个独立事务。另外,TCP允许大量的并发连接,所以在大多数情况下,可以根据需要选择是重新连接还是重新使用长连接。

熟悉MODBUS的开发人员可能会想知道为什么使用面向连接的TCP协议而不是面向数据报的UDP。主要原因是通过将个人交易控制在可以识别,监督和取消的连接中,而不需要客户端和服务器应用程序的特定操作。这使该机制对网络性能变化具有宽泛的容忍度,并允许轻松添加防火墙和代理等安全功能。

当万维网的原始开发人员选择使用知名端口80上的TCP来实现最小Web查询作为单个事务时,使用了类似的推理。

2.2数据编码

MODBUS为地址和数据项目使用“big-endian”表示。这意味着当发送大于单个字节的数字量时,首先发送最高有效字节。举个例子

                160x1234将是0x12 0x34

                320x12345678L将是0x12 0x34 0x56 0x78

2.3解释参考号码

MODBUS将其数据模型基于一系列具有显着特征的表格。四个主表是

输入离散单位,由I / O系统提供,只读

输出离散一位,可由应用程序改变,读写

输入寄存器16位数量,由I / O系统提供,只读

输出寄存器16位数量,可由应用程序改变,可读写

输入和输出之间以及位寻址和字寻址数据项之间的区别并不意味着任何应用程序行为。如果这是所讨论的目标机器上最自然的解释,那么将所有四个表格视为相互重叠是完全可以接受的,也是非常常见的。

对于每个主表,协议允许单独选择65536个数据项目,并且这些项目的读取或写入操作被设计为跨越多个连续的数据项目,直至取决于交易功能代码的数据大小限制。

没有假设数据项表示一个真正连续的数据阵列,尽管这是大多数简单PLC所使用的解释

读和写通用参考功能代码被定义为携带一个32位参考编号,并可用于允许直接访问非常大的空间内的数据项。今天没有PLC设备利用这一点。

一个潜在的混淆之处是MODBUS功能中使用的参考号与Modicon PLC中使用的注册号之间的关系。由于历史原因,用户参考号被表示为十进制数,起始偏移量为1.然而,MODBUS使用从零开始的无符号整数索引的更自然的软件解释。

因此,请求读取偏移量为0的寄存器的modbus消息将返回应用程序员已知的值,如寄存器4中所示:00001(存储器类型4 =输出寄存器,参考00001

2.4隐含的长度哲学

所有MODBUS请求和响应的设计方式都是收信人可以验证邮件是否完整。对于请求和响应具有固定长度的功能代码,单独的功能代码就足够了。对于在请求或响应中携带可变数量数据的功能代码,数据部分前面会有一个字节计数。

Modbus通过TCP传输时,前缀中会携带附加长度信息,以便接收方能够识别消息边界,即使该消息必须分成多个数据包进行传输。显式和隐式长度规则的存在以及在以太网上使用CRC-32错误校验码都会导致无法检测到请求或响应消息被破坏的机会。

3.一致性类汇总

从头开始定义新协议时,可以强化编号和解释的一致性。MODBUS的性质已经在许多地方实现,并且必须避免对现有实现的破坏。

因此,现有的一组事务类型已被分类为一致性类别,其中0级表示通用实施且完全一致的功能,2级表示有用的功能但具有一些特质。本套件中不适合互用性的那些功能也被标识出来。

必须注意的是,对该标准的未来扩展可能会定义附加的功能代码来处理现有事实标准不足的情况。然而,这些提议的扩展的细节会出现在本文件中,这会引起误解。通过发送特定的功能代码并检查异常响应的类型(如果有的话),确定某个特定目标设备是否支持特定的功能代码,这种方法将始终可以确保当前MODBUS设备与引入任何这样的扩展。事实上,这是导致当前功能代码分类的哲学。

3.10

这是MASTERSLAVE的最小有用功能集。

读取多个寄存器(fc 3

写多个寄存器(fc 16

3.21

这是通常实施和互操作的附加功能集。如前所述,许多奴隶选择将输入,输出,离散和注册视为等同。

读取线圈(fc 1

读输入分立(fc 2

读取输入寄存器(fc 4

写线圈(fc 5

写单个寄存器(fc 6

读取异常状态(fc 7

对于每个从属系列,此功能通常具有不同的含义

3.32

这些是日常操作(如HMI和监督)所需的数据传输功能

强制多个线圈(fc 15

阅读一般参考(fc 20

该功能可以处理多个同时发生的请求,并且可以接受32位的参考号。当前的584984 PLC只使用该功能来接受类型6(扩展寄存器文件)的引用。

这个函数最适合扩展来处理大型寄存器空间和当前缺少参考数字的数据项目,如未定位变量。

写一般参考(fc 21

该功能可以处理多个同时发生的请求,并且可以接受32位的参考号。当前的584984 PLC只使用该功能来接受类型6(扩展寄存器文件)的引用。

这个函数最适合扩展来处理大型寄存器空间和当前缺少参考数字的数据项目,如未定位变量。

掩码写入寄存器(fc 22

/写寄存器(fc 23

该功能允许一系列寄存器的输入和一系列寄存器的输出作为单个事务。这是使用MODBUS最有效的方式,例如使用I / O模块执行状态图像的定期交换。

因此,高性能但多功能的数据采集设备可以选择实现功能3,1623,以将数据的快速定期交换(23)与执行按需询问或更新特定数据项(316)的能力相结合

读取FIFO队列(fc 24

一个有点专门的功能,旨在允许从一个FIFO结构的表(用于584/984上的FINFOUT功能块)到主机的数据传输。在某些类型的事件记录应用中很有用

3.4机器/供应商/网络特定功能

尽管在MODBUS协议手册中提到了以下所有功能,但它们不适用于互操作性目的,因为它们过于依赖于机器。

诊断(fc 8

程序(484)(fc 9

轮询(484)(fc 10

获取通信事件计数器(Modbus)(fc 11

获取通讯事件日志(Modbus)(fc 12

节目(584/984)(fc 13

民意调查(584/984)(fc 14

报告从机IDfc 17

节目(884 / u84)(fc 18

重置通信链接(884 / u84)(fc 19

程序(ConCept)(fc 40

固件更换(fc 125

节目(584/984)(fc 126

报告本地地址(Modbus)(fc 127

4.协议结构

本节介绍在MODBUS / TCP网络上进行MODBUS请求或响应封装的一般形式。请注意,从功能代码到数据部分末尾的请求和响应主体的结构具有与其他MODBUS变体完全相同的布局和含义,例如

                MODBUS串口 - ASCII编码

                MODBUS串口 - RTU(二进制)编码

                MODBUS PLUS网络 - 数据路径

这些其他情况的唯一区别是任何成帧序列的形式,错误检查模式和地址解释。

 

所有请求都通过注册端口502上的TCP发送。

请求通常以半双工方式在给定连接上发送。也就是说,在响应未完成时,在单个连接上发送额外请求没有任何好处。反而鼓励希望获得高峰值传输速率的设备建立到相同目标的多个TCP连接。然而,已知某些现有的客户端设备试图管道化请求。附录A描述了允许服务器适应这种行为的设计技术。

MODBUS“地址字段被单字节单元标识符取代,可用于通过设备进行通信,例如使用单个IP地址的网桥和网关来支持多个独立的终端设备。

请求和响应的前缀为6个字节,如下所示

字节0:事务标识符 - 由服务器复制 - 通常为0

字节1:事务标识符 - 由服务器复制 - 通常为0

字节2:协议标识符= 0

字节3:协议标识符= 0

字节4:长度字段(高字节)= 0(因为所有消息都小于256

字节5:长度字段(低字节)=接下来的字节数

字节6:单元标识符(以前的地址

字节7MODBUS功能码

字节8开:数据根据需要

因此,一个示例事务在UI 9的偏移量4处注册了1,返回值为5

要求:00 00 00 00 00 06 09 03 00 04 00 01

回应:00 00 00 00 00 05 09 03 02 00 05

有关在一致性等级0-2中使用每个功能代码的示例,请参阅后面的部分

熟悉MODBUS的设计人员应注意,在MODBUS / TCP中不需要“CRC-16”“LRRC”检查字段。TCP / IP和链路层(例如以太网)校验和机制被用于验证数据包的准确传送。

5.一致性类的协议引用

请注意,在示例中,请求和响应从功能代码字节开始列出。如前所述,在MODBUS / TCP的情况下将会有一个依赖于传输的前缀包含七个字节

                ref ref 00 00 00 len单位

上面的参考文献是两个字节的交易参考号,它们在服务器上没有值,但是为了方便客户端,从请求到响应逐字复制。简单的客户通常选择将值保留为零。

在这些例子中,请求和响应的格式是这样给出的(这个例子是针对一个读取寄存器的请求,详见后面的部分)

03 00 00 00 01 => 03 02 12 34

这表示要附加到前缀的十六进制字节序列,因此TCP连接上的完整消息将是(假设单元标识符09再次)

要求:00 00 00 00 00 06 09 03 00 00 00 01

回应:00 00 00 00 00 05 09 03 02 12 34

(所有这些请求和响应均使用自动工具进行验证,查询Modicon Quantum PLC的当前规格)

5.10命令的细节

5.1.1读取多个寄存器(FC 3

请求

字节0FC = 03

字节1-2:参考编号

字节3-4:字数(1-125

响应

字节0FC = 03

字节1:响应的字节数(B = 2 x字数)

字节2-B + 1):寄存器值

例外

字节0FC = 83(十六进制)

字节1:例外代码= 0102

读取参考0处的1寄存器(Modicon 984中的40001),得出值1234(十六进制)

03 00 00 00 01 => 03 02 12 34

5.1.2写入多个寄存器(FC 16

请求

字节0FC = 10(十六进制)

字节1-2:参考编号

字节3-4:字数(1-100

字节5:字节计数(B = 2 x字数)

字节6-B + 5):寄存器值

响应

字节0FC = 10(十六进制)

字节1-2:参考编号

字节3-4:字数

例外

字节0FC = 90(十六进制)

字节1:例外代码= 0102

在值1234(十六进制)的参考0Modicon 984中的40001)上写入1寄存器

10 00 00 00 01 02 12 34 => 10 00 00 00 01

5.21类命令的详细信息

5.2.1读取线圈(FC 1

请求

字节0FC = 01

字节1-2:参考编号

字节3-4:位数(1-2000

响应

字节0FC = 01

字节1:响应的字节数(B =(位数+7/ 8

字节2-B + 1):位值(最低有效位是第一个线圈!)

例外

字节0FC = 81(十六进制)

字节1:例外代码= 0102

在参考0Modicon 984中的00001)读取1个线圈得到值1

01 00 00 00 01 => 01 01 01

请注意,返回数据的格式与大端架构不一致。还请注意,如果请求调用多个字,并且它们未在16位边界上对齐,则该请求可能对从器件的计算量非常大。

5.2.2阅读输入分立(FC 2

请求

字节0FC = 02

字节1-2:参考编号

字节3-4:位数(1-2000

响应

字节0FC = 02

字节1:响应的字节数(B =(位数+7/ 8

字节2-B + 1):位值(最低有效位是第一个线圈!)

例外

字节0FC = 82(十六进制)

字节1:例外代码= 0102

在参考0Modicon 984中的10001)读取1个离散量输入,得到值1

02 00 00 00 01 => 02 01 01

请注意,返回数据的格式与大端架构不一致。还请注意,如果请求调用多个字,并且它们未在16位边界上对齐,则该请求可能对从器件的计算量非常大。

5.2.3读取输入寄存器(FC 4

请求

字节0FC = 04

字节1-2:参考编号

字节3-4:字数(1-125

响应

字节0FC = 04

字节1:响应的字节数(B = 2 x字数)

字节2-B + 1):寄存器值

例外

字节0FC = 84(十六进制)

字节1:例外代码= 0102

在参考0Modicon 984中的30001)读取1个输入寄存器,得到值1234(十六进制)

04 00 00 00 01 => 04 02 12 34

5.2.4写入线圈(FC 5

请求

字节0FC = 05

字节1-2:参考编号

字节3= FF开启线圈,= 00关闭线圈

字节4= 00

响应

字节0FC = 05

字节1-2:参考编号

字节3= FF开启线圈,= 00关闭线圈(回波)

字节4= 00

例外

字节0FC = 85(十六进制)

字节1:例外代码= 0102

在参考0处写入1个线圈(Modicon 984中的00001)为值1

05 00 00 FF 00 => 05 00 00 FF 00

5.2.5写单个寄存器(FC 6

请求

字节0FC = 06

字节1-2:参考编号

字节3-4:注册值

响应

字节0FC = 06

字节1-2:参考编号

字节3-4:注册值

例外

字节0FC = 86(十六进制)

字节1:例外代码= 0102

在值1234(十六进制)的参考0Modicon 984中的40001)上写入1寄存器

06 00 00 12 34 => 06 00 00 12 34

5.2.6读取异常状态(FC 7

请注意,异常状态异常响应无关。未知异常状态消息的目的是在使用慢波特率的早期MODBUS轮询多点网络中实现最大的响应速度。PLC 通常会映射一系列8个线圈(输出分立),这些线圈将使用该消息进行询问。

请求

字节0FC = 07

响应

字节0FC = 07

字节1:异常状态(通常是8个线圈的预定范围)

例外

字节0FC = 87(十六进制)

字节1:例外代码= 0102

读取异常状态导致值34十六进制

07 => 07 34

5.32类命令的细节

5.3.1强制多个线圈(FC 15

请求

字节0FC = 0F(十六进制)

字节1-2:参考编号

字节3-4:位数(1-800

字节5:字节数(B =(位数+7/ 8

字节6-B + 5):要写入的数据(最低有效位=第一个线圈)

响应

字节0FC = 0F(十六进制)

字节1-2:参考编号

字节3-4:位数

例外

字节0FC = 8F(十六进制)

字节1:例外代码= 0102

在参考0处写入3个线圈(Modicon 984中的00001)为值0,0,1

0F 00 00 00 03 01 04 => 0F 00 00 00 03

请注意,输入数据的格式与大端架构不一致。还请注意,如果请求调用多个字,并且它们未在16位边界上对齐,则该请求可能对从器件的计算量非常大。

5.3.2阅读一般参考资料(FC 20

请求

字节0FC = 14(十六进制)

字节1:请求的剩余部分的字节数(= 7个组数)

字节2:对于6xxxx扩展寄存器文件,第一组的引用类型= 06

字节3-6:第一组的参考号码    

                                                =文件编号:6xxxx文件的偏移量

                                                = 4x​​xxx寄存器的32位参考号

字节7-8:第一组字数

字节9-15 :(对于字节2-8,对于第二组)

。。。

响应

字节0FC = 14(十六进制)

字节1:响应的总体字节数 

                                                =组的数量+组的字节数的总和)

字节2:第一组的字节数(B1 = 1 +2 x字数))

字节3:第一组的参考类型

字节4-B1 + 2):第一组的寄存器值

字节(B1 + 3):第二组的字节数(B2 = 1 +2 x字数))

字节(B1 + 4):第二组的参考类型

字节(B1 + 5 - B1 + B2 + 2):第二组的寄存器值

。。。

例外

字节0FC = 94(十六进制)

字节1:例外代码= 01020304

在参考12Modicon 984中的文件1偏移量2)读取1扩展寄存器,得到值1234(十六进制)

14 07 06 00 01 00 02 00 01 => 14 04 03 06 12 34

(未来)

在参考0处读取1寄存器,返回1234十六进制,在参考5处返回2个寄存器,返回56789abc十六进制

14 0E 04 00 00 00 00 00 01 04 00 00 00 05 00 02 => 14 0A 03 04 12 34 05 04 56 78 9A BC

请注意,传输大小限制很难在数学公式中定义。一般而言,由于缓冲区大小的原因,请求和响应的消息大小都被限制为256字节,并且必须考虑各个请求和响应数据帧的聚合大小。如果从站不愿意处理消息,则会生成异常类型04,因为响应太大。

5.3.3编写一般参考文献(FC 21

请求

字节0FC = 15(十六进制)

字节1:请求的剩余部分的字节数

字节2:对于6xxxx扩展寄存器文件,第一组的引用类型= 06

字节3-6:第一组的参考号码    

                                                =文件编号:6xxxx文件的偏移量

                                                = 4x​​xxx寄存器的32位参考号

字节7-8:第一组的字数(W1

字节9-8 + 2 x W1):为第一组注册数据

(对于任何其他组,复制来自字节2的组数据帧)

。。。

响应

响应是查询的直接回应

字节0FC = 15(十六进制)

字节1:请求的剩余部分的字节数

字节2:对于6xxxx扩展寄存器文件,第一组的引用类型= 06

字节3-6:第一组的参考号码    

                                                =文件编号:6xxxx文件的偏移量

                                                = 4x​​xxx寄存器的32位参考号

字节7-8:第一组的字数(W1

字节9-8 + 2 x W1):为第一组注册数据

(对于任何其他组,复制来自字节2的组数据帧)

。。。

例外

字节0FC = 95(十六进制)

字节1:例外代码= 01020304

在参考12Modicon 984中的文件1偏移量2)处写入1扩展寄存器为1234十六进制值

15 09 06 00 01 00 02 00 01 12 34 => 15 09 06 00 01 00 02 00 01 12 34

(未来)

在参考0处写入1寄存器至十六进制值1234,在参考5处写入2个寄存器至值56789abc十六进制

15 14 04 00 00 00 00 00 01 12 34 04 00 00 00 05 00 02 56 78 9A BC 

ð15  14 04 00 00 00 00 00 01 12 34 04 00 00 00 05 00 02 56 78 9A BC 

请注意,传输大小限制很难在数学公式中定义。一般而言,由于缓冲区大小的原因,请求和响应的消息大小都被限制为256字节,并且必须考虑各个请求和响应数据帧的聚合大小。如果从站不愿意处理消息,则会生成异常类型04,因为响应太大。

5.3.4掩码写寄存器(FC 22

请求

字节0FC = 16(十六进制)

字节1-2:参考编号

字节3-4AND掩码用于注册

字节5-6OR掩码应用于寄存器

响应

字节0FC = 16(十六进制)

字节1-2:参考编号

字节3-4AND掩码用于注册

字节5-6OR掩码应用于寄存器

例外

字节0FC = 96(十六进制)

字节1:例外代码= 0102

将参考位0Modicon 984中的40001)的位0-3的字段更改为值4(十六进制)

(与000F,或与0004

16 00 00 00 0F 00 04 => 16 00 00 00 0F 00 04

5.3.5/写寄存器(FC 23

请求

字节0FC = 17(十六进制)

字节1-2:用于读取的参考号码

字节3-4:读取字数(1-125

字节5-6:写入的参考号码

字节7-8:写入字数(1-100

字节9:字节计数(B =写入的字数)

字节10-B + 9):寄存器值

响应

字节0FC = 17(十六进制)

字节1:字节计数(B =读取的2个字数)

字节2-B + 1)寄存器值

例外

字节0FC = 97(十六进制)

字节1:例外代码= 0102

在值为0123的十六进制的参考340004,在Modicon 984中)写入1个寄存器,并在参考0读取2个寄存器,返回值00045678(十六进制)

17 00 00 00 02 00 03 00 01 02 01 23 => 17 04 00 04 56 78

请注意,如果写入和读取的寄存器范围重叠,则结果不确定。一些设备在读取之前实现写入,但其他设备在写入之前实现读取。

5.3.6FIFO队列(FC 24

请求

字节0FC = 18(十六进制)

字节1-2:参考编号

响应

字节0FC = 18(十六进制)

字节1-2:字节数(B = 2 +字数)(最大64

字节3-4:字数(FIFO中累积的字数)(最大31

字节5-B + 2):从FIFO前面寄存数据

例外

字节0FC = 98(十六进制)

字节1:例外代码= 010203

读取从参考0005Modicon 984中的40006)开始的FIFO块的内容,其中包含2个值为1234的字和5678个十六进制未完成

18 00 05 => 18 00 06 00 02 12 34 56 78

请注意,在984上实现的这个功能在多功能性方面非常有限 - 假设寄存器块包含一个可以具有031的值的计数,然后是多达31个字的数据。当函数完成时,计数字不会重置为零,这可能是从FIFO操作所期望的。

总而言之,这应该被认为是fn 16读取多个寄存器的有限子集,因为后者可以用来执行所有必需的功能。

6.例外代码

在发生问题时,由奴隶返回一组定义的异常代码。请注意,主设备可能会发出命令,并使用收到的成功或异常代码来确定设备愿意响应哪些MODBUS命令,并确定从设备上可用的各种数据区域的大小。

所有异常都是通过向请求的功能代码添加0x80来指示的,并且通过单个原因字节来跟随该字节,例如如下

                03 12 34 00 01 => 83 02

请求在索引0x1234处读取1寄存器响应异常类型2 - “非法数据地址

例外列表如下

01非法功能

查询中收到的功能代码不是从站的允许操作。这可能是因为功能代码仅适用于较新的控制器,并未在选定的单元中实施。它也可能表示从属处于错误状态来处理这种类型的请求,例如因为它未被配置并且被要求返回寄存器值。

02非法数据地址

查询中收到的数据地址不是从站的允许地址。更具体地说,参考号和传输长度的组合是无效的。对于具有100个寄存器的控制器,偏移96和长度4的请求将成功,偏移96和长度5的请求将生成异常02

03非法数据值

包含在查询数据字段中的值不是从站的允许值。这表明复杂请求的其余部分的结构中存在错误,例如隐含长度不正确。它并不意味着提交存储在寄存器中的数据项的值超出了应用程序的期望值,因为MODBUS协议不知道任何特定寄存器的任何特定值的重要性。

04非法反应的长度

表示请求框架会生成一个大小超过可用MODBUS数据大小的响应。仅用于生成多部分响应的函数,如函数2021

05确认

与编程命令配合使用

06从属设备繁忙

与编程命令配合使用

07 NEGATlVE ACKNOWLEDGE

与编程命令配合使用

08 MEMORY PARlTY错误

与功能代码2021一起专门使用,表明扩展文件区域未能通过一致性检查。

0A网关路径不可用

Modbus Plus网关结合使用时,表明网关无法分配Modbus Plus PATH来处理请求。通常意味着网关配置错误。

0B GATEWAY目标设备无法响应

专门与Modbus Plus网关配合使用,表示没有从目标设备获得响应。通常意味着设备不在网络上。

附录

A.客户端和服务器实施指南

本节中的注释不应被视为对客户端或服务器的任何特定实现具有约束力。但是,如果遵循这些政策,将在实施多供应商系统和网关以安装MODBUS设备时最大限度地降低集成意外。

下面的软件结构假定熟悉BSD套接字服务接口,例如在UNIXWindows NT上使用。

A.1客户设计

MODBUS / TCP旨在允许客户的设计尽可能简单。软件的例子在其他地方给出,但处理交易的基本过程如下

在所需服务器上使用connect()建立到端口502TCP连接

准备一个MODBUS请求,如前所述进行编码

MODBUS请求(包括其6字节的MODBUS / TCP前缀)作为单个缓冲区提交,使用send()

等待响应出现在同一个TCP连接上。或者,如果希望比TCP通常报告的通信问题更快地被建议,则使用select()在此步骤中运行超时。

使用recv()读取响应的前6个字节,它将指示响应消息的实际长度

使用recv()来读取响应的其余字节。

如果在不久的将来不希望进一步与该特定目标进行通信,请关闭TCP连接,以便服务器上的资源可以在此期间用于服务其他客户端。建议1秒的时间作为客户端连接断开的最长时间。

如果发生超时等待响应,请单方面关闭连接,打开一个新连接,然后重新提交请求。这种技术允许客户端控制重试时间,这比TCP默认提供的时间要好。它还允许备用回退策略,例如在网络基础设施组件发生故障的情况下,使用完全独立的通信网络向备用IP地址提交请求。

A.2服务器设计

MODBUS / TCP服务器应始终设计为支持多个并发客户端,即使在其预期用途中,只有一个客户端看起来有意义。这允许客户端以快速顺序关闭和重新打开连接,以快速响应未递送响应。

如果使用传统的TCP协议栈,通过减少接收和发送缓冲区大小可以节省大量的内存资源。在UNIXNT上的普通TCP服务通常会分配8K字节或更多的连接接收缓冲区,以鼓励从例如文件服务器传输数据。这种缓冲区空间在MODBUS / TCP中没有值,因为请求或响应的最大大小小于300字节。通常可以交换存储空间以获取其他连接资源。

多线程或单线程模型都可以用来处理多个连接。接下来的部分将进行说明。

A.2.1多线程服务器

鼓励使用多线程(如JAVA)的操作系统或语言可以使用多线程策略,如下所述:

 

使用listen()等待TCP端口502上的传入连接

当收到新的连接请求时,使用accept()接受它并产生一个新的线程来处理连接

 

在新线程中,在无限循环中执行以下操作:

6字节的MODBUS / TCP报头发出recv6)请求。不要在这里放置超时,而应该等到请求通过或连接关闭。这两种情况都会自动唤醒线程。

分析标题。如果它看起来损坏,例如协议字段不为零或消息长度大于256,则单击关闭连接。作为服务器,这是一种暗示TCP编码不正确的情况,这是正确的响应。

为消息的其余字节发出recv(),其长度现在已知。特别要注意的是,在这个长度上发布带有这种限制的recv()将允许坚持处理请求的客户端。任何这样的流水线请求将保留在服务器或客户端的TCP缓冲区中,并在稍后当当前请求已完成服务时提取。

现在处理传入的MODBUS消息,如果有必要暂停当前线程,直到可以计算出正确的响应。最终,您将有一个有效的MODBUS消息或EXCEPTION消息用作响应

为响应生成MODBUS / TCP前缀,从请求的字节01复制交易标识符字段,然后重新计算长度字段。

提交包括MODBUS / TCP前缀在内的响应作为连接传输的单个缓冲区,使用send()

回去等待下一个6字节前缀记录。

最终,当客户端选择关闭连接时,6×C字节前缀的recv()将失败。有序关闭通常会导致recv()返回字节数为零。强制关闭可能会从recv()生成错误返回。在任何一种情况下,关闭连接并取消当前线程。

A.2.2单线程服务器

某些嵌入式系统和较旧的操作系统(如UNIXMS-DOS)鼓励使用来自套接字接口的select选项来处理多个连接。在这样的系统中,您可以将它们作为一个通用处理程序中的多个状态机来处理,而不是在它们自己的线程中处理各个并发请求。像C ++这样的语言使这种软件的结构变得很方便。

现在的结构如下

 

通过将其状态设置为 idle 来初始化多个状态机

侦听()TCP端口502上的传入连接

现在开始一个无限循环检查终端和状态机,如下所示:

在侦听端口上,如果接收到新的连接请求,请使用accept()接受它,并使其中一个状态机将状态从 idle 更改为 newrequest 以处理传入连接

对于每个状态机

如果国家是新要求

使用select()查看请求是否已经到达。通常将超时设置为零,因为您不希望暂停该进程,因为此特定连接处于非活动状态。

如果select()指示有一个数据包,请使用recv6)像在多线程情况下一样读取标题。如果标题损坏,请关闭连接并将状态机设置为空闲状态。

如果读取成功,并且select()指示有更多输入可用,请阅读请求的其余部分。

如果请求已完成,请将会话状态更改为等待响应

如果recv()返回指示连接不再使用,请关闭连接并将状态机重置为 idle

如果状态是等待响应

查看应用程序响应信息是否可用,是否可用,如何构建响应数据包,以及如何使用send()发送它,这与多线程的情况完全相同。将状态设置为新请求

 

通过将多个select()调用按每个周期组合到一个调用中,可以优化性能,而不会影响应用程序的功能结构。

A.3要求的和预期的表现

通过MODBUSMODBUS / TCP进行事务处理时,故意没有规定所需的响应时间。

这是因为MODBUS / TCP有望用于尽可能广泛的各种通信情况中,从预计亚毫秒定时的I / O扫描器到延迟数秒的长距离无线电链路。

此外,MODBUS系列旨在鼓励通过盲信号转换网关在网络之间进行自动转换。这些设备包括Schneider以太网到Modbus Plus网桥以及从MODBUS / TCPMODBUS串行链路转换的各种设备。使用这些设备意味着现有MODBUS设备的性能与使用MODBUS / TCP相一致。

一般来说,具有扫描行为的PLC等设备将在一个扫描时间内响应输入请求,扫描时间通常在20毫秒和200毫秒之间变化。

从客户的角度来看,这个时间必须通过整个网络的预期传输延迟来延长,以确定一个合理的响应时间。对于交换式以太网来说,这种传输延迟可能是毫秒,对于广域网连接来说可能是几百毫秒。

反过来,客户用来启动应用程序重试的任何超时时间应该大于预期的最大合理响应时间。如果没有遵守,则目标设备或网络上可能出现过度拥塞,这可能会导致进一步的错误。这是一个应该始终避免的特征。

因此,在实践中,高性能应用程序中使用的客户端超时总是可能在某种程度上取决于网络拓扑和预期的客户端性能。

当在本地以太网上扫描10I / O设备并且每个设备通常在1毫秒内响应时,例如30毫秒的超时可能是合理的。另一方面,当通过串行链路上的网关监控慢PLC时,1秒的超时值可能更合适,其中正常扫描序列在300毫秒内完成。

对时间要求不高的应用程序通常会将超时值留给正常的TCP默认值,这会在大多数平台上几秒钟后报告通信故障。

鼓励客户关闭并重新建立仅用于数据访问(而不是PLC编程)的MODBUS / TCP连接,并且在下一次使用之前的预计时间很长,例如超过一秒。如果客户端遵循这个原则,它允许服务器有限的连接资源为更多的潜在客户端提供服务,并且可以帮助错误恢复策略,例如选择替代目标IP地址。应该记住,由于关闭和重新打开连接而导致的额外通信和CPU负载与由单个Modbus事务引起的负载相当。

B.非字数据的数据编码

使用功能代码3(读取寄存器),16(写入寄存器)或可能23(读/写寄存器),通过MODBUS传送任何类型的批量信息的最有效方法。

虽然这些函数是根据它们在16位寄存器上的操作来定义的,但它们可以用于将任何类型的信息从一台机器移动到另一台机器,只要该信息可以表示为16位字的连续块。

原有的支持MODBUSPLC是使用“big-endian”架构的专用计算机。大多数现代PLC是基于商用微处理器,采用小端结构。MODBUS用于在这两种体系结构之间潜在交换数据的事实引入了一些微妙之处,可能会陷入不必要的困扰。

除了原始离散位“16位寄存器之外,几乎所有的数据类型都是在采用小端微处理器之后引入的。因此,这些数据类型在MODBUS上的表示遵循小端模型,即含义

首先寄存器位15-0 =数据项的位15-0

第二寄存器位15-0 =数据项的位31-16

数据项的第三个寄存器位15-0 =47-32

等等。

B.1单词中的位数

Modicon PLC具有984梯形图语言中的预定义功能,它将一系列连续的寄存器转换为1分隔的等效长度块。最常见的这种功能是BLKM(块移动)。

为了与最初的大端架构保持一致,这些离散值从最高有效位编号到最低有效位,并且增加更多混淆,所有数字序列从1开始,而不是从0开始。(本文档中的位编号总是从零开始引用为最低位,以符合现代软件文档)

所以在一个字(注册)

离散型1将位15(值为0x8000

离散2将是位14(值0x4000 

离散3将是位13(值0x2000

离散4将位12(值0x1000 

离散5将位11(值0x0800

离散6将是位10(值0x0400 

离散7将位9(值0x0200

离散8将是位8(值0x0100 

离散9将位7(值0x0080

离散10将是位6(值0x0040 

离散值11将位5(值0x0020

离散12将位4(值0x0010 

离散13将是位3(值0x0008

离散14将是位2(值0x0004 

离散15将是位1(值0x0002

离散型16将是位0(值0x0001 

当超过16位时,例如32点离散量输入模块,分立116将在第一个寄存器中,分立1732将在第二个寄存器中。

这种编号约定对于理解通过MODBUS / TCP处理离散输入或输出设备时尤为重要,因为离散点的编号与Modicon PLC的编号一致。

特别要注意的是,一个字内IEC-1131编号约定是从0(最低有效)到15(最高有效),这与离散编号相反。

B.2多字量

原则上,可以传输16位字数组的任何数据结构,并在具有相同数据表示的机器上保持不变。

应注意以下PLC数据类型

B.2.1 984数据类型

984 16位无符号整数

自然含义:整数的位15-0 =寄存器的位15-0

984 16位有符号整数

自然含义:整数的位15-0 =寄存器的位15-0

984 ASCII

尽管PLC不具备文本操作功能,但原始梯形图语言编辑器允许寄存器每个显示为2ASCII字符。显示的第一个字符是UPPER字节(位15 - 8),显示的第二个字符是LOWER字节(位7 - 0)。特别要注意的是,这与在现代PLC上使用C语言或其他高级语言的字符数组相反。

984浮点

英特尔单精度真实

第一个寄存器包含32位数的位15-0(有效位的15-0位)

第二个寄存器包含32位数字(指数和有效位的23-16位)的第31-16位,

984单精度无符号十进制

尽管值范围限制在0 - 9999,但数据表示与16位无符号整数相同

984双精度无符号十进制

这种数据格式现在很少使用,除了驱动旧式4位十进制显示。

值的范围是099999999.第一个寄存器包含最高有效4位,第二个寄存器包含最低有效4位,每个数字表示为二进制值,范围为0-9999

B.2.2 IEC-1131数据类型

所有IEC-1131数据类型均以小端形式显示在Modicon PLC上。例子如下

字节

8位数量。

寄存器的位7-0 = BYTE的位7-0

DINT

32位数量。

第一个寄存器的位15-0 = DINT的位15-0

第二寄存器的位15-0 = DINT的位31-16

INT

寄存器的位15-0 = INT的位15-0

真实

32位英特尔单精度实数

第一寄存器的位15-0 = REAL的位15-0(有效位的位15-0

第二寄存器的位15-0 = REAL的位31-16(指数+有效位的位23-16

 

UDINT

32位数量。

第一个寄存器的位15-0 = UDINT的位15-0

第二个寄存器的位15-0 = UDINT的位31-16

UINT

寄存器的位15-0 = INT的位15-0

对于其他人,请参阅相应的IEC-1131编程手册