Modbus 协议_0

MODBUS 应用协议规范

本篇详解 Modbus 组织 提供的 MODBUS 应用协议规范-V1.1b3,感兴趣的朋友可以移步 Modbus 组织官网 详细了解。

推荐学习由百问网提供的全场景工业互联设备管理系统解决方案,其中有对 Modbus 详细的视频课程讲解和案例测试。


1. 引言

1.1 本文档的范围

MODBUS 是一种应用层消息协议,位于 OSI 模型的第七层[参考],提供在不同类型的总线或网络上连接的设备之间的客户端/服务器通信。

自 1979 年以来,MODBUS 已成为工业界的串行事实标准,持续支持数百万个自动化设备之间的通信。如今,MODBUS 简单而优雅的结构仍然得到不断支持和发展。互联网社区可以通过 TCP/IP 协议栈上的保留系统端口 502 访问 MODBUS。

MODBUS 是一种请求/回复协议,提供由功能代码指定的服务。MODBUS 功能代码是 MODBUS 请求/回复 PDU 的组成元素。本文档的目的是描述在 MODBUS 事务框架内使用的功能代码。


MODBUS 是一个用于设备间通信的协议,广泛应用于工业自动化领域,特别是在串行通信中。它基于客户端和服务器的通信模型,且采用请求-响应方式进行数据交换。功能代码(Function Codes)是 MODBUS 协议的核心,用于定义不同的操作或服务。

具体来说,MODBUS 协议自 1979 年推出以来,已经成为一种行业标准,并且随着网络的发展,越来越多的设备可以通过互联网进行通信。通过 TCP/IP 协议栈上的 502 端口(类似 HTTP 协议的 80 端口),MODBUS 协议被许多系统支持,进一步推动了它的应用和发展。

重点是理解 MODBUS 协议的功能代码,因为它们决定了数据交换的具体操作类型。每个功能代码代表一个特定的操作,例如读取数据、写入数据等,这些操作在设备之间的通讯中起着关键作用。


目前,MODBUS 的实现方式包括:

  • 通过以太网上的 TCP/IP 协议。请参见MODBUS 消息实现指南 V1.0a
  • 通过各种介质进行的异步串行传输(如:电缆:EIA/TIA-232-E、EIA-422、EIA/TIA-485-A;光纤、无线电等)。
  • MODBUS PLUS,一种高速令牌传递网络。

参考文献

  1. RFC 791, Internet Protocol, Sep81 DARPA

MODBUS 是一个高度灵活的协议,可以在多种不同的网络和传输方式中使用,满足不同应用的需求。

  1. TCP/IP 协议:MODBUS 可通过以太网上的 TCP/IP 协议进行通信,这为其提供了在现代网络环境中工作的能力。使用该协议时,MODBUS 消息在计算机网络上传输,且支持更广泛的设备和系统。

  2. 异步串行传输:这是 MODBUS 协议最早的实现方式,利用各种串行传输标准(如 RS-232、RS-422、RS-485 等)进行设备间的通信。这种方式广泛用于传统的工业自动化设备中,支持点对点或多点的通信方式。

  3. MODBUS PLUS:这是一种专为高性能要求设计的网络标准,采用令牌传递机制来实现设备间的高速通信。它通常用于需要高速度和高可靠性的应用场景。


2. 缩略词

  • ADU:应用数据单元 (Application Data Unit)
  • HDLC:高级数据链路控制 (High Level Data Link Control)
  • HMI:人机界面 (Human Machine Interface)
  • IETF:互联网工程任务组 (Internet Engineering Task Force)
  • I/O:输入/输出 (Input/Output)
  • IP:互联网协议 (Internet Protocol)
  • MAC:媒体访问控制 (Media Access Control)
  • MB:MODBUS 协议 (MODBUS Protocol)
  • MBAP:MODBUS 应用协议 (MODBUS Application Protocol)
  • PDU:协议数据单元 (Protocol Data Unit)
  • PLC:可编程逻辑控制器 (Programmable Logic Controller)
  • TCP:传输控制协议 (Transmission Control Protocol)

3. 背景

MODBUS 协议允许在各种类型的网络架构中进行便捷的通信。

每种类型的设备(如 PLC、HMI、控制面板、驱动器、运动控制、I/O 设备等)都可以使用 MODBUS 协议来发起远程操作。

