技术论坛

 1200自由口通信的报文和长报文的底层分析

返回主题列表
作者 主题
宝冬
侠圣

经验值:3734
发帖数:671
精华帖:10
楼主    2021-02-26 18:17:46
主题:1200自由口通信的报文和长报文的底层分析 精华帖 

上面的GIF截屏,是1200的485端口(CB1241)与一个温控器之间的Modbus通信。一个03功能码读取35个保持寄存器的主从问答的循环执行,在示波器上的波形所见。这个Modbus的Master功能是用自由口指令做的。

 

1、位于最前面保持不动的短报文是1200发出的03码查询。在自由口通信的程序中,它是一个长度为8字节的报文。体现到示波器的波形上,它是一个长度为80个bit的报文,为什么呢?

这里先说一下485端口的设定,9600,N,8,1。9600bps的波特率意味着传输一个bit数据需要的时间基本上就是0.1ms。另外,消息起始条件是任意字符,消息结束条件会在后面单独说。

因为端口设定无校验,所以没有校验这一个bit位。数据位是8位,结束位是1位,默认还要加上1个起始位。那么自由口程序报文中的1个字节,在线路传输中实际是10个bit的数据传输。每个字符的传输长度是10bit,也就是需要1ms的时间。

那么一个8字节的03码查询,在示波器上看到的波形就是一个长度为80bit持续时间为8ms的波形报文。这和GIF截屏中看到的一致。

波形如果放大,是可以直接从中读出报文的。从波形读取报文的时候要注意,起始位是低电平,数据1是高电平,数据0是低电平,结束位是高电平。8个数据位中,低位先发高位在后,前后倒序。

我的示波器10:1探头是连接485的A,地线是连接的B,波形呈反相,也就是上下颠倒。读报文的时候要上下翻转过来看。下面是分析的例子。


刚开始读波形报文的时候会很慢,一个一个bit核对。读多了就熟练了,打眼一看就知道,会快起来,七八百bit长的报文用眼睛读完全没问题,和程序中的报文或者串口软件捕捉的报文能完全对上,一个bit都不会差。

这要求示波器的采样率要够快。我用的便携式示波器,采样率1G。如果是台式示波器,视图会更好,波形刷新率会更高。

 

2、GIF截屏中靠后面的,有水平前后位置抖动的长报文,就是温控器对03查询的应答报文。程序中这个报文长度是35*2+5(头部3个协议字节,尾部CRC的2个字节)=75字节,体现在波形上是一个750 bit的报文。

大家会看到这个应答报文中断开了一个豁口。这个豁口的出现意味着它是一个长报文。

什么是长报文呢?对于这个温控器而言,长度超过65字节就是长报文。对于其它的modbus设备是否也是这样呢?我不能确定。

这个豁口意味着什么呢?很容易想到的是一个仪表的通信缓冲区大小是有限的。它一次能处理的通信数据是有限的,也就是它的通信速度的能力是有限度的。

如果让它一次发送10000个字节,那一定是分批处理一波一波的。豁口代表批次中间的空闲状态。

超过限度的数据长度,决定了豁口的宽窄。监测中可以看到,随着报文超限长度的不同,这个豁口的宽度是变化的。也就是它处理又一批数据的时间,会根据数据处理量变化。

上面说的是从站应答的实际情况。

 

3、那么1200的485端口接收到的报文,反映到Receive_P2P指令的缓冲区中的实际情况又是怎样的呢?这就和前面提到的消息结束条件的设定有关。

如果采用超时做为结束条件。超时分为两种,整个报文持续时间超时和应答时间超时,其中应答时间超时不能单独使用。这种情况下缓冲区一般会把这整个消息做为一帧数据接收,忽略中间的豁口。

如果是采用报文字符之间的间隔时间做为结束条件,那么会出现两种情况。

首先大家看到GIF截屏中,这个豁口的宽度是抖动变化的。也就是对同一个查询指令,每次的应答,这个豁口的间隔时间也是变化不同的。

如果这个豁口比较窄,缓冲区也会把这整个报文做为一帧数据接收,忽略中间的豁口。

如果这个豁口有点宽,超过一个程度(我的观察是大约8~9ms),缓冲区会把豁口后面报文的超长部分做为另一帧数据接收。


我在试验中的观测是通过单元机制来进行:每执行一次主从问答,通信程序会自动停止,这时候有充分时间观察和分析和调整数据。然后在监视表中再次触发,会再进行一次主从问答,然后再次自动停止。这样也方便在示波器上捕捉和观察每回单次问答之间的报文差别。


我的通信程序有个开关。开关On的时候,通信就是单次执行,手动继续。关闭Off,就恢复连续轮询的正常执行。而且从站通信任务队列中的每一个任务,不论读写,都是可以单独控制本次轮询是否执行,这样便于我观察特定功能码的不同读写任务的报文,在示波器上的单个呈现。


