Modbus Master Busy Hang Recovery on S7-1200 ET200SP

David Krause12 min read
ModbusSiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Description

On Siemens S7-1200 CPUs and ET200SP stations equipped with a CM PtP module (for example, 6ES7 541-1AB00-0AB0), the Modbus_Master instruction (FB 1104, V2.4) can enter a permanent Busy state and never raise Done or Error. The symptom is most often reported after the serial point-to-point link drops mid-transaction, after a change of input parameters while REQ = 1, or when the slave stops responding without breaking the RS-485 bus. Once the FB hangs, toggling REQ alone will not release the block. Only a CPU restart, a STOP/RUN transition, or a precise reset of the internal MB_STATE tag inside the instance DB restores the master. Engineers routinely log this as a "Modbus master freezing in Busy" defect against the Modbus_Comm_Load / Modbus_Master library.

The hang is significant because the same instance DB cannot be re-armed for a new request until the internal state machine returns to 0. In polling applications with multiple slaves, a single hung instance stalls the entire scan, even when the physical bus is healthy.

Note: Siemens Support has historically described the hang as a boundary condition rather than a documented fault, but the symptom is reproducible on V2.4 of Modbus_Master and persists across TIA Portal V15, V15.1, V16, and V17. The recovery path below is the field-proven workaround.

Affected Components and Versions

Component Order Number / Version Notes
S7-1200 CPU All firmware versions (tested through V4.5) Run Modbus library on-board serial port
ET200SP CPU / IM All firmware versions Use CM PtP for serial comms
CM PtP (ET200SP) 6ES7 541-1AB00-0AB0 RS-232 / RS-422 / RS-485
TIA Portal V15 / V15.1 / V16 / V17 Reproduced on full TIA V15
Modbus_Comm_Load (FB 1100) V3.0 (in V15 delivery) Configures the CM PtP
Modbus_Master (FB 1104) V2.4 (in V15 delivery) Performs the master request
Modbus_Slave (FB 1102) V2.3 / V2.4 Not affected, not used here

The library is bundled with the CPU firmware; the instruction version shown in the TIA Portal Project Tree corresponds to the firmware on the device. When upgrading TIA Portal, always re-supply the library from the device's "Instructions" pane so the call is bound to the firmware-resident block.

Root Cause Analysis

Internal state machine of Modbus_Master

The Modbus_Master FB drives a five-state machine that lives in the instance DB under the STAT area. The variable commonly referred to as MB_STATE (also labelled state in some library versions) advances through the following values during a normal transaction:

MB_STATE Phase Exit condition
0 Idle, waiting for REQ rising edge Rising edge on REQ
1 Building request frame Frame handed to CM PtP
2 Transmitting Transmit complete
3 Waiting for response (RESP_TO running) Response received or RESP_TO
4 Validating response Done or Error set

If the link drops while the FB is in state 2, 3, or 4, the CM PtP driver signals an internal abort that the FB must translate into a transition back to state 0. In V2.4, that translation only occurs when the Blocked_Proc_Timeout watchdog on the Modbus_Comm_Load instance expires.

Why the FB remains Busy

Three conditions keep the FB in Busy indefinitely:

  1. Link drop with no RESP_TO expiry. If the slave powers down faster than RESP_TO (default 1000 ms) elapses but the CM PtP does not raise a transport error, the FB stays in state 3. Because the FB has not received a definitive "no response" indication, it never falls through to state 4.
  2. Input parameters change while REQ = 1. A change of MB_ADDR, MODE, DATA_ADDR, DATA_LEN, or DATA_PTR while a request is in flight corrupts the state machine. The FB does not re-evaluate inputs in flight; it silently desynchronises from the CM PtP driver.
  3. Coordinated multi-master switching. When two Modbus_Master instances are interleaved on the same CM PtP, the second FB must wait for the first to clear the port. If the first FB has hung in Busy, the second FB never sees the port released and the entire scan deadlocks.