这种通信既可以通过串行线路实现,也可以通过以太网 TCP/IP 网络实现。网关允许使用 MODBUS 协议在多种总线或网络类型之间进行通信。


MODBUS 协议不仅可以在各种不同的设备之间实现通信,而且可以适用于多种网络架构。无论是串行通信(如 RS-232、RS-485 等)还是基于 Ethernet 的 TCP/IP 网络,MODBUS 协议都能够有效地支持。

  • 多种设备支持:MODBUS 协议适用于广泛的设备类型,例如 PLC(可编程逻辑控制器)、HMI(人机界面)、控制面板、驱动器、运动控制系统以及各种输入输出设备(I/O 设备)。这些设备可以通过 MODBUS 协议进行远程操作和数据交换。

  • 支持不同类型的网络:无论是在传统的串行通信线路还是现代的 TCP/IP 网络中,MODBUS 都能够顺利工作。这使得其在工业自动化和其他领域的应用更加广泛。

  • 网关支持:在使用不同网络架构的设备之间,MODBUS 协议通过网关实现了跨网络通信。网关可以连接不同类型的总线或网络,让它们通过 MODBUS 协议进行互通。

如图 Figure 2 展示了一个典型的 MODBUS 网络架构示例,图中包含了不同类型的设备、通信协议以及网关的使用。

其中 Drive(驱动器)PLC(可编程逻辑控制器)HMI(人机界面)I/O(输入输出设备)Device(设备) 等,都是 MODBUS 网络中的节点或设备。

PLCHMI 作为主要的控制设备,通常与其他设备(如驱动器、I/O 设备等)进行通信。

  1. MODBUS 协议的实现

    • MODBUS on TCP/IP:表示 MODBUS 协议通过以太网的 TCP/IP 协议进行通信。它连接了多个设备(如 PLC、HMI、I/O 设备等),这是一种基于现代 IP 网络的通信方式,适用于分布广泛的设备。
    • MODBUS on MB+:这是 MODBUS PLUS(MB+)协议,它用于一种高速令牌传递网络,能够实现高效的设备通信。图中用它连接了 PLC、驱动器和 I/O 设备。
    • MODBUS on RS232MODBUS on RS485:这两种表示串行通信协议的部分,分别使用 RS-232 和 RS-485 接口进行数据传输。RS-232 常用于点对点连接,而 RS-485 支持多点通信,因此适合多个设备同时连接的场景。
    • Device:图中的某些设备被标注为 "Device",它们可能是具有较少功能的设备,通常与 PLC、HMI 等进行通信。
  2. 网关(Gateway)

    • Gateway 在图中起到了桥梁的作用,连接了不同类型的总线或网络(如 TCP/IP 网络与串行 RS-232 或 RS-485 网络)。通过网关,MODBUS 协议可以跨越不同的通信介质,确保不同网络和设备之间能够互联互通。

4. 一般描述

4.1 协议描述

MODBUS 协议定义了一个简单的协议数据单元(PDU),它独立于底层通信层。MODBUS 协议在特定总线或网络上的映射可能会在应用数据单元(ADU)中引入一些额外的字段。

MODBUS 应用数据单元是由发起 MODBUS 事务的客户端构建的。功能代码指示服务器执行何种操作。MODBUS 应用协议规定了客户端发起请求的格式。

MODBUS 数据单元的功能代码字段由一个字节编码。有效的功能代码范围是 1 到 255(十进制)(其中 128 到 255 范围保留并用于异常响应)。当消息从客户端发送到服务器设备时,功能代码字段告诉服务器执行何种操作。
功能代码 "0" 是无效的。

某些功能代码会添加子功能代码,用于定义多个操作。

从客户端发送到服务器设备的消息的数据字段包含服务器用于执行功能代码所定义操作的附加信息。这些信息可以包括离散值和寄存器地址、要处理的项目数量以及字段中实际数据字节的计数。

在某些类型的请求中,数据字段可能不存在(长度为零),在这种情况下,服务器不需要任何额外信息,仅通过功能代码即可指定操作。

如果在正确接收的 MODBUS ADU 中与请求的 MODBUS 功能无关的错误没有发生,则从服务器到客户端的响应数据字段将包含请求的数据。如果发生与请求的 MODBUS 功能相关的错误,则该字段将包含一个异常代码,服务器应用程序可以使用该代码来确定下一步应采取的操作。