在观察中,超时做为结束条件的结果都是把整个消息做为一帧接收。而字符间隔的条件下,就出现上述的2种情况。

但受实验条件所限,没法很长时间的观察,不排除有些情况下,超时条件的报文也会被断开。而且连续高速运转工作下的电气特性可能和单元执行的时候不一样,也可能出现断开的情形。没有做更多的测试,因为跑不出这两种情形,不会影响应对策略。


上面的描述总结就是一句话:当消息长度超过65字节,缓冲区中接收到的可能是完整的1帧报文,也可能被断开成2帧,甚至更多帧报文,要看消息总长度了。


前面提到从站报文65字节这个分界点,其实真正的分界点是在64。为什么这么说呢?

实测中,如果应答报文的长度恰好是65,也就是读取30个寄存器,那么第65个字节的数据实际上是错误的。这个时候的第64和65字节本应该分别是CRC校验的低字节和高字节。而实际情况是低字节正确,高字节不对,这个温控器是固定把16#11填充到第65字节中。这表明这个温控器的发送缓冲区大小应该是64字节,CRC高字节被丢掉了。

如果读取的数据长度超过30个寄存器,报文全长超过65字节,应答报文会开始出现豁口。这时候应答报文最后的CRC校验已经不是对整个报文的校验了,而是只对豁口后面数据的校验。

那么豁口在整个消息中出现的精确位置在哪里呢?如果整个消息总长超过65字节,豁口出现在第63字节之后。为什么是这样呢?

寄存器都是双字节,而读寄存器的指令会额外加上5个字节,所以报文的全长一定是奇数。也就是会有一个字的两个字节是骑跨在64这个分界线上(第64和65字节)。这也就是为什么从63字节之后用豁口分隔开,以保持一个数据字的传输完整。

 

4、上面这些不同的场景,导致对接收数据会存在4种不同的CRC验证策略。而接收数据要循环进行。

如果读取小于30个数据,那么对全部数据进行正常的CRC校验。

如果读取等于30个数据,那么也是对全部数据进行正常的CRC校验,但只取低字节核对。

如果读取大于30个数据,如果串口缓冲区忽略豁口,把全部报文做为一帧接收,那么CRC校验的起点就不能从缓冲区的0字节开始,要向后滑动一个长度单位,这里就是63。

如果读取大于30个数据,如果串口缓冲区不忽略豁口,而是把豁口后面的报文做为另一帧接收。那么可以对最后这一帧按照正常CRC校验。

 

5、上面说的都是关于报文和长报文的一些要点和处理方式。

实践中线路很可能还会窜入干扰帧,也就是错误杂乱信息。而自由口本身是不分对错的。

接收的时候要分析和忽略,循环接收,整合形成正确报文。这里面的健壮性不是100%的,串口通信不像TCP,很难对每一帧进行精确核对和合成。但是合理的策略会大大降低错误率,实现比较好的实用健壮性。


在我的测试中,温控器485的AB两根线,是同时接到1200的485串口和另一个ModbusTCP网关的485串口。为的是同时测试同一个modbus设备FB块的RTU和TCP两种执行模式,让两者可以随时自由切换。

1200通过这两条路和这两种modbus方式可以通信到温控器,任一时间只有一种方式在工作。RTU和TCP之间的模式切换是没有等待时间的。在切换这个瞬间,485网络中会有残存的数据帧造成干扰。

当设备FB的执行从RTU切换到TCP的时候,1200的Master功能是停掉了。ModbusTCP具体执行情况完全看网关自身串口算法对线路噪声的处理策略。实测中偶尔会有一次错误。

从ModbusTCP切换回Modbus RTU的时候,串口执行的细节就完全受PLC程序控制了。通过策略实现了完全0错误,不受网络中残余帧的影响。


6、其实也不是绝对不能精确验证串口通信的每一帧。端口组态中关于消息起止设定,特殊起始字符和特殊结束字符那些可以干这个用。

但是现实中,我们总是购买使用别人生产出来的现成设备,一般都是固化的标准协议,自己没法改。除非是自己开发系统,发送和接收两端都是自己设计定制出来的,这样才可以。但现实中往往不是这样。

博途里面的自由口通信不太受重视了。不像200Smart给提供底层缓冲区的中断,可以灵活定制。


大家平时一般都是用串口助手这类软件来监听串口报文,但是这些报文都是被串口软件合并了之后的,根本不会看到长报文中存在分隔豁口的事情以及CRC的一些变数与此的关联。


上面这些都是通过程序的测试和观察得来的。这也提示了一个很重要的问题,程序应该是设计成可观察调试、可扩展的结构,而不仅仅是满足基本应用功能的。一个好的FB应该是可以维护和诊断自己,可以灵活定制的玩具。


您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。