Blocked_Proc_Timeout versus RESP_TO

Parameter Block Default Unit Function
RESP_TO Modbus_Comm_Load (FB 1100) 1000 ms Maximum time the FB waits for a response frame after a request has been transmitted. Per transaction.
Blocked_Proc_Timeout Modbus_Comm_Load (FB 1100) 0.5 seconds Maximum time the FB is allowed to remain Busy in total before it self-aborts with a STATUS code.

With the defaults, a single transaction can stay in Busy for up to 500 ms before the watchdog declares an error. If a second request is queued during that window, the total Busy time of the queued FB begins from the moment it tries to acquire the port, and Blocked_Proc_Timeout starts ticking immediately. Engineers who observe hangs longer than one second are usually looking at the queuing effect, not at RESP_TO.

Note: The Siemens help text labels Blocked_Proc_Timeout as a "maximum duration that a Modbus_Master may be blocked." Some installations raise it to 3 s, but that only delays the eventual self-abort; it does not recover the FB if the input-parameter-change defect is hit.

Pre-Recovery Diagnostics

Before applying the recovery sequence, capture the following to confirm the hang is in the FB and not in the physical layer.

  1. Open the Modbus_Master instance DB online and inspect MB_STATE (or state in older libraries). A value other than 0 with BUSY = TRUE and no DONE / ERROR pulse confirms the FB hang.
  2. Capture STATUS from both Modbus_Comm_Load and Modbus_Master. Common values during a hang:
    STATUS (hex) Meaning during a hang
    0x0000 Idle, but BUSY still TRUE — the FB is mid-transition; not a real hang.
    0x7001 State 1 / 2 in progress without timeout
    0x7002 State 3 in progress (waiting for response)
    0x80C8 Blocked_Proc_Timeout expired (STATUS from Modbus_Comm_Load)
    0x8188 Negative acknowledgement from CM PtP driver
  3. Watch the CM PtP diagnostic buffer in TIA Portal: Online & diagnostics > Diagnostics buffer > Open. A bus short, parity storm, or slave brown-out appears as a CM PtP event before the FB hang.
  4. Measure RS-485 biasing. Missing fail-safe bias causes the line to float when the slave is powered down; the CM PtP then sees noise that the FB interprets as valid characters.

Recovery Sequence A: MB_STATE Reset (Recommended)

This sequence forces the state machine back to 0 and re-arms the FB without a CPU restart. It must be executed from a higher-priority OB (OB 1) and is intended as a last-resort recovery, not a routine.

Step-by-step

  1. Identify the instance DB: iDB_ModbusMaster[0] for the first FB, iDB_ModbusMaster[1] for the second, and so on.
  2. Add a watch table or a small FB that reads MB_STATE and BUSY.
  3. When BUSY = TRUE for longer than (Blocked_Proc_Timeout + 0.5 s) with no DONE or ERROR edge, execute the reset:
// Reset sequence (ST, executed in OB1 once per scan after watchdog elapses) IF #Watchdog_Hang.Q THEN iDB_ModbusMaster[0].MB_STATE := 0; // force idle iDB_ModbusMaster[0].REQ := FALSE; // drop request latch iDB_ModbusMaster[0].BUSY := FALSE; // clear sticky BUSY (if accessible) iDB_ModbusMaster[0].DONE := FALSE; iDB_ModbusMaster[0].ERROR := FALSE; iDB_ModbusMaster[0].STATUS := 16#0000; #Watchdog_Hang(IN := FALSE); // arm again END_IF;
Note: The exact names of the STAT variables depend on the instruction version. In TIA V15 with Modbus_Master V2.4, the state is stored as a static WORD near the top of the instance DB. The Online & Diagnostics "Monitor / Modify" view lets you confirm the symbol name before writing to it.

Recovery Sequence B: REQ / DISCONNECT Toggle