例如,客户端可以读取一组离散输出或输入的开/关状态,或者可以读取/写入一组寄存器的数据内容。

当服务器响应客户端时,它使用功能代码字段来指示正常(无错误)响应或发生了某种错误(称为异常响应)。对于正常响应,服务器只是将原始功能代码回显给请求。


MODBUS 协议的数据单元结构:

  • 协议数据单元(PDU):MODBUS 协议的数据交换单位称为 PDU(Protocol Data Unit)。它包含了协议所需的基本信息,并且与底层的通信层(如 TCP/IP 或串行通信协议)无关。因此,PDU 的结构是固定的,独立于具体的网络或物理传输介质。

  • 应用数据单元(ADU):虽然 PDU 是 MODBUS 协议的核心部分,但当 MODBUS 被映射到具体的网络或总线上时,可能会在 PDU 上方增加一些额外的信息,这些信息构成了应用数据单元(ADU)。这些额外字段通常用于处理通信的具体细节,如网络地址、数据包的封装格式等。
    ADU 是协议在实际传输过程中的实际数据单元,它包括了 PDU 和其他相关的控制信息。

Note:
PDU 和 ADU 以及 PCI、SDU 等属于计算机网络中的的概念,详细内容参考计算机网络体系结构中对各层数据封装后的描述。以下简单陈述

例如:

Modbus协议中的 PDU协议数据单元(Protocol Data Unit))。在计算机网络中,它是网络通信中针对应用层 Modbus 数据传输的基本单位,而不同的网络协议层使用不同的 PDU 来封装数据。

PDU 在不同的协议层有不同的定义和格式,这里不以 OSI 七层参考模型为例,而是以实际应用的五层参考模型为例:

  1. 物理层:在物理层,PDU 被称为 比特(Bit),代表传输的最小单位,它是以电信号的形式在物理介质上传输的数据。

  2. 数据链路层:在数据链路层,PDU 被称为 帧(Frame)。它包括了源地址、目标地址、错误检测等控制信息以及实际要传输的数据。

  3. 网络层:在网络层,PDU 被称为 包(Packet)。它除了包含数据外,还包含了源和目标 IP 地址以及其他路由控制信息。

  4. 传输层:在传输层,PDU 被称为 段(Segment)或数据报(Datagram)。在 TCP 协议中,它还包括了源端口和目标端口号,帮助标识应用程序之间的通信。

  5. 应用层:在应用层,PDU 被称为 数据(Data),它通常是发送给用户应用程序的原始信息。

Modbus 作为应用层协议,其在应用层的 PDU 称为数据(Date)格式是固定的,其作为 SDU(服务数据单元)传递给下层的传输层,传输层根据本层的协议在上层的 SDU 上添加 PCI(协议控制信息)作为新的 PDU,也就是 Modbus 中所称的 ADU
将该 PDU 即 Modbus 中所称的 ADU 传递给下层,重复执行这个过程直到物理层。

总结来说,PDU 是数据在不同网络协议层中传输的载体,随着网络层次的不同,PDU 的形态和名称也有所不同。每个层次对 PDU 都有自己的一套封装规则和处理方式。


  1. 功能代码:在 MODBUS 协议中,功能代码字段用于指示服务器需要执行的操作。它由一个字节表示,功能代码的有效范围是 1 到 255,除去 128 到 255 范围(这些值用于异常响应)。每个功能代码对应一个特定的操作,比如读取数据、写入数据等。功能代码为 "0" 是无效的。

  2. 子功能代码:某些功能代码可以通过添加子功能代码来扩展操作的类型,允许一个功能代码支持多个不同的操作。

  3. 数据字段:在客户端到服务器的消息中,数据字段用于传递额外的信息,帮助服务器执行功能代码指定的操作。数据字段通常包含操作所需的详细信息,如地址、处理项的数量和数据字节的数量等。

  4. 无数据字段的请求:某些请求可能不包含数据字段(即数据长度为零),在这种情况下,服务器只需根据功能代码来确定要执行的操作,无需额外的信息。


