Problem Statement
When configuring a SIMATIC S7-1200 CPU with a CM 1241 (6ES7 241-1CH32-0XB0) communication module in TIA Portal, the module may be added to the device view as a submodule of the CPU rather than appearing as a discrete port in the PORT parameter drop-down of the Modbus_Master (FB 641), Modbus_Comm_Load, or USS_Port_Select function blocks. The symptom is typically observed as:
- The hardware identifier of the CM 1241 cannot be selected from the PORT drop-down list of Modbus instructions; only submodules of the CPU rack are shown.
- The MB_DB.S_PORT static parameter of the multi-instance shows W#16#FFFF instead of a valid HW identifier.
- Modbus_Master returns STATUS = W#16#8281 with the message: "Check the input at the PORT parameter."
- Underlying WRREC.STATUS reports W#16#C080_9000 and the diagnostic buffer logs an "Area length error in FB 641."
Subsequent attempts to switch the CM 1241 firmware between V2.0, V2.1, and V2.2, change the CPU firmware (V4.1 / V4.2 / V4.4), replace the controller (CPU 1214FC vs. CPU 1217C), alter baud rate (9600 to 115200), or remove 120 Ω termination resistors do not resolve the assignment issue.
Affected Hardware and Firmware Matrix
| Component | Order Number (MLFB) | Observed FW | Behavior |
|---|---|---|---|
| CPU 1217C DC/DC/DC | 6ES7 217-1AG40-0XB0 | V4.2 | CM 1241 visible as submodule only |
| CPU 1214FC | 6ES7 214-1HF40-0XB0 | V4.1 – V4.4 | Same symptom across all firmware revisions |
| CM 1241 RS422/RS485 | 6ES7 241-1CH32-0XB0 | V2.0 / V2.1 / V2.2 | V2.2 not addressable; V2.0 / V2.1 appear as submodule |
| CM 1241 RS232 | 6ES7 241-1AH32-0XB0 | V2.x | Same symptom when used as substitute |
Root Cause: Submodule Versus Port in TIA Portal
Every point-to-point (PtP) capable hardware object in an S7-1200 system carries two distinct identifiers that the Modbus library functions interpret differently:
-
Hardware Identifier (HW ID) of the module itself, e.g.
269for a CM 1241 in slot 101. -
System constant of type
HW_IOorHW_INTERFACEthat points specifically to the communication port exposed by the module, e.g.CM_1241_RS422_RS485_1::CM_1241_RS422_RS485.
In TIA Portal, when the CM 1241 is dragged into the device view from the hardware catalog, the IO-Link connector of the module is automatically published as a port. However, certain library versions and project migrations (especially after upgrading from TIA V13 SP1 to V14 / V15 / V16 / V17) collapse the port into the parent submodule, producing an HW ID that references the module block rather than the port interface. The result is that the Modbus_FB PORT input still references a valid HW constant — but the constant no longer matches the IO-Link object the runtime expects.
This explains why a clean re-insert of the module, a CPU firmware update, or a baud-rate change do not change the runtime behavior: the assignment error is a configuration artefact, not a firmware limitation. The same root cause produces the related errors documented in Siemens FAQ 109751654 — S7-1200 Modbus RTU master error codes and the S7-1200 system manual, chapter "Point-to-point communication" (entry ID 109772940).
Hardware Identifier and PORT Parameter Relationship
The Modbus library blocks (FB 640 Modbus_Comm_Load and FB 641 Modbus_Master, library version ≥ V2.1 for the S7-1200) require the PORT input to be of the system data type HW_IO or HW_ANY. When you drop a function block on the FBD/ST/LAD editor and click the PORT drop-down, TIA Portal presents a filterable list of:
- All HW identifiers of PtP-capable modules in the device configuration.
- All HW identifiers of submodules (CPU sub-IDs, onboard ports, signal boards).
Only the port-level identifier is valid for FB 640/641. A submodule-level identifier compiles cleanly and passes static syntax checks but fails at runtime with STATUS 16#8281. The diagnostic error 16#C080_9000 returned by the underlying WRREC call is a vendor-class error from the system firmware meaning "I/O access error – address not configured for the requested operation." Detailed definitions are listed in the Modbus RTU master error reference.
Modbus Master Status Code Reference
| STATUS (hex) | Meaning | Recommended Action |
|---|---|---|
| W#16#0000 | No error / execution successful | Continue normal polling |
| W#16#80C8 | No response from slave within timeout | Check RS485 polarity A/B, termination, slave address |
| W#16#81D5 | Modbus parity / framing error | Verify parity, stop bits, baud rate match slave |
| W#16#8281 | Invalid PORT input | Re-assign PORT to the CM 1241 port HW constant, not the submodule |
| W#16#C080_9000 | WRREC: IO access error / address not configured | Module is addressed at submodule level; re-publish as port |
| W#16#FFFF | MB_DB.S_PORT not initialised | Multi-instance wiring of MB_DB is broken — see next section |
The MB_DB Multi-Instance Wiring Problem
FB 641 Modbus_Master uses a static tag MB_DB of type MODBUS_MASTER_DB. In TIA Portal, the canonical pattern is to instantiate both FB 640 and FB 641 as multi-instances inside a single user FB (for example, FB_ModbusPoller). When you call FB 641 in this pattern, you must wire the MB_DB input of FB 641 to the MB_DB static of the same instance DB, not to a global DB or to a different instance DB created by a separate call of FB 640.
If FB 640 and FB 641 are placed in separate instance DBs (or one in a global DB and the other as multi-instance), MB_DB.S_PORT is never initialised and stays at W#16#FFFF, which propagates the same error pattern observed in the user case. The correct wiring is shown below in SCL:
FUNCTION_BLOCK FB_ModbusPoller
VAR
// Static multi-instance DBs
MB_Comm_Load : Modbus_Comm_Load; // FB 640 instance
MB_Master : Modbus_Master; // FB 641 instance
// Configuration
BaudRate : DINT := 9600;
SlaveAddr : UINT := 1;
END_VAR
BEGIN
// Step 1: load port once on first scan
IF first_run THEN
MB_Comm_Load(
REQ := TRUE,
PORT := "CM_1241_1_PORT", // <-- port-level HW constant
BAUD := BaudRate,
PARITY := 0, // 0=none, 1=odd, 2=even
FLOW_CTRL:= 0,
TIMEOUT := 1000,
MB_DB := MB_Master.MB_DB, // <-- link to the multi-instance
DONE => load_done,
ERROR => load_err,
STATUS => load_status);
first_run := FALSE;
END_IF;
// Step 2: poll holding register 40001
MB_Master(
REQ := poll_trigger,
MB_DB := MB_Master.MB_DB, // <-- same multi-instance
MODE := 0, // 0=read holding
DATA_ADDR := 1,
DATA_LEN := 10,
DONE => poll_done,
ERROR => poll_err,
STATUS => poll_status);
END_FUNCTION_BLOCK
MB_DB from a global DB or a separate single-instance DB of FB 640. The internal state machine of FB 641 expects the MB_DB shared with the FB 640 that configured the same physical port. Detailed guidance is in the Siemens Modbus RTU FAQ and the S7-1200 communication function manual, entry ID 109751654.REQ / DONE / ERROR Trigger Logic
DONE and ERROR outputs of Modbus_Comm_Load and Modbus_Master are edge-triggered and remain TRUE for exactly one CPU scan. The standard, field-proven pattern is:
- Set REQ = TRUE.
- Wait for DONE = TRUE or ERROR = TRUE.
- Capture STATUS into a dedicated tag (do not overwrite it on the next scan).
- Reset REQ = FALSE.
- Re-arm REQ only after the next expected polling interval, or immediately after an ERROR to retry.
Setting REQ to a constant TRUE and ignoring DONE/ERROR causes two failure modes:
- Re-request storm: the master may issue a new request before the slave finishes the previous transaction, leading to corrupted frames and STATUS 80C8 (timeout) or 81D5 (parity/frame error).
- Lost status codes: the STATUS value latches only on the single scan when ERROR is TRUE; subsequent reads return 0 and the real cause is hidden.
The recommended re-trigger logic is:
// Pseudo-code
IF poll_done OR poll_err THEN
last_status := poll_status;
poll_trigger := FALSE;
poll_timer(IN := TRUE, PT := T#200ms);
END_IF;
IF poll_timer.Q THEN
poll_timer(IN := FALSE);
poll_trigger := TRUE;
END_IF;
Step-by-Step Resolution Procedure
- Update the CPU firmware. Use the Siemens S7-1200 Firmware Update Tool or TIA Portal Online → Accessible Devices → Update Firmware. Confirm the CPU is on a firmware revision listed in the latest S7-1200 system manual (entry 109772940) that is supported by your TIA Portal version.
- Update the CM 1241 firmware. The CM 1241 ships with a separate firmware that is independent of the CPU. TIA Portal V14 SP1 or newer is required to flash firmware V2.x onto a 6ES7 241-1CH32-0XB0. Do not skip this — firmware V2.0 on a project that expects V2.1 capabilities can also produce the port-versus-submodule symptom.
- Recreate the device configuration. Delete the CM 1241 from the device view, recompile, then drag the part 6ES7 241-1CH32-0XB0 from the catalog into the slot to the left of the CPU. After insertion, expand the module node: it must show a child element named "CM 1241 (RS422/RS485)" or similar — this child is the port. The HW identifier of the child is what the PORT input requires.
-
Verify the system constant. Open PLC Tags → Show all tags → System constants and confirm there is an entry of the form
<ModuleName>::<PortName>. If only a submodule-level constant exists, the port has not been published. Right-click the module → Properties → Port Configuration and ensure "Enable port" is checked. - Reassign the PORT input. In every call of FB 640 (Modbus_Comm_Load), delete the existing drop-down selection, click the input field, and choose the port-level system constant, not the module-level one. The drop-down shows both; the correct entry is the indented one belonging to the port child.
-
Fix the MB_DB wiring. Convert FB 640 and FB 641 to a single user FB with multi-instance variables, and wire
MB_DBof FB 641 to theMB_DBstatic of that same multi-instance. See the SCL example above. - Verify REQ logic. Implement the edge-triggered REQ/DONE/ERROR pattern. Capture STATUS into a separate tag on every ERROR edge.
- Compile and download. Perform a Software (rebuild all blocks) compile, then download the project to the CPU in STOP mode. Going online in RUN may leave stale instance data behind.
Wiring and Physical Layer Verification
Even with the PORT correctly assigned, a non-functional Modbus link typically indicates a physical-layer problem. The CM 1241 (6ES7 241-1CH32-0XB0) ships with a 4-pin terminal block (T/B, T/A, R/B, R/A) supporting both RS422 and RS485. For 2-wire RS485 to a single Modbus slave:
- Wire the slave's D+/A to CM 1241 pin T/B (TX/RX+) and the slave's D-/B to pin T/A (TX/RX-). Siemens uses the convention B = +, A = -, which is the opposite of some Chinese-vendor slaves — verify against the slave datasheet.
- Insert a 120 Ω termination resistor between T/B and T/A at each end of the bus. The CM 1241 has no internal termination; an external resistor is required.
- Provide a common ground reference between the slave and the CM 1241. Floating grounds are the most common cause of intermittent 80C8 / 81D5 errors after the port is correctly assigned.
- Bias the bus (pull-up on B to +5 V, pull-down on A to GND) when no slave is actively driving; otherwise the receiver floats and noise causes parity errors.
Full pinout and cable diagrams are in the S7-1200 system manual chapter "CM 1241 communication module".
Firmware Update Procedure
- Connect the engineering station directly to the CPU PROFINET port (not through a router).
- In TIA Portal, choose Online → Accessible Devices and identify the CPU's IP address.
- Open Online & Diagnostics → Firmware Update.
- Browse to the firmware file (.upd) downloaded from Siemens Industry Online Support. The file for the 6ES7 241-1CH32-0XB0 is named similarly to CM1241_RS422_RS485_V02_02_00.upd.
- Select the slot of the CM 1241 (not the CPU) and execute the update. Do not power-cycle the system during the update; the module automatically resets when the new firmware is applied.
- After the update, re-do the device configuration steps 3 – 5 of the resolution procedure because the new firmware may publish a different port identifier than the one stored in the project.
Verification and Validation Tests
After the port is correctly assigned, perform these tests in order:
-
Static check: Online monitor the MB_DB instance.
MB_DB.S_PORTmust be non-zero (typically in the range 256 – 511 for slot-side modules). -
Modbus_Comm_Load test: Force a one-shot trigger and confirm
DONE = TRUE,ERROR = FALSE, andSTATUS = 16#0000. If STATUS is non-zero, see the error code table above. - Loopback test: With only one CM 1241, wire T/B → R/B and T/A → R/A, then send a broadcast Modbus request (slave 0) and confirm an echo. This isolates the wiring from the slave device.
- Single-register read test: Poll holding register 0 (function code 03) from the slave. A valid response must appear within the configured timeout (default 1000 ms).
- Long-run stability test: Poll continuously for at least 30 minutes and monitor for STATUS changes. Persistent 0000 confirms the port is stable; periodic 81D5 or 80C8 indicates remaining physical-layer issues.
Diagnostic Buffer and Online Monitor Workflow
When an ERROR is captured, the diagnostic buffer entry of the CPU typically contains the most actionable detail. To extract it efficiently:
- Open Online & Diagnostics → Diagnostic Buffer.
- Filter for events with ID "IO access error" (event ID 0x0800 / 0x0801) and "Modbus error".
- For each event, note the Address field — it contains the HW identifier of the failing IO. If the address is the submodule-level ID, you have confirmed the port-versus-submodule problem. If it is a different ID, the issue is a different one (e.g. wrong slot, wrong module type).
- Use the "Go to" button to jump from the diagnostic entry to the affected block in the project.
Frequently Asked Questions
Why does the CM 1241 appear in the PORT drop-down as a submodule and not as a port?
The CM 1241 publishes two hardware identifiers: one for the module itself (submodule) and one for the IO-Link port it exposes. TIA Portal, especially after a project migration or firmware update of the CM 1241, may collapse the port identifier and expose only the submodule ID. Open the module's Properties → Port Configuration and confirm "Enable port" is checked, then recompile the project.
Modbus_Master returns STATUS 16#8281 — what does it mean?
STATUS 16#8281 means the PORT input of the block does not reference a valid point-to-point port. The most common cause is that the hardware constant selected is the module-level identifier rather than the port-level identifier. Reassign the PORT input to the <ModuleName>::<PortName> system constant and recompile.
What does MB_DB.S_PORT = 16#FFFF mean?
W#16#FFFF in MB_DB.S_PORT indicates that the static tag was never initialised by Modbus_Comm_Load. This typically happens when Modbus_Comm_Load and Modbus_Master are placed in different instance DBs, breaking the shared MB_DB contract. Place both blocks as multi-instances inside a single user FB and wire MB_DB of FB 641 to the MB_DB static of that multi-instance.
Is firmware V2.2 of the CM 1241 required for TIA Portal V17 projects?
For new S7-1200 projects in TIA Portal V16 SP1 or newer, the CM 1241 firmware V2.2 is the recommended revision and exposes additional diagnostic data. Older TIA Portal versions do not recognise V2.2 and the module may not appear in the device catalog — in that case downgrade to V2.1 or update TIA Portal. Always check the release notes of your specific TIA Portal version before flashing.
Can I keep REQ constantly TRUE on Modbus_Master?
No. DONE and ERROR are TRUE for a single CPU scan only. Holding REQ constantly TRUE causes re-request storms that corrupt Modbus frames and hide the real STATUS code. Use the edge-triggered pattern: set REQ TRUE, wait for DONE or ERROR, capture STATUS, then clear REQ and re-arm it after a defined interval or after an error.