Resolving SFC51 SSL-ID Compatibility Issues on S7-300/S7-400 CPUs

David Krause15 min read
PLC HardwareSiemensTechnical Reference
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

SFC51 and the System Status List Architecture

The Siemens SIMATIC S7-300 and S7-400 CPU firmware exposes system internal data through the System Status Lists (SSL, German Systemzustandslisten, SZL). These lists are accessible from user programs via the system function block SFC51 (SZL_Read / RDSYSST), which copies a partial extract (SZL-Teilliste / partial list) of a single SSL sublist into a destination area.

The function signature in STEP 7 STL is:

CALL "RDSYSST" / "SZL_Read" / SFC 51
  REQ     :=               // BOOL - 1 = read request, edge-triggered
  SZL_ID  :=               // WORD  - which SSL sublist to read
  INDEX   :=               // WORD  - which partial list / element offset
  RET_VAL :=               // INT   - return value (0 = OK, error code on fail)
  BUSY    :=               // BOOL  - operation in progress (asynchronous mode)
  SZL_HEADER :=            // STRUCT - header with LENTHDR, N_DR (count of records)
  DR      :=               // ANY   - destination area for record data

Two parameters drive what the CPU returns: SZL_ID selects the SSL sublist family and INDEX selects a specific record or partial extract inside that sublist. Support for both is CPU-dependent. The destination area DR must be sized to the worst-case record length (typically W#16#0024 bytes = 36 bytes per record), and the SZL_HEADER STRUCT always returns LENTHDR = 28 and N_DR = number of records actually delivered.

Critical: If the requested SZL_ID / INDEX combination is not supported by the target CPU firmware, SFC51 does not return a benign "no data" result. It returns a non-zero RET_VAL that you must evaluate. Treating the destination area as valid when RET_VAL <> 0 is the single most common source of corrupted diagnostic data in user code.

SSL-ID Address Space Structure

The SSL address space is not contiguous. Sublists are grouped into families identified by the high byte of the SSL-ID. Within each family, the low byte identifies a specific sublist, and the INDEX parameter selects a record inside that sublist. The families documented across recent SIMATIC firmware are:

SSL-ID family Typical content Sample sublist IDs (hex)
0x00xx Module and system identification 0x0011, 0x0012, 0x0013, 0x0014, 0x0019, 0x001C, 0x0022, 0x0025, 0x0031, 0x0032
0x01xx - 0x0Fxx Status and diagnostic partial lists 0x0090, 0x0091, 0x0092, 0x0094, 0x00A0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x0111, 0x0112, 0x0113, 0x0121, 0x0131, 0x0132, 0x0174, 0x0191, 0x0192, 0x0195, 0x01F1
0x1xxx - 0xFxxx Reserved / vendor specific Not generally available to user programs

Within the 0x01xx family, the high nibble of the low byte (0x9_, 0xB_, 0x1_, 0x7_, etc.) often groups functionality: 0x9_ for module / rack information, 0xB_ for diagnostic data, 0x1_ for LED and operating-mode state, 0x7_ for time and communication. The numbering is not monotonic across the manual - the official Instruction List appendices order sublists by topic, not by ascending SSL-ID.

Address convention: SZL_ID is a WORD where the high byte is the family and the low byte is the sublist. Many legacy code samples pass a W#16#0090 constant rather than the literal 0x90. Always confirm the data type when porting code between STEP 7 classic and TIA Portal.

CPU Family SSL-ID Support Matrix

The following table summarizes documented support for the three SSL-IDs of interest (0x90, 0x111, 0x195) across the SIMATIC S7 CPU families covered by the current Instruction List manuals. Values reflect the most recent manuals on the Siemens support portal at time of writing; legacy CPUs must be verified against the historical revision of the Instruction List applicable at their ship date.

SSL-ID (hex) Subject S7-300 / S7-300C S7-400 (standard) S7-400F / FH S7-400H
0x0090 Module identification - basic (CPU order number, firmware, serial) Supported (most FW) Supported Supported Supported
0x0111 LED status of the CPU front panel Supported (most FW) Supported Supported Supported
0x0195 Safety mode / F-runtime status (F-CPU specific) Not applicable Not supported Supported (F/FH only) Not applicable

The table is conservative: where a manual states "supported from firmware x.y for CPU type z", that is encoded as "Supported (most FW)". The exact cutoff firmware per CPU must be read from the relevant Instruction List appendix - there is no single global firmware version for an SSL-ID.

SSL-ID 0x0090 - Module Identification

Sublist 0x0090 returns basic module identification: order number (MLFB), firmware version, serial number, and module name. It is one of the few sublists that returns data for both central and distributed (PROFIBUS / PROFINET) modules when the appropriate INDEX is supplied.

Field Width Description
Index 0 1 record Identification of the CPU itself (always available)
Index 1..31 1 record per slot Identification of modules in the central rack (S7-300)
Index 100..215 1 record per DP station / logical address Identification of PROFIBUS DP slaves (S7-300C / S7-400 with DP interface)
Index 100..255 1 record per PN device / slot Identification of PROFINET IO devices (CPU FW-dependent)

Each record returned through DR is 28 bytes and includes:

  • Byte 0..3: Index echo
  • Byte 4..5: Module type identifier (e.g. 0x0001 = CPU)
  • Byte 6..7: Reserved / channel count
  • Byte 8..23: Order number (MLFB) as ASCII, right-padded with spaces
  • Byte 24: Firmware version major
  • Byte 25: Firmware version minor
  • Byte 26..27: Reserved

Field behavior on very old CPUs: 0x90 was not always implemented for the extended PROFIBUS / PROFINET index ranges. Pre-2000 vintage CPUs (example: 6ES7 414-2XJ01) may return RETVAL = W#16#8085 ("SSL sublist does not exist") when called with PROFIBUS station indexes even though central-rack indexes work.

SSL-ID 0x0111 - LED Status Information

Sublist 0x0111 reports the current state of the LEDs on the CPU front panel: SF, BF, BF1, BF2, MAINT, RUN, STOP, and any LED specific to the form factor. It is widely used by HMI panels to mirror the CPU LED state without parsing the diagnostic buffer.

Field Description
RETVAL = 0 Header and records valid
RETVAL = W#16#8085 SSL sublist does not exist (CPU too old)
RETVAL = W#16#80A2 Index error - the index you supplied is not in the valid range for this CPU's 0x111 implementation
RETVAL = W#16#80B1 CPU in STOP / HOLD / cold-restart state, partial list not yet populated

The classic 0x111 index 0 returns a single 28-byte record describing the LED bitfield. Index 1 and higher are reserved for rack extension in newer firmware and return "index not supported" on CPUs that predate the extension. This is the exact symptom observed in the field on a 414-2XJ01: SZL_ID = W#16#0111 with INDEX = 6 returns W#16#80A2 even though the documentation lists 0x111 as supported.

Index discipline: A non-zero RETVAL from SFC51 does not necessarily mean the SSL-ID itself is unsupported - it may mean that only the index you supplied is unsupported. Code must always loop the index from the documented minimum up to the documented maximum, not assume a contiguous range.

SSL-ID 0x0195 - Safety Mode Status (S7-400F / FH)

Sublist 0x0195 is reserved for fail-safe CPU functionality. On a standard S7-400, calling SFC51 with SZL_ID = W#16#0195 returns W#16#8085 ("sublist does not exist") regardless of firmware version, because the safety-mode partial lists are only generated when the F-runtime is active.

Index Subject Availability
0 Safety mode summary (active safety signature, F-CPU state) F and FH only
1..n F-runtime group state per group F and FH only, count of groups varies by CPU

If your application is built as a standard (non-F) project, 0x195 is irrelevant. If your application is a fail-safe project and you target an older F-CPU (for example CPU 416F-2 prior to firmware V4.x), check the F-CPU Instruction List for the exact firmware cut-in; the safety partial lists were extended several times across the F-CPU firmware history.

Index Handling and Partial List Extraction

The INDEX parameter of SFC51 has three operational meanings depending on the SSL-ID:

  1. Single-record selector: INDEX returns one record of N bytes - e.g. 0x111 with INDEX 0.
  2. Slot / station selector: INDEX addresses a physical slot, PROFIBUS station, or PROFINET device - e.g. 0x90 with INDEX 1..31.
  3. Range selector: INDEX 0 means "all records" and BUSY is held true while the CPU fills the DR area over multiple OB1 cycles (asynchronous read). You must dimension DR to N_DR * 28 bytes after the call completes.

Common RETVAL codes to expect in production code:

RETVAL (hex) Meaning Engineer action
0000 Success, data valid Proceed to parse DR
7000 BUSY, asynchronous read in progress Call again next cycle
8085 SSL sublist does not exist for this CPU Skip this SSL-ID or fall back to alternative
80A2 Index error - this index not valid for this CPU / SSL Skip this index and continue with next
80B1 CPU state prevents reading (STOP / startup / HOLD) Retry once CPU is in RUN, do not interpret as permanent error
80C3 Resource bottleneck (read in progress by another caller) Retry on next OB1 cycle, add jitter if contention persists
80D0 / 80D1 Communication error reading distributed sublist Check bus state, increase retry count

Locating Instruction List Documentation

The authoritative source for SSL-ID and INDEX coverage is the Instruction List (German: Operationsliste) for the target CPU family. Each Instruction List contains a System Status Sublist section that lists every supported SSL-ID, valid index ranges, record length, and the firmware version where the sublist was introduced. The manuals are hosted on the Siemens Industry Online Support portal:

For legacy CPUs whose manuals have been delisted from the main support tree, the historical "Operations List" PDFs are typically preserved as scanned PDFs in the legacy support.automation.siemens.com URL tree and can be retrieved via the entry-ID redirector. The Siemens support portal accepts the entry ID in the URL form /cs/ww/en/view/<entryID> and resolves archived manuals transparently.

Procurement: Older firmware-specific manuals are sometimes only available inside the Siemens "Premium Support" tier or as scanned PDFs linked from the global FAQ "Which manuals are available for legacy SIMATIC products?". Engineering teams maintaining long-lifecycle plants should download and archive the Instruction List for every CPU type deployed on site at the time of commissioning - the document is essentially irreplaceable once the entry is delisted.

Compatibility Verification Procedure

When porting an existing FB / FC that uses SFC51 to a new CPU or firmware version, run the following sequence in the order given. Stop on first failure.

  1. Open the Instruction List for the target CPU family (links above) and navigate to the System Status Sublists appendix.
  2. Locate each SZL_ID in your code and verify that the appendix lists the SSL-ID as supported on the target CPU. Mark "not supported" entries as platform-incompatible.
  3. For each supported SSL-ID, write down the documented index range. Note the firmware cut-in where the range was extended.
  4. Read out the CPU type and firmware from the CPU front panel or via the online diagnostic view in STEP 7 / TIA Portal.
  5. Wrap every SFC51 call in a conditional that checks the target CPU's MLFB and firmware against the supported list. If the combination is not in the supported list, call a fallback path or set a "not supported" status word.
  6. Test each supported (SSL-ID, INDEX) combination in a commissioning test on the actual CPU or on a PLCSIM instance of the matching CPU type. Confirm that RETVAL = 0 and that N_DR from the header is non-zero where the SSL-ID is supposed to return at least one record.
  7. Test the asynchronous (INDEX 0 = "all records") path separately. BUSY must be polled across multiple OB1 cycles and the destination area must be sized for the worst-case N_DR.
  8. Document the compatibility matrix inline in the source code as a structured constant array so that the next engineer can read it without leaving the editor.

A reference skeleton for a guarded SFC51 call in structured text (STEP 7 classic, SCL):

FUNCTION_BLOCK FB_SSL_GuardedRead
VAR
  fbRDSYSST : RDSYSST;             // SFC51 instance
  tState    : INT := 0;            // 0=idle,1=busy,2=done,3=not-supported
  wSzlId    : WORD := W#16#0111;   // SSL-ID to read
  wIndex    : WORD := 0;           // 0 = all records (async)
  iRetVal   : INT;
END_VAR
BEGIN
  IF tState = 0 THEN
    IF IsSzlSupported(wSzlId, wIndex) THEN     // user-supplied compat check
      fbRDSYSST.REQ    := TRUE;
      fbRDSYSST.SZL_ID := wSzlId;
      fbRDSYSST.INDEX  := wIndex;
      tState           := 1;
    ELSE
      tState := 3;                            // mark not-supported
    END_IF;
  ELSIF tState = 1 THEN
    fbRDSYSST.REQ := FALSE;                   // pulse for next state read
    fbRDSYSST(REQ:=FALSE,
              SZL_ID:=wSzlId,
              INDEX:=wIndex,
              RET_VAL:=iRetVal,
              BUSY:=bBusy,
              SZL_HEADER:=szlHdr,
              DR:=pDr);
    IF NOT bBusy THEN
      IF iRetVal = 0 THEN
        tState := 2;                          // success
      ELSIF iRetVal = W#16#8085
         OR iRetVal = W#16#80A2 THEN
        tState := 3;                          // sublist / index not present
      ELSE
        tState := 4;                          // transient - retry next cycle
      END_IF;
    END_IF;
  END_IF;
END_FUNCTION_BLOCK

Troubleshooting Matrix

Symptom Likely RETVAL (hex) Root cause Corrective action
CPU LED mirrors OK in HMI but SSL read returns 8085 8085 SSL-ID not implemented in this CPU firmware Verify SSL-ID against Instruction List; fall back to SFC6 / SFC13 diagnostic buffer reads
Some indexes of an otherwise supported SSL-ID fail with 80A2 80A2 Index range was extended in newer firmware than the running CPU's Loop index from documented minimum to maximum; do not assume contiguous
Call returns 80B1 intermittently after power-on 80B1 CPU not yet in RUN when read was issued Skip the read while OB100 / OB101 is active; retry once startup completes
Call returns 80C3 every cycle 80C3 Multiple consumers reading same SSL with INDEX 0 (async) Serialize access with a semaphore; one async read at a time
Old 414-2XJ01 returns 8085 for 0x90 and 0x195 8085 Sublist predates this CPU's firmware Document as not supported; use older API (SFC51 with 0x11) or substitute SFC51 with SFC6 / SFC13
0x111 INDEX 6 returns 80A2 on 414-2XJ01 80A2 Index 6 part of an extension introduced after this CPU's ship date Reduce index range to documented legacy maximum (typically 0..3 for this CPU)
F-CPU standard project still returns data for 0x195 0000 (false success) Compiler / runtime substitution on F-CPU maps 0x195 to non-F sublist Do not call 0x195 from a standard project - branch on CPU MLFB before issuing the call

Legacy CPU Handling: The 414-2XJ01 Case

The 6ES7 414-2XJ01 is a pre-2000 vintage S7-400 CPU. Its Instruction List (Operations List) is no longer listed on the main Siemens support tree but is preserved as an archived PDF on the legacy support.automation.siemens.com URL. The symptoms observed on this CPU are:

  • SZL_ID = W#16#0090: returns W#16#8085 for PROFIBUS station indexes (INDEX 100..215). Central-rack indexes 1..31 work. The sublist existed on this CPU but with a narrower index range than modern firmware provides.
  • SZL_ID = W#16#0111: sublist supported, but only INDEX 0 returns a valid record. INDEX 1..n return W#16#80A2 because the multi-record LED partial list extension was introduced in firmware subsequent to this CPU's ship date.
  • SZL_ID = W#16#0195: returns W#16#8085 unconditionally. This CPU is not an F-CPU and the safety partial list is never generated.

When maintaining code that must run on such legacy CPUs:

  1. Read the CPU MLFB at startup (via SFC51 / SSL 0x0011, INDEX 0) and store it in an instance DB.
  2. Compare the MLFB against a whitelist of supported CPU types in the application code. If the running CPU is not on the list, set a "limited diagnostics" status and continue with the subset of SSL-IDs the legacy CPU supports.
  3. Loop every supported index from the documented minimum and break on first RETVAL = W#16#80A2 rather than treating it as a fatal error. This is the safest cross-version pattern.
  4. For the F-CPU sublists (0x195), make the call conditional on a project-wide "F-CPU build" flag rather than runtime CPU detection, because a misconfigured call on a non-F CPU produces misleading return codes on some firmware revisions.
Migration guidance: When modernizing a plant that includes pre-2000 S7-400 CPUs, treat the legacy Instruction List as a baseline and add a "CPU compatibility matrix" header to every FB that issues SFC51. The matrix should list every CPU MLFB the FB has been validated against, the firmware cut-in per SSL-ID, and the maximum index validated on each CPU. This document is the only reliable substitute for the missing firmware-cut-in tables in the System Software manual.

Frequently Asked Questions

Which Siemens manual lists every SSL-ID with its valid index range per CPU?

The CPU-family Instruction List (Operations List) contains a "System Status Sublists" appendix that lists every supported SZL_ID, its index range, record length, and the firmware cut-in. For S7-300 use entry ID 31977679, for S7-300C use 13206730, and for S7-400 use 23904435. The "System and Standard Functions" manual (entry ID 12151704) explains SFC51 semantics but not per-CPU support.

Why does SFC51 with SSL-ID 0x195 fail on a non-F S7-400?

Sublist 0x0195 is only generated when the F-runtime is active. On a standard S7-400 the safety partial lists do not exist, so SFC51 returns RETVAL = W#16#8085 regardless of firmware. Call 0x0195 only from fail-safe projects on F or FH CPUs.

SFC51 with SSL-ID 0x111 returns 0x80A2 on an old CPU - is the SSL-ID unsupported?

Not necessarily. W#16#80A2 means "index not supported" while the SSL-ID itself is fine. On a 414-2XJ01, 0x111 is supported with INDEX 0 only; indexes above the legacy maximum return 0x80A2. Loop index from the documented minimum and break on first 0x80A2 instead of treating it as a fatal error.

What is the difference between INDEX 0 (async) and a fixed INDEX on SFC51?

With a fixed INDEX, SFC51 returns one record synchronously within one OB1 cycle and you size DR to 28 bytes. With INDEX 0, the CPU streams all records asynchronously: BUSY stays true across multiple OB1 cycles and you must size DR to N_DR * 28 bytes after the call completes. Two consumers using INDEX 0 on the same SSL-ID at the same time will collide and return W#16#80C3.

Can I use SSL-ID 0x90 to identify a PROFIBUS slave on every S7-300 CPU?

No. 0x90 with PROFIBUS station indexes (typically 100..215) requires a CPU and firmware revision that implements the extended module-identification sublist. On a very old CPU such as 414-2XJ01, those indexes return W#16#8085 even though central-rack indexes work. Always cross-check against the Instruction List appendix for the specific CPU MLFB and firmware version deployed on site.

Back to blog