在 MODBUS 协议中,响应的内容依赖于请求是否正确,以及是否发生了错误。

  1. 正常响应:如果客户端发送的请求在没有任何错误的情况下被正确处理,服务器将会在响应的数据字段中返回请求的数据,同时功能代码字段将回显请求中使用的功能代码。这意味着请求和响应的功能代码一致,表示正常的通信。

  2. 异常响应:如果在处理请求时发生了错误,服务器将返回一个异常响应,异常响应包含一个异常代码。这个异常代码告诉客户端发生了什么样的错误,客户端可以根据这个异常代码决定如何继续进行。异常响应有助于客户端识别问题并采取相应的措施。


对于异常响应,服务器返回一个代码,该代码相当于来自请求PDU的原始功能代码,其最高有效位设置为逻辑1。

Note:
最好管理超时,以避免无限期地等待可能永远不会到达的答案。

MODBUS PDU的大小受到首次在串行线网络上实现 MODBUS 时的大小限制(最大RS485 ADU = 256字节)。

因此:

串行通信的MODBUS PDU = 256 - 服务器地址(1字节) - CRC(2字节) = 253字节。

因此:

  • RS232 / RS485 ADU = 253字节 + 服务器地址(1字节) + CRC(2字节) = 256字节。
  • TCP MODBUS ADU = 253字节 + MBAP(7字节) = 260字节。

MODBUS协议定义了三种PDU(协议数据单元)。它们是:

  • MODBUS请求PDU,mb_req_pdu
  • MODBUS响应PDU,mb_rsp_pdu
  • MODBUS异常响应PDU,mb_excep_rsp_pdu

  • mb_req_pdu的定义:

    mb_req_pdu = {功能码, 请求数据}, 其中:
    - 功能码 = [1字节] MODBUS功能码,
    - 请求数据 = [n字节] 此字段依赖于功能码,通常包含如变量引用、变量计数、数据偏移量、子功能码等信息。

  • mb_rsp_pdu的定义:
    mb_rsp_pdu = {功能码,响应数据}, 其中:
    - 功能码 = [1字节] MODBUS功能码,
    - 响应数据 = [n字节] 此字段依赖于功能码,通常包含如变量引用、变量计数、数据偏移量、子功能码等信息。

  • mb_excep_rsp_pdu的定义:
    mb_excep_rsp_pdu = {异常功能码,请求数据}, 其中:
    - 异常功能码 = [1字节] MODBUS功能码 + 0x80,
    - 异常码 = [1字节] MODBUS异常码(参见“MODBUS异常码表”,请参见第7节)。


在Modbus通信中,PDU(协议数据单元)的大小是有限制的,这些限制主要源自最早在串行线(如RS485)上实现Modbus协议时的限制。具体来说,串行通信的MODBUS PDU最大只能为253字节,这是因为在每个数据包中需要保留1字节用于服务器地址以及2字节用于CRC校验。
总的来说,这使得在RS232和RS485串行通信中,数据包的总大小限制为256字节。

而在TCP通信中,虽然数据传输的格式不同,但由于增加了MBAP(Modbus Application Protocol)头部(7字节),因此在TCP模式下的MODBUS ADU(应用数据单元)总大小为260字节。

这些不同的通信方式和其数据包大小限制直接影响Modbus协议的应用和通信效率。

MODBUS协议通过定义三种不同的PDU来进行通信,分别是请求PDU(Request PDU)响应PDU(Response PDU)以及异常响应PDU(Exception Response PDU)
每种PDU的结构都有特定的字段,依赖于MODBUS的功能码(function code)。


4.2 数据编码

  • MODBUS使用“高位在前,大端”(big-Endian)表示法来表示地址和数据项。这意味着,当传输一个大于单个字节的数值时,高字节会先发送。例如:
寄存器大小
16位 0x1234

在这种情况下,首先发送的是0x12字节,然后是0x34字节。


4.3 MODBUS 数据模型

MODBUS 基于一系列具有不同特征的表格来构建其数据模型。主要的四个表格如下:

主要表格 对象类型 访问类型 说明
离散输入 (Discrete Input) 单比特 (Single bit) 只读 (Read-Only) 这种数据通常由 I/O 系统提供
线圈 (Coils) 单比特 (Single bit) 读写 (Read-Write) 可以被应用程序修改,通常由 I/O 系统提供
输入寄存器 (Input Registers) 16位字 (16-bit word) 只读 (Read-Only) 通常由 I/O 系统提供,并且只能读取
保持寄存器 (Holding Registers) 16位字 (16-bit word) 读写 (Read-Write) 可以由应用程序修改