If MB_STATE is not accessible (older libraries, different naming), the field-proven alternative is the REQ + DISCONNECT toggle sequence used by Navnag and HannAri in the original report.

  1. On hang detection (Busy > 2 s with no Done/Error):
      a. Set REQ = 0 and DISCONNECT = 1.
      b. Wait one OB1 cycle (or a TON with 100 ms).
      c. Set DISCONNECT = 0 and REQ = 1 for the next request.
  2. If the FB still returns BUSY = TRUE within 500 ms, repeat the sequence up to N times (typical N = 3). After N failed attempts, raise a permanent fault and require a CPU restart.

This sequence works because the DISCONNECT pulse forces the CM PtP driver to release the port. Once released, the state machine can complete its idle transition the next time REQ is raised.

Multi-Master Coordination Pattern

When two or more Modbus_Master FBs share one CM PtP, the polling logic must serialise them on a single REQ clock and respect the watchdog.

// Cyclic dispatcher, OB1, 100 ms tick CASE #iSlave OF 0: iDB_ModbusMaster[0].MB_ADDR := 1; iDB_ModbusMaster[0].MODE := 0; // FC 03 read holding iDB_ModbusMaster[0].DATA_ADDR := 0; iDB_ModbusMaster[0].DATA_LEN := 10; iDB_ModbusMaster[0].REQ := #Tick.Q AND NOT iDB_ModbusMaster[0].BUSY; 1: iDB_ModbusMaster[0].MB_ADDR := 2; iDB_ModbusMaster[0].MODE := 0; iDB_ModbusMaster[0].DATA_ADDR := 0; iDB_ModbusMaster[0].DATA_LEN := 10; iDB_ModbusMaster[0].REQ := #Tick.Q AND NOT iDB_ModbusMaster[0].BUSY; END_CASE; // Watchdog: detect hang, advance, and recover #HangWatch(IN := iDB_ModbusMaster[0].BUSY, PT := T#2S); IF #HangWatch.Q THEN iDB_ModbusMaster[0].REQ := FALSE; #iSlave := (#iSlave + 1) MOD 2; // skip the hung slave #HangWatch(IN := FALSE); END_IF;

Rules that prevent the hang

  1. Do not modify any input of a Modbus_Master FB while REQ = 1. Always wait for DONE or ERROR before changing MB_ADDR, MODE, DATA_ADDR, DATA_LEN, or DATA_PTR.
  2. Never use a free-running clock on REQ. REQ must be edge-driven (single-shot) or level-driven only when the FB is idle. A continuous clock such as a 1 Hz blink on REQ will collide with multi-master switching and reproduces the hang.
  3. Serialise multi-master. Only one REQ may be TRUE per OB1 scan. Use a token variable or a CASE structure.
  4. Set RESP_TO shorter than the worst-case slave latency. For RS-485 at 9600 baud, a 32-register read takes ~70 ms. RESP_TO = 200 ms gives margin without a hang.
  5. Raise Blocked_Proc_Timeout to 1.0 s on every Modbus_Comm_Load instance. This gives a hung FB enough time to self-abort and free the port.

Modbus_Comm_Load Configuration Reference

Input Recommended value (RS-485 RTU) Comment
REQ One-shot on startup Edge-triggered, not clocked
PORT CM PtP slot / ID From device configuration
BAUD 9600 (or 19200) Match the slave
PARITY 2 (even) Standard for Modbus RTU
FLOW_CTRL 0 (none) for RS-485 Use 1 for RS-232 with RTS/CTS
RTS_ON_DLY / RTS_OFF_DLY 0 / 0 for RS-485 Only relevant for RS-232 handshaking
RESP_TO 200 to 1000 Tune to slave response time
MODE 2 (RS-485 half duplex) Use 1 for RS-422 4-wire, 0 for RS-232
Blocked_Proc_Timeout 1.0 s Watchdog for the state machine

