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.
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:
-
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. -
Input parameters change while REQ = 1. A change of
MB_ADDR,MODE,DATA_ADDR,DATA_LEN, orDATA_PTRwhile 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. -
Coordinated multi-master switching. When two
Modbus_Masterinstances 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.
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.
- Open the
Modbus_Masterinstance DB online and inspectMB_STATE(orstatein older libraries). A value other than 0 withBUSY = TRUEand noDONE/ERRORpulse confirms the FB hang. - Capture
STATUSfrom bothModbus_Comm_LoadandModbus_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 - 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.
- 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
- Identify the instance DB:
iDB_ModbusMaster[0]for the first FB,iDB_ModbusMaster[1]for the second, and so on. - Add a watch table or a small FB that reads
MB_STATEandBUSY. - When
BUSY = TRUEfor longer than(Blocked_Proc_Timeout + 0.5 s)with noDONEorERRORedge, 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;
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.
- On hang detection (Busy > 2 s with no Done/Error):
a. SetREQ = 0andDISCONNECT = 1.
b. Wait one OB1 cycle (or a TON with 100 ms).
c. SetDISCONNECT = 0andREQ = 1for the next request. - 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
-
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, orDATA_PTR. - 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.
- Serialise multi-master. Only one REQ may be TRUE per OB1 scan. Use a token variable or a CASE structure.
-
Set
RESP_TOshorter 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. -
Raise
Blocked_Proc_Timeoutto 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
- Force
REQon a known-good slave and confirmDONEpulses within 200 ms. - Power down the slave, leave the cable connected, and watch
STATUS. AfterRESP_TOms, the FB must raiseERRORwith STATUS = 16#80C8 (timeout). IfBUSYstays TRUE for longer thanBlocked_Proc_Timeout+ 200 ms, the watchdog has misfired. - 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.
- 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.
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.