输入与输出的区分,以及比特寻址和字寻址数据项的区分,并不意味着任何特定的应用行为。如果在目标机器上最自然的解释是将这四个表格视为重叠在一起,那么这样做是完全可以接受且非常常见的。

对于每个主要的表格,协议允许单独选择 65536 个数据项,且对这些数据项的读写操作设计为跨越多个连续的数据项,直到数据大小达到一个由事务功能码决定的限制。

显然,通过 MODBUS 处理的所有数据(比特、寄存器)必须位于设备应用程序的内存中。但需要注意的是,内存中的物理地址不应与数据引用混淆。唯一的要求是将数据引用与物理地址链接。

MODBUS 逻辑引用号在 MODBUS 函数中使用,它们是从零开始的无符号整数索引。


MODBUS 通过四个主要的数据模型组织数据,它们分别是离散输入、线圈、输入寄存器和保持寄存器。每种模型有其独特的功能和访问权限,离散输入和输入寄存器为只读,而线圈和保持寄存器则支持读写操作。理解这些基本数据类型是使用 MODBUS 协议进行设备间通信的关键。

MODBUS 数据模型中的输入和输出数据类型并不暗示特定的应用行为。在某些情况下,可以将四个数据模型重叠使用,这取决于目标机器的实现方式。

MODBUS 协议支持对每个数据模型中的 65536 个数据项进行选择,且读写操作可以跨越多个连续数据项,具体的范围取决于功能码的要求。

尽管所有数据必须存储在设备的内存中,MODBUS 协议要求的仅仅是数据引用与物理地址的关联,而不是直接的内存地址。

MODBUS 使用从零开始的无符号整数作为逻辑引用号,用于标识数据项。

MODBUS 数据模型的实现示例

下面的示例展示了在设备中组织数据的两种方式。虽然还有其他组织方式,但并非所有方式都在本文件中描述。每个设备可以根据其应用需求,拥有自己的数据组织方式。

  • 示例 1:具有 4 个独立模块的设备
    下面的示例展示了在一个设备中,数字和模拟输入输出的数据组织方式。每个模块是独立的,因为不同模块之间的数据没有相关性。因此,每个模块可以通过不同的 MODBUS 功能进行访问。

    设备内存被划分为多个独立的模块,每个模块都可以通过不同的 MODBUS 功能进行访问。这些模块包括:

    • Input Discrete (输入离散量):这是设备的输入离散量部分,通常用于表示数字输入,如开关状态。
    • Coils (线圈):线圈是设备的输出部分,通常用于控制继电器等开关设备。
    • Input Registers (输入寄存器):用于存储输入的模拟信号数据,通常用于传感器读取的模拟值。
    • Holding Registers (保持寄存器):用于存储输出的模拟信号数据或设备配置数据,通常用于控制输出设备或设置设备参数。

    图中的 MODBUS 服务器设备 部分,数据模型的各个块是通过 MODBUS 协议进行访问的。MODBUS 客户端(通常是控制系统或其他设备)通过发送 MODBUS 请求 来访问服务器的数据模型,称为Modbus access

    1. 数据组织方式:图中展示的设备内存结构通过不同的模块将数据进行分类,按照数据类型(离散量、线圈、寄存器等)来划分内存区域。每个模块之间的数据没有相关性,意味着它们可以独立访问,这符合我们之前讨论的将不同功能的模块分开处理的设计原则。

    2. 模块化设计:设备通过多个独立的数据块来组织不同类型的数据,这使得每个模块可以使用不同的 MODBUS 功能来访问。例如,客户端可以选择使用 Read CoilsRead Input Registers 来分别访问线圈和输入寄存器的数据。这种模块化设计不仅增强了数据访问的灵活性,还使得设备管理更加简洁高效。

    3. 设备内存分配:从图中可以看出,设备的应用内存(Device application memory)是如何按需分配给不同类型的寄存器和离散量的。这种分配保证了设备可以高效地处理不同类型的数据,同时使得不同类型的数据可以通过专门的功能进行读写操作,避免了不必要的冲突或数据混乱。

    4. MODBUS 请求:在实际的 MODBUS 通信中,客户端发送请求并指定要访问的寄存器或离散量。在图中,黄色箭头指向了 MODBUS 请求,这表明客户端可以根据需要选择访问的模块,发送相应的读取或写入请求。

  • 示例 2:只有1个块的设备

    在该示例中,设备只有1个数据块。通过多个MODBUS功能,可以通过16位访问或通过访问位访问相同的数据。

