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等。
全部0条评论
快来发表一下你的评论吧 !