Modbus RTU转TCP后一堆怪毛病?问题多半出在网关的超时和缓冲
前面几篇讲的都是"直接拉 485 总线"的场景。现在越来越常见的做法是:现场段仍是 RS485,往上位机方向转成以太网——中间隔着串口服务器或 RTU-TCP 网关。这一转,很多新问题就来了。而且有个共同特点:单看 485 段没毛病,单看以太网段也没毛病,毛病出在两者接缝上。先分清三种"上 TCP"的方式,坑各不相同。一、三条路,别混透传模式(串口服务器/虚拟串口) — 网关只做"透明管道",上位机通过虚拟串口软件像操作本地 COM 口一样收发原始 RTU 帧。网关不理解内容,也就不理解时序——3.5T 帧间隔、换向时序这些前面聊过的东西,全靠两端软件自觉。协议网关模式(RTU over TCP) — 网关理解 Modbus 报文,TCP 侧收到请求后转成 RTU 发到串口侧,收到应答再回 TCP。组态软件直接配"Modbus TCP + 从站 IP"。主动上报模式 — 网关定时轮询下游从站,把结果主动推到云端/服务器。本地不跑主站程序。分清方式的意义:透传的问题按"串口链路"查,网关的问题按"主站逻辑"查。方式没搞清楚,查的方向就是错的。二、透传模式的三个坑坑 1:虚拟串口把"流"当"帧"虚拟串口软件按字节流转发,不做任何分帧。主站程序里"读一次 COM 口就认为收到一个完整帧"的逻辑,在透传链路上会碎掉——TCP 的分段、以太网的 MTU 都会让一帧被拆成几次到达,或者两帧粘成一次到达。现象:本地直连测试全对,挂上网关就时好时坏,且错的位置每次不一样。解法:主站程序按空闲超时判帧(超过 3.5T 无新字节即认为一帧结束),或直接按功能码+字节数解帧。凡是按"固定读取长度"写的收包代码,透传模式下都得改。坑 2:透传把 3.5T 帧间隔拉长虚拟串口软件的打包周期(很多默认 10~20ms 才攒一批发送)会让帧间隔远超 3.5T。这对"一问一答"影响不大,但主站用广播帧 + 紧跟下一帧的时序时,下游从站会粘帧。解法:透传模式下避免广播;或把网关的打包周期改到最小。坑 3:TCP 断了但没人知道网关和上位机之间的 TCP 连接因为网络抖动断了,虚拟串口软件不一定会通知应用层。主站程序以为串口还在,其实发出去的数据早就石沉大海,表现是"突然全部超时,重启组态软件才恢复"。解法:应用层必须有心跳和自动重连。这一条没做,透传链路的可用性上限就被锁死了。三、协议网关模式的坑:都在"翻译"上坑 1:Unit ID 的两重含义Modbus TCP 报文里的 Unit ID 字段,在协议网关模式下通常被映射为下游 485 总线的从站地址。但有的网关固件把这个字段留着不用,固定发给下游某个地址;还有的网关自身也是一台"虚拟从站"(占一个 Unit ID),只有特定 Unit ID 才触发透传。现象:换了一台网关,组态里的从站号全对不上。解法:新网关上线先做一件事——用抓包工具看一遍"TCP 侧收到的 Unit ID X"是否真的转成了"485 侧地址 X"。确认映射规则再配点表。坑 2:超时预算被两头瓜分网关模式下链路是两段:TCP 侧等待 + 485 侧应答。网关自己有一个"下游应答超时"(常见默认 100~1000ms),主站还有一个自己的超时。典型事故:主站超时设 200ms,网关的下游超时设 1000ms。慢从站 300ms 才应答——网关等到了,但主站早就判超时并重发了。重发帧到达网关时,网关还在等第一帧的应答,产生队列堆积,于是越慢越重发、越重发越慢,整条总线雪崩。解法:主站超时 > 网关下游超时 + 485 段最坏应答时间,一层比一层短,且每层都留余量。慢设备单独配置,全局一个超时值是网关场景下的头号杀手。坑 3:从站离线时网关"编数据"不少网关在下游从站无应答时,会回一个全 FF 填充的响应而不是异常帧(前面误码篇提过这个现象)。更过分的是个别固件会回"上一次缓存的数据"。这比报错危险得多——数据看起来是好的,其实是编的。画面不报警,库里全是错的。解法:新网关验收时专门做一项测试——拔掉一台从站,看上位机收到的是异常帧、FF 填充还是旧数据。是旧数据的网关直接退场。坑 4:并发请求被排队或被拒组态软件十几个线程同时发请求,透传网关如果不支持多事务排队,会丢弃或错乱。MBAP 头里的 事务标识符(Transaction ID) 本来就是为并发设计的,网关必须逐一把请求和应答对上。现象:多客户端接入时丢包、张冠李戴(1 号泵的数据出现在 2 号泵的点位上)。解法:查网关规格里的"并发连接数/事务队列深度";软件侧对同一从站做请求串行化,不依赖网关排队。四、主动上报模式:注意数据的新鲜度网关定时轮询下游、主动推送的模式下,最大的问题是所有数据的时间戳都是"网关采集时间",不是"从站产生时间"。从站寄存器 500ms 刷新一次,网关 1s 轮询一次——你看到的每个值都可能是 500ms~1.5s 前的。拿这个数据去做联锁控制、能耗分项计量,误差就在设计里了。另外轮询模式下报警的时效性取决于轮询周期——下游设备报警了,最长要等一个轮询周期才报出去。报警类信号尽量单独走硬接点或缩短该设备的轮询间隔。五、验收清单:网关上线前必测七项按这套测一遍,能挡掉后面九成的怪毛病:[*]Unit ID 映射 — 每个下游地址经网关读一遍,确认映射正确
[*]超时层级 — 主站超时 > 网关超时 > 从站最坏应答,逐层核过
[*]从站离线行为 — 拔从站看响应:异常帧(合格)/ FF 填充(可容)/ 旧数据(一票否决)
[*]粘包拆包 — 连续快速请求 100 次,检查帧完整性
[*]并发 — 两个客户端同时访问,数据不串
[*]断线恢复 — 拔网线再插上,看应用层能否自动恢复(不等重启)
[*]冷启动 — 整个系统断电重启,看从站上电慢于主站时首几轮的表现(前篇讲过的宽限期问题)
六、一句话收尾网关没有让通讯变简单,只是把"一处复杂"换成了"两段链路 + 一道接缝"。透传按串口链路查,网关按主站逻辑查,接缝上的超时映射和离线行为,上线前专门测——这三句话记住,大部分怪毛病都有下手的地方。
页:
[1]