图中展示了一个 MODBUS 数据模型,该模型与上一个示例不同,设备只有一个数据块。设备内存被统一组织在一个单一的内存块中,而不同的数据类型(如离散量、线圈、寄存器等)都共享同一块内存。这块内存可以通过多种 MODBUS 功能来访问,既可以通过 16 位访问,也可以通过位访问。

图中标注了 RW,这分别表示读取(Read)和写入(Write)操作。箭头指向设备内存块的不同位置,表示不同类型的 MODBUS 请求(例如,读取输入离散量、线圈、输入寄存器和保持寄存器)的访问方式。

  1. 单一数据块设计:与第一个示例中的多个独立模块不同,这种设计将所有的数据都集中在一个单一的内存块中。这意味着,设备内存没有按照数据类型或功能分块,而是将所有的数据(无论是离散量、线圈、寄存器等)都组织在一起,按需访问。

  2. 多种访问方式:图中展示了可以通过不同的 MODBUS 功能进行数据访问的方式:

    • 16 位访问:这意味着通过 16 位的功能来访问设备内存中的数据(如读取寄存器)。
    • 位访问:通过位级别的功能(例如,读取或写入离散量或线圈)来访问设备内存的特定位。

    这种设计让用户可以灵活选择访问的方式,无论是处理 16 位的数据还是单个比特的数据,都是通过同一个内存块进行的。

  3. 设备内存的共享:由于所有数据都在同一个内存块中,MODBUS 客户端可以通过不同的功能码选择访问不同类型的数据。这种共享内存的方式使得设备设计更加简单,但可能会在不同数据类型之间产生一些复杂性,尤其是在需要区分数据类型时。

  4. 数据访问模式:图中的 RW 操作表示读取和写入操作。这意味着客户端可以通过 MODBUS 协议请求从内存中读取数据或写入数据,不同的数据类型(如离散量、线圈、寄存器)都可以通过相同的内存块来完成读写操作。


4.4 MODBUS 寻址模型

MODBUS应用协议明确定义了PDU(协议数据单元)寻址规则。在一个MODBUS PDU中,每个数据的地址范围从0到65535。

它还清晰地定义了一个由4个块组成的MODBUS数据模型,该模型包含多个编号从1到n的元素。在MODBUS数据模型中,每个数据块内的元素编号从1到n。

随后,MODBUS数据模型必须与设备应用进行绑定(例如,IEC-61131对象或其他应用模型)。MODBUS数据模型与设备应用之间的预映射是完全由设备厂商定义的。

上图显示编号为X的MODBUS数据在MODBUS PDU X-1中寻址。


图 figure8 展示了MODBUS寻址模型的概念,以及设备应用、MODBUS数据模型和MODBUS PDU地址之间的关系。图中的三个主要部分分别表示:

  1. 设备应用(Device Application)
  2. MODBUS数据模型(MODBUS Data Model)
  3. MODBUS PDU地址(MODBUS PDU Addresses)

设备应用(Device Application)

图左侧展示了设备应用的框架,其中标记了几个区域,代表了不同功能或数据类型的存储位置。这些区域和MODBUS协议中的数据类型有映射关系。例如,设备应用中的数据块和MODBUS数据模型中的数据块之间的映射关系。

MODBUS数据模型(MODBUS Data Model)

中间部分显示了MODBUS数据模型的结构,具体包括以下几个数据块:

  • Discrete Input(离散输入):数据模型中的离散输入块,在MODBUS中通常用来表示输入状态,如开关的状态。
  • Coils(线圈):这是一种常见的MODBUS数据类型,用于表示输出的状态或控制信号。
  • Input Registers(输入寄存器):输入寄存器用来表示设备的输入数据,例如传感器的值。
  • Holding Registers(保持寄存器):这些寄存器用于表示设备的输出数据或需要保持的配置参数。

