S7-300 PROFINET Diagnostics with RDSYSST Block (S7-315F PN/DP)

David Krause15 min read
S7-300SiemensTutorial / How-to
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

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 direct RDSYSST call returns an error code in RET_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:

  1. AR (Application Relationship) table – one entry per established AR with each configured PROFINET IO device.
  2. CR (Communication Relationship) table – IO CR, supervisor AR, etc.
  3. Diagnostic buffer entries – chronological log of stack events (link up/down, AR established, watchdog timeout).
  4. SSL partial lists – precomputed byte arrays accessible via RDSYSST in 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

  1. 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).
  2. Insert a new FB (e.g., FB100 – "PN_Diagnostics") in your program. Declare the static instance of RDSYSST as sRDSYSST : RDSYSST; in the static section.
  3. 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.
  4. Implement a call to RDSYSST in OB1 (or OB35 at 100 ms) with SZL_ID = W#16#0x94 and INDEX = 1. Capture SZL_HEADER on the first completed cycle to size the buffer correctly.
  5. 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.
  6. 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.
  7. 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
  8. 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.
  9. Handle partial-list overflow. If SZL_HEADER.N_DR reports more records than fit in the 32-byte buffer (typical when N_DR * LENTHDR > 32), call RDSYSST again with the same SZL_ID and INDEX; the block automatically continues from the next record. Use the RET_VAL value W#16#80A1 (end of list reached) to stop.
  10. 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

  1. Place the FB100 call in OB1 with a 1-second enable pulse. Connect iPN_Network = 1.
  2. Go online with the CPU. In the monitoring table, watch oStatus cycle between W#16#0000 (OK) and W#16#0000 at the next request. If oStatus remains W#16#8085, the SSL partial list is not supported on the current firmware – fall back to W#16#0x94 / 0x96.
  3. Disconnect the PROFINET cable from one configured IO device. Within 1–2 scan cycles, the corresponding sDevice[i].Reachable should drop to FALSE and sDevice[i].Faulty should rise to TRUE.
  4. Reconnect the cable. Confirm Reachable returns to TRUE and Faulty clears within the AR re-establishment time (typically 1–3 seconds).
  5. Open the TIA Portal online Devices & Networks view and compare the same device against the program-reported state. They must match.
  6. 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.
  7. 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.

Back to blog