Reading RUN LED Status via SFC51 (RDSYSST) on S7-400 CPUs
This technical reference documents the procedure for reading the RUN/STOP LED status of a Siemens S7-400 CPU using the system function SFC51 (RDSYSST). The content targets engineers commissioning, troubleshooting, or maintaining CPU 412-5H PN/DP and related S7-300/S7-400 systems that report LED state into a WinCC HMI such as the TP1500 Comfort. The article explains the SZL (System State List) IDs required, the cause of error W#16#8082, the behavioral gap when the CPU is in STOP, and a robust clock-merker workaround for SCADA supervision.
1. Overview of SFC51 / RDSYSST
SFC51 reads a partial list of the System Status List (SSL) at runtime. The SSL is a virtual database maintained by the CPU's firmware that contains diagnostic data, module status information, communication state, and—most relevant here—the LED status partial lists for the CPU.
The function block is documented in the Siemens manual "System Software for S7-300/400 - System and Standard Functions" (entry ID 109751706) and is invoked from the user program in OB1, OB35, or any cyclic OB. The call signature is:
| Parameter | Type | Description |
|---|---|---|
| REQ | INPUT (BOOL) | Edge-triggered request: set to 1 to start the read |
| SZL_ID | INPUT (WORD) | Identifier of the SSL partial list (e.g. W#16#0119, W#16#0174) |
| INDEX | INPUT (WORD) | Object number within the partial list |
| RET_VAL | OUTPUT (INT) | Error code; W#16#0000 if successful |
| BUSY | OUTPUT (BOOL) | 1 while read is in progress (asynchronous mode) |
| SZL_HEADER | OUTPUT (STRUCT) | LENGTH_DR, N_DR returned by the CPU |
| DR | OUTPUT (ANY) | Destination area that receives the SZL data record |
The SZL read is triggered on a positive edge at REQ. If the call completes synchronously, BUSY returns to 0 and the data record is already in DR. If the operation is asynchronous, BUSY = 1 and SFC51 must be called repeatedly with REQ = 1 until BUSY falls. Reference: RDSYSST - Read System Status List (S7-300, S7-400) - TIA Portal V20 documentation.
2. SZL IDs for CPU LED Status
Two SZL partial lists are commonly used to obtain CPU LED state:
| SZL_ID | Index | Returned Data | Typical Use |
|---|---|---|---|
| W#16#0119 | W#16#0000 | Complete CPU status word (RUN/STOP, HALT, fault, force, etc.) | Preferred for diagnostic overview |
| W#16#0119 | W#16#0001…0007 | Status of object types (CPU itself, CPs, etc.) | Targeted module checks |
| W#16#0174 | W#16#0000 | LED status partial list (dedicated to LED information) | Compact LED-only read |
| W#16#0174 | W#16#0001 | LED status of the first relevant object | Index-based LED query |
The structure returned for SZL_ID = W#16#0119 with INDEX = 0 is a WORD bitfield where the meaning of each bit is defined in the CPU's reference manual. The high byte typically contains the LED state (RUN, STOP, HALT, LINK, MAINT, IFM1F, MSTR) and the low byte contains the operating mode. The exact assignment depends on the CPU generation—consult the manual for your specific order number (e.g. 6ES7 412-5HK06-0AB0).
3. Call Structure in STL / SCL
The two implementations below are functionally equivalent. Use the SCL version in modern projects; the STL version is shown for legacy STEP 7 V5.x projects.
STL (Statement List) - synchronous, single call:
// --- Read CPU status with SFC51 (RDSYSST) ---
// Trigger on OB1 scan or rising edge
U "M_SFC51_REQ"; // 1-cycle pulse from edge detection
= "DB_LED".REQ;
// Source data area sized per SZL_HEADER
CALL SFC 51
REQ := "DB_LED".REQ
SZL_ID := W#16#119 // CPU status partial list
INDEX := W#16#0
RET_VAL:= "DB_LED".RET_VAL
BUSY := "DB_LED".BUSY
SZL_HEADER := "DB_LED".HDR
DR := P#DB100.DBX 0.0 BYTE 20 // big enough to hold N_DR bytes
NOP 0;
// If RET_VAL <> 0 propagate to HMI alarm word
L "DB_LED".RET_VAL;
L 0;
<>I ;
S "ALARM_SFC51_ERR";
SCL (Structured Control Language) for S7-300/400 in STEP 7 V5.5+:
// SCL block FB_LED_Status, called in OB35 at 100 ms
IF bStart AND NOT bBusy THEN
iRetVal := RDSYSST(
REQ := TRUE,
SZL_ID := W#16#119,
INDEX := W#16#0,
BUSY := bBusy,
SZL_HEADER := sHeader,
DR := P#DB100.DBX0.0 BYTE 20);
IF iRetVal = 0 THEN
wCpuStatus := DWORD_TO_WORD(HEADER_TO_DWORD(sHeader));
END_IF;
END_IF;
Asynchronous pattern (recommended for S7-400 / S7-400H CPUs where reads can span multiple OB cycles):
// OB1 edge-triggered start
IF "DB_LED".REQ AND NOT "DB_LED".Busy THEN
"DB_LED".ReqPulse := TRUE;
END_IF;
// OB1 - keep calling until BUSY falls
IF "DB_LED".ReqPulse THEN
"DB_LED".RetVal := RDSYSST(
REQ := "DB_LED".ReqPulse,
SZL_ID := "DB_LED".SzlId,
INDEX := "DB_LED".Index,
BUSY := "DB_LED".Busy,
SZL_HEADER := "DB_LED".Hdr,
DR := P#DB100.DBX0.0 BYTE 20);
IF NOT "DB_LED".Busy THEN
"DB_LED".ReqPulse := FALSE;
END_IF;
END_IF;
4. CPU 412-5H PN/DP Compatibility Notes
The 6ES7 412-5HK06-0AB0 (CPU 412-5H PN/DP) is a high-availability CPU of the S7-400H family. SFC51 is fully supported; however:
- Always install the latest firmware available from Siemens Industry Online Support (article ID 109751706) before relying on SZL ID W#16#0174. Older firmware (≤ V4.5) may not implement this partial list.
- In an H system, SFC51 reads the state of the CPU on which the block is executed (A-CPU or B-CPU). The H-programming manual recommends calling SFC51 on both sides and combining results if you need aggregated H-status.
- Reserve a destination area (DR) of at least 20 bytes for SZL 0119/0; undersized DR areas produce error W#16#8082 (the same code as "unknown SZL"), which makes field diagnostics confusing. Always check
SZL_HEADER.LENGTH_DRandSZL_HEADER.N_DRafter the call to size DR correctly.
| Firmware | W#16#0119/0 | W#16#0174/0 | Notes |
|---|---|---|---|
| V4.0 | Supported | Not implemented | Use 0119/0 fallback |
| V5.0 | Supported | Supported | Index 0 valid |
| V6.0 | Supported | Supported | Index ≥ 0 valid |
5. Error Code 8082 - Root Cause and Resolution
W#16#8082 (decimal -32638 or 32638 unsigned) is the most common error reported by SFC51. The official meaning per the STEP 7 manual is:
"SSL_ID is wrong, or the requested SSL partial list is not implemented in the CPU, or the data record (DR) is too small to receive the data."
This single error code has three distinct root causes. Diagnose them in the order below:
5.1 Wrong SZL_ID
Confirm the SZL_ID against the CPU's reference manual. W#16#174 without the leading 0, or with a typo (e.g. W#16#1744), is a common mistake. Always format the literal as W#16#0174 (4 hex digits).
5.2 SZL not implemented in this CPU/firmware
The S7-400H CPU 412-5H PN/DP does not implement every SZL partial list. If the manual does not list W#16#0174 for your firmware version, fall back to W#16#0119/0. Reference: Siemens Industry Online Support entry IDs 1111126 and 16689448.
5.3 Destination area (DR) too small
The DR ANY pointer must reference a memory area whose size is greater than or equal to SZL_HEADER.N_DR. If N_DR = 16 and you declared DR as BYTES 8, SFC51 returns 8082. Fix by enlarging the DB area (typical values: 16, 20, 26, or 34 bytes depending on the SZL).
6. STOP-Mode Behavior: The LED-Reading Gap
The most important behavioral limitation of SFC51 is that it can only be called from a running CPU. When the CPU enters STOP or HALT, the OB1, OB35, and OB100 error OBs cease to execute, and SFC51 calls return without update. In practical terms:
- The user program stops; the last value of the LED status word remains in the DB but is no longer refreshed.
- The HMI receives the last RUN status and may falsely indicate "CPU healthy" even though the CPU is in STOP.
- The diagnostic buffer, OB100 / OB102, and the STOP LED must be inspected physically or via the SIMATIC Manager to determine the cause of the STOP.
This is precisely why the second technical approach in the field—using a clock merker (clock bit) edge detector—is widely deployed. It is independent of user-program execution timing and reliably indicates whether the controller is still alive.
7. Workaround: Clock Merker for RUN-State Detection
Clock merkers (clock bytes) are bits inside the CPU that toggle at a fixed duty cycle regardless of the user program state, as long as the CPU is in RUN. By monitoring the edge of a clock merker in WinCC or a TP1500 Comfort HMI, you can determine whether the CPU has stopped scanning.
- In HW Config (or TIA Portal device configuration), enable a clock merker byte (e.g. MB10) and set the period to 1 Hz (period = 1.0 s, duty 50%).
- From WinCC, create a tag that reads M10.0 and stores its last cycle value.
- Configure a tag trigger: if M10.0 does not change state within 3 seconds, raise a "CPU not scanning / line interruption" alarm.
- Cross-check: when the WinCC alarm fires, also fetch the diagnostic buffer via S7-protocol diagnostic request to identify the STOP cause.
| Method | RUN detection | STOP detection | Detailed LED bit | CPU-independent |
|---|---|---|---|---|
| SFC51 (RDSYSST) | Yes (synchronous) | Last valid only | Yes (W#16#0119, W#16#0174) | No (needs program execution) |
| Clock merker edge in WinCC | Yes (1 Hz toggle) | Yes (no edge ≥ 3 s) | No | Yes |
| S7-Diagnostic buffer | After event | Yes | Partial | Yes |
8. Integration with WinCC / TP1500 Comfort
The TP1500 Comfort can be configured in WinCC Professional / TIA Portal to display the CPU LED status read from SFC51:
- Create a raw tag in the HMI connection, e.g.
DB100.DBW0, length WORD. - Add the SFC51 call to an OB that runs at a slower rate (OB35, 100 ms typical) to limit PLC load.
- Map the bits of the status word onto graphics: green lamp = RUN, red lamp = STOP, yellow lamp = HALT. The exact bit positions are documented in the CPU's "Status and Fault Indicators" section.
- Configure a status pane that shows the raw value of
RET_VALduring commissioning. This is the fastest way to detect a lingering 8082 error during HMI bring-up.
For an S7-400H pair, repeat the configuration on the second CPU and create a combined HMI tag that shows the worst-case status (RUN + RUN = healthy, RUN + STOP = degraded, STOP + STOP = fault).
9. Step-by-Step Commissioning Procedure
- Open the project in STEP 7 V5.5 or TIA Portal V16+ (V20 for the latest documentation set). Confirm the CPU hardware matches the configured type (412-5H PN/DP, 6ES7 412-5HK06-0AB0).
- Check the CPU's firmware version in PLC > Online > Accessible Nodes. Update to ≥ V5.0 if you plan to use SZL 0174.
- Create a global DB, e.g.
DB_LED, with the SFC51 parameter set and a 20-byte work area. - Insert the SFC51 call in OB1 with edge-triggered REQ using a 1 Hz clock merker or a periodic OB35 tick.
- Compile, download, and switch the CPU to RUN.
- Read
RET_VALonline; confirm W#16#0000. - For each SZL you plan to use, read
SZL_HEADER.LENGTH_DRand resizeDRaccordingly. The cycle "check RET_VAL → resize DR → re-download → re-test" takes 1-2 minutes per SZL. - Test error paths: force the CPU into STOP via the programming device, then observe that the last SFC51 result remains unchanged in the HMI and the clock-merker watchdog triggers a separate alarm.
- Document the SZL assignments and the watchdog timeout in the project documentation so that future maintenance engineers can quickly verify the configuration.
10. Verification Checklist
- RET_VAL = W#16#0000 in every cycle after the first successful read.
- BUSY returns to 0 within one OB cycle for the CPU and SZL you are using (synchronous mode is the most common case for 0119/0).
- DR contains a non-zero value with the LED bits at the expected positions.
- Clock merker M10.0 toggles at 1 Hz on the TP1500 Comfort tag view.
- Force-stopping the CPU causes the LED status HMI tag to freeze at the last RUN value while the watchdog alarm fires within 3 s.
- CPU diagnostic buffer is readable from the programming device (Online > Diagnostic Buffer) and contains the expected STOP entry.
11. Troubleshooting Matrix
| Symptom | Probable Cause | Corrective Action |
|---|---|---|
| RET_VAL = W#16#8082 with SZL 0174 / INDEX 0 | Index 0 not valid for this CPU/firmware | Switch to INDEX ≥ 1, or use SZL 0119 / INDEX 0 |
| RET_VAL = W#16#8082 with valid parameters | DR too small | Read SZL_HEADER.N_DR and increase DB area |
| RET_VAL = W#16#8082 in old firmware | SZL 0174 not implemented | Update firmware or use SZL 0119 |
| HMI shows RUN but CPU LED is STOP | User program stopped; SFC51 no longer called | Add clock-merker watchdog |
| SFC51 RET_VAL = W#16#80C3 | Resource bottleneck / re-entrancy | Lengthen call interval; serialize SFC51 calls in OB1 |
| Always 0 returned in DR | DR not correctly aligned to ANY pointer | Verify pointer byte offset and bit alignment |
| Tags flicker between 0 and 1 | Multiple sources writing same tag | Use a single OB1/OB35 call and a write-protected area |
12. State Machine - LED Read Lifecycle
13. Best Practices and Field-Proven Caveats
- Always read RET_VAL and BUSY; never assume success. A 8082 can lurk unnoticed for days if you only ever read the DR buffer.
- Use OB35 (100 ms) or OB82 (diagnostic interrupt) as the trigger OB. Avoid OB1 with edge detection unless you need sub-100 ms response—SFC51 has CPU-specific latency that can break tight loops.
- For S7-400H systems, duplicate the call on both CPUs. SFC51 cannot fetch state from the partner CPU; it only reports on the CPU that runs the call.
- Document the DR sizing in the DB header. Different SZLs have different record sizes (2, 4, 16, 20, 26 bytes). A static 20-byte buffer covers the LED/status SZLs but not the diagnostic buffer SZLs (typically 240 bytes).
- Implement a clock-merker watchdog even if SFC51 is working. The two methods cover each other's blind spots.
- For WinCC TP1500 Comfort, use the "Life beat" or "Poll with change of state" tag acquisition mode. Polling at 1 s gives a clear edge for the watchdog.
14. FAQ
Why does SFC51 return error 8082 on CPU 412-5H PN/DP?
Error W#16#8082 means the SZL_ID is invalid for the firmware, INDEX 0 is not implemented, or the destination area (DR) is smaller than SZL_HEADER.N_DR. First try SZL_ID = W#16#0119 with INDEX = W#16#0, and ensure your DR area is at least 20 bytes. Reference: STEP 7 System and Standard Functions manual, error-code table.
Can SFC51 read the LED status when the CPU is in STOP?
No. SFC51 is a user-program block; once the CPU leaves RUN, the cyclic OBs stop and SFC51 is not called. The last valid LED status remains in the DB but is not refreshed. Use a clock merker (e.g. M10.0 at 1 Hz) and a WinCC watchdog to detect a STOP-state condition.
What is the difference between SZL 0x0119 and SZL 0x0174?
SZL W#16#0119 is the CPU status partial list and is broadly supported. SZL W#16#0174 is the dedicated LED status partial list and is supported on newer S7-400 firmware (V5.0+). For maximum compatibility on older or H-systems, prefer W#16#0119/0.
How do I size the destination area (DR) for SFC51?
Run SFC51 once with a large temporary DR (e.g. 50 bytes) and read SZL_HEADER.N_DR from the returned header. Allocate the DB area to that exact byte count. For W#16#0119/0 the typical size is 4-20 bytes; for W#16#0174/0 it is 4-16 bytes. Always round up to the next even byte.
Is SFC51 supported in a redundant S7-400H pair?
Yes. SFC51 runs independently on each CPU and reports the local CPU's state. Deploy the call on both sides and combine the LED status in the HMI to show the worst-case condition between A-CPU and B-CPU. Reference: S7-400H programmable controller system manual, entry ID 1111126.