每个数据块中的元素(例如离散输入的编号、线圈的编号等)从1到n编号,代表不同的地址。

MODBUS PDU地址(MODBUS PDU Addresses)

右侧部分显示了MODBUS PDU地址的示例。这些地址对应MODBUS协议中的PDU部分,PDU用于在通信中传递实际的数据。图中列举了几个常见的MODBUS功能码,如:

  • Read input 0:读取离散输入(Discrete Input)的地址0。
  • Read coils 4:读取线圈(Coils)地址4。
  • Read Registers 1:读取输入寄存器(Input Registers)地址1。
  • Read Registers 54:读取保持寄存器(Holding Registers)地址54。

图中的箭头表示了设备应用与MODBUS数据模型以及MODBUS PDU地址之间的映射关系。每个设备应用中的数据块,通过映射关系与MODBUS协议中的数据类型和地址一一对应。这一映射是特定于厂商的(Vendor specific),因此每个厂商的设备可能有不同的实现方式。

4.5 定义 MODBUS 事务

下面的状态图描述了服务器端 MODBUS 事务的一般处理。

一旦服务器处理了请求,就会使用适当的 MODBUS 服务器事务来构建MODBUS响应。

根据处理的结果,建立两种类型的响应:

  • MODBUS 正确响应:
    • 响应函数代码 = 请求函数代码
  • MODBUS 异常响应 (参见第7节):
    • 目的是向客户提供有关处理过程中检测到的错误的相关信息;
    • 异常功能代码 = 请求功能代码 + 0x80;
    • 提供异常代码以指示错误原因。

Figure9 这张图展示了MODBUS事务状态图,它描述了MODBUS协议在服务器端如何处理请求的通用流程。图中使用了状态转换图,展示了从接收请求到发送响应的过程,同时也包括了错误处理的部分。

  1. Wait for a MB indication(等待MB指示)

    • 这一步是服务器端的初始状态,表示它在等待MODBUS(MB)请求到达。通常,服务器在此状态下处于空闲,等待来自客户端的指令。
  2. Validate function code(验证功能码)

    • 当接收到MB指示(Receive MB indication)后,服务器首先验证请求中的功能码。功能码是MODBUS协议中用于区分不同操作类型的代码,例如读取输入寄存器、写入线圈等。
    • Invalid(无效):如果功能码无效,服务器将直接进入异常处理流程,发送MODBUS异常响应。
    • Valid(有效):如果功能码有效,接下来验证数据地址。
  3. Validate data address(验证数据地址)

    • 这是验证MODBUS请求中的地址是否合法。地址可以是输入寄存器、保持寄存器等的数据起始位置。
    • Invalid(无效):如果数据地址无效,服务器进入异常处理流程,发送MODBUS异常响应。
    • Valid(有效):如果数据地址有效,接下来验证数据值。
  4. Validate data value(验证数据值)

    • 此步骤验证MODBUS请求中的数据值是否在合法范围内。例如,写请求中所携带的值是否超出了寄存器的范围。
    • Invalid(无效):如果数据值无效,服务器进入异常处理流程,发送MODBUS异常响应。
    • Valid(有效):如果数据值有效,服务器执行相应的MODBUS功能。
  5. Execute MB function(执行MODBUS功能)

    • 如果所有验证都通过,服务器将执行MODBUS功能。具体功能可能是读取或写入某个寄存器、线圈等。
  6. Send Modbus Response(发送MODBUS响应)

    • 最后,服务器根据执行结果,发送相应的MODBUS响应。如果操作成功,响应会携带读取的数据或者写入确认等。如果出现异常,响应会返回异常代码。

异常处理(Exception Codes)

图中的异常处理部分说明了MODBUS事务可能出现的不同错误,以及每个错误对应的处理逻辑。异常代码(ExceptionCode)有多个值,每个值代表不同的错误类型:

  • ExceptionCode = 1(无效功能码)

    • 如果请求中的功能码无效,服务器会返回异常响应,表示请求无法处理。
  • ExceptionCode = 2(无效数据地址)

    • 如果请求中的数据地址不在合法范围内,服务器会返回异常响应,表示请求无法处理。
  • ExceptionCode = 3(无效数据值)

    • 如果请求中的数据值无效(例如超出允许的范围),服务器会返回异常响应。
  • ExceptionCode = 4, 5, 6(执行错误)

    • 如果发生其他错误(例如硬件故障、内部错误等),服务器会返回相应的异常响应。