Verification Procedure

  1. Force REQ on a known-good slave and confirm DONE pulses within 200 ms.
  2. Power down the slave, leave the cable connected, and watch STATUS. After RESP_TO ms, the FB must raise ERROR with STATUS = 16#80C8 (timeout). If BUSY stays TRUE for longer than Blocked_Proc_Timeout + 200 ms, the watchdog has misfired.
  3. Unplug the RS-485 cable during a transaction. Verify that the FB recovers within 2 s (either through self-abort or the application watchdog) and that the next request succeeds when the cable is reconnected.
  4. Run a 24-hour cyclic test on a test bench with two slaves and a 100 ms dispatcher. The system must complete tens of thousands of transactions without a CPU restart.

Troubleshooting Matrix

Symptom Likely cause First action
BUSY = TRUE > 2 s, STATUS = 0 FB in state 2 or 3, link drop not signalled Check RS-485 bias and slave power
BUSY = TRUE > 2 s, STATUS = 16#80C8 Blocked_Proc_Timeout expired but state not cleared Apply MB_STATE reset (Sequence A)
BUSY latched after parameter change Inputs modified while REQ = 1 Refactor dispatcher to change inputs only on DONE / ERROR
Only second FB hangs First FB leaked port on previous cycle Serialise both FBs on a single REQ token
FB hangs every few hours EMI on RS-485 / floating line Add 680 ohm fail-safe bias at the end of the bus
FB hangs on every request Wrong MODE (full duplex instead of half duplex) Set MODE = 2 for RS-485

Known Limitations of V2.4

The Modbus library V2.4 ships in the S7-1200 / ET200SP firmware through TIA V17. The hang described above is not fixed in V2.4. The recovery procedures in this article are the documented field workaround. Newer instruction versions (V3.0 and later) are bundled with the S7-1200 V4.6 firmware / TIA V18 library updates; they add a STATUS code that explicitly identifies a hang but the recovery sequence still requires an application-side reset of the request latch and, in some cases, a CPU restart.

Safety: Never apply the MB_STATE reset while a real slave is mid-transaction. The reset drops the request latch and can leave the bus in an undefined state. Use it only when the application watchdog has declared the FB truly hung.

Standards Reference

The Modbus RTU frame structure, inter-character timing, and silent interval requirements are defined in the Modbus Organization's Modbus over Serial Line specification. The CM PtP enforces the 3.5 character silent interval at the configured baud rate; an off-specification slave that violates the silent interval can cause the FB to misframe and hang. Verify any third-party slave against the published Modbus reference.

FAQ

What does the Modbus_Master BUSY output really mean?

BUSY = TRUE means the FB is in state 1, 2, 3, or 4. It is not a fault; it is a status. A healthy request raises BUSY for the duration of one transaction. A hang raises BUSY indefinitely because the state machine does not return to 0.

What is the difference between RESP_TO and Blocked_Proc_Timeout?

RESP_TO (input on Modbus_Comm_Load, default 1000 ms) is the per-transaction response timeout: how long the FB waits for the slave to reply. Blocked_Proc_Timeout (also on Modbus_Comm_Load, default 0.5 s) is the watchdog on the FB itself: how long the FB is allowed to be Busy before the library self-aborts it.

Can I clear the hang by toggling REQ alone?

No. The original report shows that setting REQ = 0 and back to 1 does not release the FB if the state machine is mid-flight. The recovery requires either an MB_STATE = 0 write inside the instance DB, a DISCONNECT pulse, or a CPU restart.

Is the Modbus_Master V2.4 hang fixed in newer instruction versions?

The V2.4 hang is still reproducible on V3.0 of Modbus_Master in current firmware. The library adds a more descriptive STATUS code but does not change the recovery path. The application-side watchdog and reset sequence remain required.

How do I avoid the hang when I have two slaves on one CM PtP?

Use a single Modbus_Master instance and change MB_ADDR on the DONE edge. If you must use two instances, serialise them on a token so only one REQ is TRUE per OB1 scan, and apply the 2 s watchdog / MB_STATE reset described in this article.

Back to blog