You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: flush the RTU receive buffer before each transaction
A transient line glitch (a single bad-CRC frame) permanently wedged a
shared RTU bus: every device on it went unavailable and never recovered,
needing a restart. Observed at least daily on a two-slave bus.
Once a corrupted or short frame leaves unread bytes in the serial input
buffer, the bus desynchronises by one frame -- each read returns the
previous request's reply, so every transaction fails "response not from
requested slave" (or bad CRC on the partial frame). The trigger is
TRANSIENT (a CRC/timeout/wrong-slave error is not FATAL, by design, so a
USB-serial hiccup does not tear down the bus), which means the bus is
never reconnected -- and reconnect was the only place modbus_flush() ran.
Nothing drained the stale bytes, so the one-off glitch became permanent.
Flush the input buffer before issuing each request on an RTU bus, so a
transaction always starts from a clean buffer. The flush must precede the
request, not follow a failed read: when a stale-frame read fails it
returns instantly while the genuine reply is still in flight, so flushing
afterwards only discards the current stale frame and lets the in-flight
one become the next -- the lag survives. Flushing before the send drops
the stale frame and lets the read block for this request's own reply,
resynchronising on the next poll. On a healthy bus the buffer is already
empty (a successful read consumes its frame exactly), so this discards
nothing. TCP is unaffected and skipped.