状态图流程总结

  1. 等待请求:服务器在初始状态下等待MODBUS请求。
  2. 验证请求
    • 检查请求的功能码、地址和数据值是否合法。
    • 如果请求无效,服务器将生成并发送异常响应。
  3. 执行功能:如果请求有效,服务器根据请求执行相应的功能(例如读取寄存器、写入寄存器等)。
  4. 发送响应:服务器将根据执行结果发送MODBUS响应,如果操作成功,则返回操作结果;如果出现异常,则返回异常代码。

5 功能码类别

MODBUS功能码有三个类别,分别是:

  • 公共功能码

    • 经过明确定义的功能码,
    • 保证唯一,
    • 经MODBUS.org社区验证,
    • 已公开文档化,
    • 提供合规性测试,
    • 包括已定义的公共分配功能码以及为未来使用预留的未分配功能码。
  • 用户自定义功能码

    • 用户自定义功能码有两个范围,即65到72和100到110(十进制)。
    • 用户可以选择并实现一个规范中未支持的功能码。
    • 不保证所选择的功能码将是唯一的。
    • 如果用户希望将该功能的功能码重新定位为公共功能码,必须启动RFC(请求更改提案)以将该更改引入公共类别,并为其分配一个新的公共功能码。
    • MODBUS组织明确保留开发提议的RFC的权利。
  • 保留功能码

    • 一些公司目前为其遗留产品使用的功能码,这些功能码不可供公众使用。
    • 说明性注释:读者请参阅附录A(说明性)《MODBUS保留功能码、子码和MEI类型》。

公共功能码(Public Function Codes)是MODBUS协议中非常重要的组成部分,它们用于确保MODBUS设备之间的互操作性和标准化。以下是关于公共功能码的几个要点:

  1. 明确定义:每个公共功能码都有明确的定义,确保在各种设备和实现中都能够正确理解和使用这些功能码。

  2. 唯一性:每个公共功能码都是唯一的,没有重复,这保证了功能码在不同设备之间的识别不会出现冲突。

  3. 验证与标准化:这些功能码经过MODBUS.org社区的验证,符合行业标准,确保它们能够广泛应用于实际的设备和系统中。

  4. 公开文档:公共功能码的定义是公开的,任何开发者都可以查看相关文档,确保开发时能够正确实现这些功能。

  5. 合规性测试:为公共功能码提供合规性测试,帮助开发者验证他们的实现是否符合MODBUS标准,确保系统的兼容性。

  6. 预留的未分配功能码:除了已定义的公共功能码外,MODBUS还保留了一些未分配的功能码,以便未来能够扩展协议,增加新的功能。

在MODBUS协议中,用户可以根据自己的需求定义功能码,这些功能码不一定受到标准协议的限制。用户自定义功能码的范围是从65到72和从100到110(十进制),这为用户提供了一定的灵活性,允许他们在标准协议之外定义新的功能。

然而,需要注意的是,使用这些自定义功能码时,并不能保证它们在全世界范围内的唯一性。这意味着,其他用户或设备也可能使用相同的功能码,因此可能会出现冲突。

如果用户希望将自己的自定义功能码作为公共功能码发布,以便在未来被更多的设备和系统广泛采用,他们需要通过RFC(请求更改提案)来发起变更申请。通过RFC,用户可以提议将这些功能码正式纳入公共标准类别,并且会为其分配新的公共功能码。

MODBUS组织对于这些提议具有决定权,可以决定是否采纳和发展这些新的功能码提案。这样的流程确保了标准的稳定性,同时也为创新提供了空间。

在MODBUS协议中,有一些功能码被保留用于特定公司或厂商的遗留产品,这些功能码并不向公众开放使用。这些保留功能码通常是为了兼容旧版本设备或满足特定厂商的需求。因此,普通用户或开发人员不应使用这些功能码,以避免与其他标准化功能码发生冲突。

此外,协议文档中提到读者应参考附录A,这部分内容通常包含对这些保留功能码、相关子码以及MEI(Message Elements Identifiers,消息元素标识符)类型的详细描述。对于开发者来说,这些信息有助于更好地理解和避免使用不适当的功能码。

5.1 公共功能代码定义