Modbus通信协议报文分析

描述

10.4.7 字节序和大小端

Modbus中传输的数据,按照“大字节序”来传输,比如:

寄存器

寄存器数值是0x1234,先传输0x12,再传输0x34。

在Modbus寄存器中,对于一个由2字节组成的16数,在内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址为小端(Little-Endian)字节序;另一种方法是将高序字节存储在起始地称为大端(Big-Endian)字节序。Modbus通信协议中具体规定了字节高低位发送顺序,这样就自然引出了字节序和大小端的问题。

①什么是大端:

所谓大端,是指数据的低位保存在内存的高地址中,数据的高位保存在内存的低地址中。

②什么是小端:

所谓小端,是指数据的低位保存在内存的低地址中,数据的高位保存在内存的高地址中。

③为什么会有大小端:

计算机系统是以字节为单位的,每个地址单元都对应着1个字节,一个字节为8bit。但在C语言中除了8bit的char类型,还有16bit的short类型和32bit的long类型,还有就是对于位数大于8位的处理器,如16位或32位的处理器,由于寄存器宽度大于一个字节,那么必然存在一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式的出现。

低位字节和高位字节:比如123456其中的1就是高位数字,6就是低位数字。

举一个例子,在32位数字0x12345678在内存中的表示形式为:

1)大端模式:

低地址 —— —— 高地址
0x12 0x34 0x56 0x78

2)小端模式:

低地址 —— —— 高地址
0x78 0x56 0x34 0x12

10.4.8 Modbus报文分析

在第二章中我们已经生成了一个报文,我们就拿此报文来逐步分析一下,报文如下:

寄存器

我们可以看到上面报文都是循环发送的,这样看起来不太容易分析,摘抄下来其中一组来给大家分析:

发送:

从机
地址
功能码 起始地址高位 起始地址低位 寄存器数量高位 寄存器数量低位 CRC
高位
CRC低位
01 03 00 00 00 0A C5 CD

响应:

从机地址 功能码 返回字节数 数据位 CRC高位 CRC低位
01 03 14 00 42… CF 10

这里我们就以03功能码为例来分析一下报文:

03发送报文格式:从机地址+功能码+加起始地址+寄存器数量+CRC校验

03接受报文格式:从机地址+功能码+字节数+具体数据+CRC校验

首先我们看一下发送报文:

从机地址是01,功能码03,起始地址00,寄存器数量是十六进制0A也就是10,和门设置的是一样的,我们来对对照一下我们设置的参数:

寄存器

我们再来看一下接收报文:

从机地址是01,功能码03,返回字节数是十六进制14也就是返回20给字节,我们发送是个返回20个字节也是对的上的,第一个数据位是00 42也是和我们发送的可以对上,十六机制42,也就66,我们来看一下我们之前设置的参数:

寄存器

10.4.9 Moubus TCP消息帧格式

1. 协议描述

在Modbus TCP/IP中,串行链路中的主/从设备分别演变为客户端/服务器端设备,即客户端相当于主站设备,服务器端设备相当于从设备。基于TCP/IP网络的传输特性,串行链路上一主多从的机构也演变为多客户端/多服务器端的构造模型。Modbus协议在TCP/IP上的实现是在TCP/IP层上的应用,它需要一个完整的TCP/IP栈作为支撑,Modbus TCP/IP服务器端通常使用端口502作为接收报文的端口。

下图为Moubus TCP的通讯结构:

寄存器

ModbusTCP与ModbusUDP的报文格式是一样的,它们之间的区别其实就是TCP与UDP的区别,因此下面就针对ModbusTCP的协议进行分析,ModbusTCP与ModbusRtu(ModbusASCII)之间的区别如下图:

寄存器

从上图可以看出,ModbusTCP在Modbus串行通信的基础上,去除了校验(由于TCP本身就带有校验和)和设备地址(ModbusTCP弱化了设备地址,用IP地址来取代),再加上MBAP报文头(占7bytes),下面针对MBAP进行分析说明:

寄存器

事务处理标识符:

事务处理标识用于在查询报文与未来响应之间建立联系。因此,对TCP/IP连接来说,在同一时刻这个标识符必须是唯一的。有以下几种使用此标识符的方式。

例如,可以将传输标识作为一个带有计数器的简单“TCP发送顺序号”,在每个请求发送时自动+1;也可以用作智能索引或指针,用来识别事务处理的内容,以便记忆当前的远端服务器和未处理的请求。

服务器端可接收的请求数量取决于其容量,即服务器资源量和TCP窗口尺。

同样,客户端同时启动事务处理的数量也取决于客户端的资源容量。

单元标识符:

在对Modbus或Modbus+等串行链路子网中的设备进行寻址时,这个域用于路由的目的。在这种情况下,单元标识符(Unit Identifier)携带一个远端设备的Modbus从站地址。

如果Modbus服务器连接到Modbus+或Modbus串行链路子网,并通过一个网桥或网关配置这个服务器的IP地址,则Modbus单元标识符对识别连接到网桥或网关后的子网的从站设备是必需的。TCP连接中的目的IP地址识别了网桥本身的地址,而网桥则使用Modbus单元标识符将请求转交给正确的从站设备。分配给串行链路上的Modbus从站设备地址为1~247(十进制),地址0作为广播地址。

对单纯的Modbus TCP/IP设备来说用IP地址即可寻址Modbus服务器端设备,此时Modbus单元标识符是无用的,必须使用值0xFF填充。当对直接连接到TCP/IP网络上的Modbus服务器寻址时,建议不要在“单元标识符”域使用有效的Modbus从站地址。

以上是MBAP报文头个字段含义的详细说明。

实际上,在Modbus TCP/IP传输过程中,服务端(从机)返回的响应报文中同样包含MBAP报头,除了Length字段外,其他字段均与客户端一致。Modbus消息TCP/IP层提供,不需要像串行链路那样自己判断一帧是否结束,所有数据传输均由TCP/IP层处理。因为底层TCP/IP确保了端到端的连接,而且TCP/IP链路层已确保传输数据的准确性,所以Modbus TCP/IP中已不再需要LRC或CRC等校验功能。

2. 查询与响应报文示例

对于Modbus TCP消息帧格式,下面举例说明各部分的含义。

①查询报文:00 00 00 00 00 06 09 03 00 04 00 01。

1)0x06:后续还有6字节。

2)0x09:单元标识符为9。

3)0x03:功能码3,即读保持寄存器的值。

4)0x00 0x04:Modbus起始地址4(即40005)。

5)0x00 0x01:读取寄存器个数为1。

②响应报文:00 00 00 00 00 05 09 03 02 00 05。

1)0x05:表示后续还有5字节。

2)0x09:同查询报文,单元标识符。

3)0x03:功能码,同查询报文。

4)0x02:返回数据字节数。

5)0x00 0x05:寄存器的值。

可见,在Modbus TCP模式下,差错校验字段已不复存在。但在某些特殊场合,例如串行Modbus协议转Modbus TCP的情况下,串行协议数据可以完整地装载到Modbus TCP的数据字段,这时CRC或LRC差错校验字段仍然存在。例如,Modbus RTU Over TCP/IP或Modbus ASCII Over TCP/IP等。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分