Overview: PROFINET Connection Diagnostics on S7-300
The S7-300 family, including the F-CPU variant 6ES7315-2FJ14-0AB0 (CPU 315F-2 PN/DP), exposes a different diagnostic surface than S7-1200 and S7-1500 controllers. The user-friendly DeviceStates instruction that ships in the S7-1200/1500 system library is not supported on S7-300/400 firmware, regardless of the firmware version loaded on the CPU. Engineers migrating diagnostic code from a 1200/1500 program to a 315F-2 PN/DP therefore need to fall back on the lower-level RDSYSST (Read System State) block to read partial lists of the System State List (SSL).
This reference documents how to use RDSYSST on a CPU 315F-2 PN/DP to extract per-device PROFINET IO connection state information, decode the returned data record, and surface the data on an HMI or use it for application-level decisions (skip commissioning devices, raise a maintenance alarm, etc.). The procedure is applicable to any S7-300 CPU with an integrated PROFINET interface or an external CP 343-1, and to S7-400 CPUs with PROFINET connectivity, with only minor firmware-dependent variations.
Prerequisites
- SIMATIC S7-300 CPU with integrated PROFINET interface. Example: 6ES7315-2FJ14-0AB0 (CPU 315F-2 PN/DP, FW V3.3 or later). Lower firmware revisions may not populate all SSL partial lists referenced below.
- STEP 7 V5.5 / SP4 or higher, or TIA Portal V13 or higher with the appropriate S7-300 CPU HSP installed.
- Configured PROFINET IO system with at least one IO device (distributed I/O, drive, or third-party PROFINET device) with device numbers assigned in HW Config / device configuration.
- Basic familiarity with the Siemens contribution "Reading SZL via RDS/SYSST" as background.
- Optional: TIA Portal or STEP 7 online diagnostic view for verification of states read by the application program.
Why DeviceStates Is Not Available on S7-300
The DeviceStates instruction is part of the system instructions family added with the S7-1200 (FW V4.0) and S7-1500 system library. Internally, DeviceStates wraps calls to the RDSYSST partial lists that are only populated on the newer system firmware. On S7-300/400, the following limitations apply:
- The user-program instruction catalog does not expose
DeviceStates; placing the block from the S7-1200/1500 library results in an unresolved reference at compile time. - The underlying SSL partial lists referenced by
DeviceStates(notably the PROFINET IO device state list) are not generated by the S7-300 firmware, so even a directRDSYSSTcall returns an error code inRET_VAL(typically W#16#8085, "evaluated function not available in this CPU"). - OB-based diagnostics (OB82, OB86) still work, but the engineer may prefer a polled, deterministic read in OB1, which the SSL approach provides.
For F-CPU variants (e.g., 315F-2 PN/DP), the F-runtime signature imposes additional restrictions on user blocks in the F-runtime group; the diagnostic logic must execute in the standard runtime or in a non-safety DB and be accessed via the F-shared DB interface if it is consumed in the F-program.
PROFINET Diagnostic Architecture and Data Flow
The PROFINET IO stack on the S7-300 integrated PN interface maintains several internal data structures:
- AR (Application Relationship) table – one entry per established AR with each configured PROFINET IO device.
- CR (Communication Relationship) table – IO CR, supervisor AR, etc.
- Diagnostic buffer entries – chronological log of stack events (link up/down, AR established, watchdog timeout).
-
SSL partial lists – precomputed byte arrays accessible via
RDSYSSTin OB1 or a cyclic OB (e.g., OB35).
SSL partial lists are organized by a 16-bit SZL_ID (also called SSL_ID). Each SZL_ID returns a header (SZL_HEADER) describing the length and number of records, followed by one or more data records in the DR buffer. For PROFINET-relevant diagnostics on S7-300, the partial lists most commonly used are W#16#0x94, W#16#0x95, W#16#0x96, and on supported firmware revisions, W#16#0694 and the PROFINET IO statistics partial lists.
RDSYSST Block: Interface and Operating Principle
The RDSYSST block is located in the Standard Library > System Function Blocks (SFB) folder in STEP 7 V5.5, or under Instructions > Communication > Communication processor > System diagnostics in TIA Portal when used with S7-300/400 targets.
| Parameter | Declaration | Data Type | Description |
|---|---|---|---|
| REQ | INPUT | BOOL | Edge-triggered start signal. A rising edge initiates the read operation. The block remains busy until the operation completes. |
| SZL_ID | INPUT | WORD | Identifies the SSL partial list to read. Format W#16#0xxx (e.g., W#16#0x94). |
| INDEX | INPUT | WORD | Sub-list / subnet selector. For PROFINET IO on S7-300, INDEX = PROFINET interface (network) number, not the device number or the IP address. |
| RET_VAL | OUTPUT | INT | Error / status code. W#16#0000 = OK, W#16#80A1..W#16#80B4 = standard errors, W#16#8085 = SSL not supported. |
| BUSY | OUTPUT | BOOL | TRUE while the read is in progress. |
| SZL_HEADER | OUTPUT | STRUCT | Length of one data record (LENTHDR) and number of records (N_DR) in the response. |
| DR | OUTPUT | ANY | Destination buffer. Must be sized to LENTHDR * N_DR bytes as reported by SZL_HEADER on the previous cycle, or 32 bytes as a safe default for partial reads. |
Because RDSYSST can take multiple OB cycles to return a large partial list, the standard pattern is to call it inside an FB with a small state machine that re-triggers it on the next scan when BUSY drops. A polled call in OB1 also works; the result reflects the state at the moment BUSY falls.
SSL_ID Reference Table for PROFINET IO
| SZL_ID | Name | Returned Data per Record | Typical Use on S7-300 |
|---|---|---|---|
| W#16#0x94 | Module status – rack 0 | Logical address, status, channel/IO flags | CPU itself and rack 0 modules |
| W#16#0x95 | Module status – central rack | Logical address, status | Centralized I/O and CP diagnostics |
| W#16#0x96 | Module status – all racks | Logical address (bits 0–14), status, channel flags | Iterate over all configured modules; the address field is a logical I/O address, not a device number |
| W#16#0x132 | Module diagnostic information | Diagnostic data records (4 bytes per slot) | Channel-level diagnostics |
| W#16#0694 | PROFINET IO device state (firmware-dependent) | Per-device connection state, error code | Per-device connection state; availability depends on the CPU firmware and PROFINET stack version |
| W#16#0A91 | PROFINET IO port statistics (CP 343-1 and PN-CPU V4+) | Discarded frames, CRC errors per port | Link-quality diagnostics on the local interface |
| W#16#0A92 | PROFINET IO interface statistics | Frame counters, error counters | Throughput sanity checks |
Important: SZL_ID availability is firmware-dependent. On a CPU 315F-2 PN/DP with firmware V3.x, W#16#0694 is typically not populated. The standard workaround is to iterate the module status partial list (W#16#0x94 / 0x96), match the returned logical addresses against the IO address ranges assigned in HW Config, and use the status field to derive a per-device "reachable / faulty" state.
Decoding the INDEX Parameter Correctly
The most common error when calling RDSYSST for PROFINET on S7-300 is to place a PROFINET device number or an IP address octet into the INDEX input. INDEX for PROFINET IO is the PROFINET network (interface) number configured in HW Config, not a device selector.
| Misconception | Correct Interpretation |
|---|---|
| "INDEX is the PROFINET device number (1, 2, 3, ...)" | INDEX is the PROFINET interface / network number. For a CPU 315F-2 PN/DP with a single PN interface, INDEX = 1. |
| "INDEX is the IP address (e.g., 192.168.0.10)" | INDEX is an integer network index, not an IP address. The IP address is read through the system data blocks of the PN interface, not via SZL. |
| "INDEX is the slot number in the IO device" | Slots are addressed by the data record index inside a single record, not by SZL INDEX. |
For multi-interface configurations (CPU 315PN/DP plus an external CP 343-1, or an S7-400 with multiple PROFINET CPs), each interface is assigned a sequential network number starting from 1. Iterate INDEX from 1 to N if you want to enumerate all PROFINET subnets.
Step-by-Step Implementation
- Open the project in STEP 7 / TIA Portal and load the S7-300 station with the CPU 315F-2 PN/DP configured. Confirm in HW Config / device configuration that the PROFINET interface is assigned network number 1 (default).
-
Insert a new FB (e.g., FB100 – "PN_Diagnostics") in your program. Declare the static instance of
RDSYSSTassRDSYSST : RDSYSST;in the static section. - Declare a 32-byte ARRAY of BYTE as the destination buffer for the partial list data, plus a BOOL array indexed by PROFINET device number to expose the connection state.
-
Implement a call to
RDSYSSTin OB1 (or OB35 at 100 ms) with SZL_ID = W#16#0x94 and INDEX = 1. CaptureSZL_HEADERon the first completed cycle to size the buffer correctly. - Iterate the returned data record. For each entry, extract the logical I/O address from bits 0–14 of the first WORD. Match it against the IO address ranges configured for each PROFINET device in HW Config.
- Map address range to device number. Each PROFINET IO device is assigned a contiguous address range; build a lookup table (ARRAY[1..16] OF STRUCT with iAddrStart, iAddrEnd, iDeviceNumber) in a DB.
-
Decode the status byte. For W#16#0x94 / 0x96, the standard module-status encoding is:\li>
- Bit 0 = module exists (configured)
- Bit 1 = module fault (1 = faulty, 0 = OK)
- Bit 2 = module not accessible (1 = not reachable, e.g., AR not established)
- Bit 3 = wrong module (type mismatch)
- Bit 6 = channel fault present
- Set the connection state array. For each device, write a BOOL "reachable", BOOL "faulty", BOOL "diagnostic available". The HMI can read these directly; the application program can branch on them.
-
Handle partial-list overflow. If
SZL_HEADER.N_DRreports more records than fit in the 32-byte buffer (typical when N_DR * LENTHDR > 32), callRDSYSSTagain with the same SZL_ID and INDEX; the block automatically continues from the next record. Use theRET_VALvalue W#16#80A1 (end of list reached) to stop. - Surface the data to the HMI. Connect the BOOL array to HMI tags via the connection configured for the project (typically S7ONLINE / PN/IE). On a WinCC flexible / TIA WinCC panel, display the device number plus a colored status icon.
SCL Code Example
FUNCTION_BLOCK FB100_PN_Diagnostics
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
VAR_INPUT
iExecute : BOOL; // start a diagnostic scan cycle
iPN_Network : INT := 1; // PROFINET interface / network number
END_VAR
VAR_OUTPUT
oDone : BOOL;
oBusy : BOOL;
oError : BOOL;
oStatus : WORD; // RET_VAL mirror
oDeviceCount : INT; // number of devices detected this cycle
END_VAR
VAR
sRDSYSST : RDSYSST;
sPhase : INT := 0; // 0=idle, 1=request, 2=wait, 3=process
sBuffer : ARRAY[0..31] OF BYTE;
sHeader : STRUCT
LENTHDR : WORD;
N_DR : WORD;
END_STRUCT;
sDevice : ARRAY[1..16] OF STRUCT
Reachable : BOOL;
Faulty : BOOL;
Configured : BOOL;
END_STRUCT;
END_VAR
BEGIN
oBusy := sRDSYSST.BUSY;
oStatus := INT_TO_WORD(sRDSYSST.RET_VAL);
CASE sPhase OF
0: // Idle - wait for execute
IF iExecute THEN
oDone := FALSE;
oError := FALSE;
sPhase := 1;
END_IF;
1: // Request a read of module status partial list
sRDSYSST.REQ := TRUE;
sRDSYSST.SZL_ID := W#16#0x96; // all racks - includes PROFINET IO
sRDSYSST.INDEX := INT_TO_WORD(iPN_Network);
sPhase := 2;
2: // Wait for completion
sRDSYSST.REQ := FALSE;
IF NOT sRDSYSST.BUSY THEN
IF sRDSYSST.RET_VAL = 0 THEN
sPhase := 3;
ELSIF sRDSYSST.RET_VAL = W#16#80A1 THEN
// end of list - normal termination
sPhase := 0;
oDone := TRUE;
ELSE
sPhase := 99; // error
END_IF;
END_IF;
3: // Process one data record
// SZL_HEADER returned; copy into static buffer
sHeader.LENTHDR := sRDSYSST.SZL_HEADER.LENTHDR;
sHeader.N_DR := sRDSYSST.SZL_HEADER.N_DR;
// Iterate the records (28 bytes per record in W#16#0x96)
// For each record: WORD @ offset 0 = logical I/O address (bits 0-14),
// WORD @ offset 2 = status, WORD @ offset 4 = channel flags
// Example pseudo-decoding follows in the next FB cycle via a loop counter
sPhase := 0;
oDone := TRUE;
99: // Error terminal state
oError := TRUE;
oDone := TRUE;
sPhase := 0;
END_CASE;
END_FUNCTION_BLOCK
For the S7-300 with classic S7-300 instruction set (no optimized block access), the same FB works with the following adjustment: replace RDSYSST with the FB call convention used in STEP 7 V5.5, where SZL_HEADER is an ANY pointer or two WORDs at the start of the DR buffer, depending on the source library.
Alternative Approaches
OB86 – Rack or Station Failure
The OB86 (rack failure OB) is called automatically by the CPU when a PROFINET IO device AR (Application Relationship) drops or a station becomes unreachable. OB86_EXTERNAL_FAULT bit 4 (EVENT_CLASS) indicates an incoming fault (device lost) and bit 5 indicates an outgoing fault (device returned). OB86_RESERVED_1 contains the PROFINET device number in the upper 8 bits and slot in the lower 8 bits. The OB can update a status array exactly like the polled approach but is event-driven, so the engineer does not need to poll in OB1. Note that OB86 is not a substitute for diagnostic interrupts on the device itself (those are OB82 events).
SFB52 RDREC – Read Data Record from PROFINET Device
For deeper diagnostics (e.g., channel-level faults, manufacturer-specific records), use SFB52 (RDREC) with the PROFINET device number as the hardware identifier. The standard record index 0x8000 (PROFINET standard diagnostics) and 0xC00A (multiple record request) are typically supported by GSDML-described devices.
Report System Errors (S7-300 / 400)
STEP 7 and TIA Portal both offer the Report System Errors wizard, which generates FB_REPGEN, FB_REPSUI, and related blocks that evaluate SSL data internally and raise alarms with textual error messages. See the TIA Portal System Diagnostics for S7-300/S7-400 manual for configuration. This is the highest-level approach and the recommended one for new projects.
PROFINET Connection Diagnostics Page in TIA Portal
For runtime verification, the Connection Diagnostics S7-300/S7-400 documentation describes the online diagnostics view that presents the same PROFINET connection state in a table; comparing the polled program output against this view is the simplest verification.
Verification and Commissioning Checklist
- Place the FB100 call in OB1 with a 1-second enable pulse. Connect
iPN_Network= 1. - Go online with the CPU. In the monitoring table, watch
oStatuscycle between W#16#0000 (OK) and W#16#0000 at the next request. IfoStatusremains W#16#8085, the SSL partial list is not supported on the current firmware – fall back to W#16#0x94 / 0x96. - Disconnect the PROFINET cable from one configured IO device. Within 1–2 scan cycles, the corresponding
sDevice[i].Reachableshould drop to FALSE andsDevice[i].Faultyshould rise to TRUE. - Reconnect the cable. Confirm
Reachablereturns to TRUE andFaultyclears within the AR re-establishment time (typically 1–3 seconds). - Open the TIA Portal online Devices & Networks view and compare the same device against the program-reported state. They must match.
- Force a configuration mismatch (rename a device in HW Config, do not download, then restart) and confirm the program flags the device as Wrong module.
- Validate the F-program side: if any of these tags are consumed in the F-runtime, route them through the F-shared DB and observe the F-signature recompile requirement.
Troubleshooting Matrix
| Symptom | RET_VAL | Likely Cause | Remediation |
|---|---|---|---|
| RDSYSST never returns BUSY=FALSE | — | DR buffer too small or wrong SZL_ID | Verify SZL_ID exists for the firmware; size DR to LENTHDR * N_DR |
| RET_VAL = W#16#8085 | 8085 hex | SSL not supported by this CPU/firmware | Use module status partial lists W#16#0x94/0x95/0x96 instead of W#16#0694 |
| RET_VAL = W#16#80B1 | 80B1 hex | INDEX invalid for this SZL | Confirm INDEX = PROFINET network number, not device number or IP |
| RET_VAL = W#16#80A1 | 80A1 hex | End of partial list reached (normal) | Treat as successful termination; trigger next read or stop |
| All devices show Reachable=TRUE but application reports fault | — | Logical address range mismatch in lookup table | Cross-check IO address ranges in HW Config against lookup table |
| State oscillates every cycle | — | RDSYSST called faster than the stack updates | Throttle request to a 1-second pulse |
| Device flagged Faulty but TIA shows OK | — | Reading wrong interface index (multi-CPU / multi-CP projects) | Verify PROFINET network number in HW Config matches INDEX |
| Compiler error: RDSYSST unknown | — | Library not installed or wrong CPU selected | Install S7-300 system library; verify device family in project |
| OB86 not triggered on disconnect | — | OB86 missing from project (CPU goes STOP on rack failure) | Insert OB86 (even as empty) into the project to keep CPU in RUN |
| F-signature check fails after adding FB | — | Diagnostic FB inside F-runtime group | Move FB to standard runtime; expose state via F-shared DB |
Notes on Safety and Runtime Constraints
On F-CPUs such as the 315F-2 PN/DP, the F-runtime signature (F-Signature) is invalidated whenever the F-program changes. Diagnostic logic that runs in OB1 outside the F-runtime group does not invalidate the signature, but reading F-shared data from the standard runtime must respect the F-CPU access rules: standard code can read F-tagged DBs only through the F-shared DB mechanism, not through direct DB access. If the diagnostic block itself is consumed by the safety program (e.g., to inhibit a safety function when a non-safety PROFINET device is lost), a standard FB writes a BOOL to an F-shared DB that the F-program then reads through DB_F_SHARED. Avoid placing RDSYSST itself inside the F-runtime group – its execution time is variable and unbounded, which violates F-runtime determinism.
FAQ
Why does the DeviceStates block not compile on my CPU 315F-2 PN/DP?
DeviceStates is a system instruction introduced with the S7-1200 (FW V4.0) and S7-1500 system library. S7-300/400 firmware, including the 315F-2 PN/DP, does not include the underlying SSL partial lists the instruction wraps. Use RDSYSST with SZL_ID W#16#0x94 / 0x96 to read module status and derive per-device connection state on S7-300.
What does the INDEX input of RDSYSST actually mean for PROFINET?
INDEX is the PROFINET network (interface) number configured in HW Config, not the PROFINET device number, slot, or IP address. For a CPU 315F-2 PN/DP with a single PROFINET interface, INDEX = 1. Setting INDEX to a device number or IP address returns RET_VAL = W#16#80B1 (invalid index).
Can I read PROFINET device diagnostics on S7-300 without using OB82 or OB86?
Yes. Use RDSYSST with SSL_ID W#16#0x94, 0x95, or 0x96 to read module status in OB1 (or a cyclic OB) and decode the returned logical address and status bytes. This polled approach gives a deterministic view of which devices are reachable and which have faults without relying on diagnostic or rack-failure OBs.
Which SZL_ID should I use for PROFINET IO on a 315F-2 PN/DP with firmware V3.3?
Firmware V3.x typically does not populate W#16#0694 (PROFINET IO device state). Use the module status partial lists W#16#0x94 (rack 0), W#16#0x95 (central rack), or W#16#0x96 (all racks). Match the returned logical addresses against the IO address ranges configured in HW Config to derive per-device state.
How do I avoid invalidating the F-signature when adding diagnostic logic to a 315F-2 PN/DP?
Implement the RDSYSST-based diagnostics in a standard FB called from OB1, outside the F-runtime group. If the safety program needs the diagnostic state, write it to an F-shared DB and read it through the standard F-shared DB access rules. Do not place RDSYSST inside the F-runtime group – its non-deterministic execution time violates F-runtime timing constraints.