S7-300 Module Health Monitoring: SFC13/SFC51 Beyond RSE

David Krause17 min read
S7-300SiemensTechnical 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

Overview: Why Report System Error (RSE) Is Not Always the Right Tool

On S7-300/400 controllers (and their ET200 distributed I/O siblings), Siemens ships a wizard called Report System Errors (RSE). The wizard generates standardized diagnostic message blocks (FB/s for OB82, OB83, OB84, OB85, OB86, OB87, OB121, OB122), automatically renders incoming diagnostics in WinCC as operator messages, and keeps the HMI in sync with PLC errors. For the broad case of "tell me when something fails, send the right error number to the operator" RSE is excellent.

What RSE is not designed for is fine-grained, user-defined health evaluation of a specific I/O card in a specific slot. The wizard works on the standard DP/PN diagnostic record set that Siemens publishes; it does not let you strip out, for example, channel-level "wire break on channel 4 of the analog input card in slot 5" and turn that into a boolean flag you can interlock on, without re-routing the message through HMI tags. The original engineering problem surfaced in field deployments of ET200M on PROFIBUS with an IM 153-2 (6ES7 153-2BA02-0XB0) interface module and mixed SM 321 (6ES7 321-1BH02-0AA0) digital input and SM 331 (6ES7 331-7KF02-0AB0) analog input cards. RSE raised the error, but no usable per-card health bit was exposed for code interlock.

This reference documents the alternative path: combining SFC 13 "DP_DIAG" (read PROFIBUS DP slave diagnostic buffer) with SFC 51 "RDSYSST" (read system status list, SSL) and, where needed, the channel-level diagnostic records accessible through the standard slave diagnostics. With these calls you can build a deterministic, code-consumable health flag per slot, per channel group, or per module — without depending on WinCC message routing or HMI acknowledgement state.

Scope. This article targets STEP 7 V5.5/V5.6 on S7-300 CPUs (3xx/3xxF/3xxT/3xxC) and S7-400 CPUs, with ET200M stations on PROFIBUS DP. PROFINET variants (SFC 13 still applies but with PN diagnostic records) follow the same pattern; see the Siemens Support entry 22727527 for the WinCC/RSE wiring side.

What Report System Error (RSE) Actually Does

RSE is invoked from HW Config → Options → Report System Error. On activation the wizard generates:

  • Diagnostic OB code (FB / DB pair per OB) for OBs 82, 83, 84, 85, 86, 87, 121, 122.
  • Text libraries under the WinCC project that translate the Siemens standard diagnostic numbers into operator messages.
  • Automatic registration of each rack/slot in the diagnostic target so that a pull, a fault, or a wire break on a referenced channel generates a defined message in WinCC with rack/slot coordinates.

The input source is the standard diagnostic frame of the DP/PN slave. ET200M stations feed the IM 153-2 (6ES7 153-2BA02-0XB0) which aggregates the SM 321, SM 331, SM 332, SM 322 and other cards behind it into the PROFIBUS DP standard diagnostic record (6 bytes of station diagnostics + module status + channel-related diagnostics). RSE renders that frame, but the granularity of what is exposed to the program is determined by the wizard, not by the user. This is the core limitation when a control engineer needs a bit per card usable inside FBD/LAD/ST code without involving the HMI layer.

RSE Standard Diagnostic Sources

OB Trigger RSE output
OB 82 Diagnostic interrupt (module/channel error) WinCC message with slot, channel, error type
OB 83 Insert/remove interrupt WinCC message "module pulled / returned"
OB 84 CPU redundancy change H-system only
OB 85 OB not found / class 1 fault WinCC message on process image update failure
OB 86 DP/PN slave failure WinCC message "station failure / return"
OB 87 Communication fault WinCC message
OB 121 Programming error WinCC message
OB 122 I/O access error WinCC message

None of these give a program-consumable "CardInSlotN_Healthy := BOOL;" by themselves. The WinCC side renders the message, but the PLC program still needs to query the diagnostic data itself.

When RSE Falls Short: The Custom Diagnostic Requirement

Three field situations where RSE is insufficient and a custom SFC 13 / SFC 51 path is required:

  1. Pre-interlock health gate. A motion function block should refuse to start if a safety-relevant DI card (e.g. SM 326F) is reporting wire break on any channel. The PLC needs a boolean, not an HMI message.
  2. Per-card degradation detection. An SM 331 (6ES7 331-7KF02-0AB0) reports overflow on channel 3; the recipe should be paused but the rest of the rack should keep running. RSE reports "overflow at slot X channel 3" to WinCC, but the program must read the channel-level bit.
  3. Loss of a single sub-module behind an ET200M. The IM 153-2 stays present on PROFIBUS but one of the SM cards downstream is gone. OB 86 fires only on full station failure, not on partial. SFC 13 with the standard diagnostic record reads the per-slot status byte inside the station diagnostic and exposes the per-card bit.

Prerequisites

  • STEP 7 V5.5 SP4 or V5.6 with HW Config and the Standard Library "IEC S7 Blocks" and "System Function Blocks" available.
  • S7-300 / S7-400 CPU with firmware ≥ the version listed in the catalog for the SSL partial lists referenced (most S7-300 CPUs from 314C onwards and all S7-400 CPUs support the relevant SSL IDs).
  • ET200M station with IM 153-2 (6ES7 153-2BA02-0XB0) for PROFIBUS, or IM 153-4 (6ES7 153-4AA01-0XB0) for PROFINET.
  • Configured DI / DO / AI / AO cards in HW Config with their diagnostic-capable article numbers (e.g. 6ES7 321-1BH02-0AA0, 6ES7 322-1HH01-0AA0, 6ES7 331-7KF02-0AB0, 6ES7 332-5HF00-0AB0).
  • Symbolic names assigned per slot, e.g. IM153_S1_DI32_Slot4, to keep the cross-reference readable.

Module Identification: Catalog Numbers and Slot Map

The ET200M rack used as a reference here is a typical PROFIBUS DP-V1 station. The slot map must match the HW Config exactly. Any drift between HW Config and physical rack invalidates the diagnostic decode.

Slot Module Article No. Diagnostic-relevant?
0 IM 153-2 (Head) 6ES7 153-2BA02-0XB0 Yes (station diagnostics)
1 SM 321 DI16 × DC24V 6ES7 321-1BH02-0AA0 Yes (wire break / channel error on supported variants)
2 SM 321 DI16 × DC24V 6ES7 321-1BH02-0AA0 Yes
3 SM 322 DO16 × DC24V/0.5A 6ES7 322-1BH01-0AA0 Yes
4 SM 331 AI8 × 12 bit 6ES7 331-7KF02-0AB0 Yes (overflow / underflow / wire break)
5 SM 332 AO4 × 12 bit 6ES7 332-5HB01-0AB0 Yes

Slots 1–5 are where SFC 13 will return the per-slot module status byte inside the station diagnostic record. The IM 153-2 is the gateway to PROFIBUS: it aggregates all sub-modules and reports a single DP slave diagnostic frame to the CPU.

SFC 13 "DP_DIAG" — Reading the Slave Diagnostic Frame

SFC 13 is the standard call to read the PROFIBUS DP diagnostic buffer of a slave (master-system-aware). The call returns the six-byte station diagnosis, the identifier-based module status (one byte per slot indicating "OK / wrong / missing / faulty"), and any identifier-based channel-related diagnostic records.

Call Signature

// STL style
CALL  SFC  13
     REQ    := TRUE               // edge-triggered read
     LADDR  := W#16#03E8          // PROFIBUS I/O address of the slave (HW Config -> DP slave Properties -> Diagnostic address)
     RETVAL := #iRetVal            // return value: 0 = OK, 8091 = unsupported, 80B1 = data length error, etc.
     BUSY   := #bBusy
     RECORD := P#DB_StatDiag.DBX0.0 BYTE 128   // destination area; must be at least 128 bytes

Layout of the Result Buffer

Offset (byte) Length Content
0..5 6 Station status (byte 0 = station_status_1, byte 1 = station_status_2, bytes 2..5 = station_status_3)
6..7 2 Vendor-specific high-word of vendor ID (PROFIBUS DP-V1)
8..10 3 Module status header: byte 8 = "module status" count, bytes 9..10 = slot / channel identifier structure
11..(11+2·n) 2 per slot Module status entries: byte = slot number, byte = module status code
Following Variable Channel-related diagnostic records (header + entries)

Module Status Code Meanings

Code (hex) Meaning Action for health flag
0x00 No entry Skip
0x10 Wrong module in slot Unhealthy
0x20 Module OK Healthy
0x30 Module faulty Unhealthy
0x40 Module not present Unhealthy (treat as missing)
0x70 Module in self-test Hold last state, do not flag unhealthy yet

Pattern: Decode the Per-Slot Module Status

After SFC 13 has filled a data block (recommend a dedicated DB_DiagResult instance), walk the entries starting at offset 11, two bytes at a time, until you hit the marker 0x80 on the slot field. Store the slot and the status code into two parallel byte arrays sized to the maximum rack width (16 slots for ET200M).

// FBD/ST style pseudocode for the decoder
FOR n := 1 TO 16 DO
    slotByte   := DB_DiagResult.DBD[n*2 + 11].B0;
    statusByte := DB_DiagResult.DBD[n*2 + 12].B0;
    IF slotByte = 16#80 THEN EXIT; END_IF;
    "DiagSlot".SLOT[n]   := slotByte;
    "DiagSlot".STATUS[n] := statusByte;
    "DiagSlot".HEALTH[n] := (statusByte = 16#20);
END_FOR;

The result is a 16-element boolean array DiagSlot.HEALTH[n] usable directly in the application code. This is the missing piece RSE does not expose.

RETVAL troubleshooting. If SFC 13 returns 0x8091 the slave does not support the standard diagnostic record (rare on ET200M, common on third-party DP slaves). If it returns 0x80B1 the destination buffer is too small — increase from 128 to 240 bytes. A persistent 0x8085 means the diagnostic address in HW Config does not match the physical configuration.

SFC 51 "RDSYSST" — Reading the System Status List

Where SFC 13 reads the DP-slave-level diagnostic frame, SFC 51 reads the System Status List (SSL) maintained inside the CPU. The SSL is the canonical view of "what modules exist, in which slots, in what state". Two SSL partial lists are particularly relevant:

SSL_ID INDEX Meaning
W#16#0092 Slot All slots of the local rack and configured DP/PN stations; returns slot number, module type, module OK / faulty / missing
W#16#0094 Slot Rack / station fault status: returns 0 if everything OK, non-zero if at least one slot in that rack is faulty or missing
W#16#00A0 0 Diagnostic buffer of the CPU (events with timestamp)
W#16#0222 Slot Channel-specific diagnostic of the slot (analog wire break, overflow, etc.) — only populated if the card supports channel diagnostics

Call Signature

CALL  SFC  51
     REQ    := TRUE
     SSL_ID := W#16#0092            // module information
     INDEX  := W#16#0001            // rack 0 / slot 1
     RETVAL := #iRetVal
     BUSY   := #bBusy
     SZL_HEADER := #SSL_Header      // 12-byte SSL header
     DR    := P#DB_SSL.DBX0.0 BYTE 256

Per-Slot Module Information Record (SSL 0x0092)

Offset (word) Content
0 Logical address of the slot
2 Module type code (1=IM, 4=DI, 5=DO, 6=AI, 7=AO, etc.)
4 Reserved
6 Status word: bit 0 = faulty, bit 1 = wrong module, bit 2 = module OK, bit 3 = not present
8 Reserved

Bit 2 of the status word is the cleanest card healthy flag at the CPU level. Combine with the SFC 13 module status (which comes from the slave, not the CPU) to disambiguate "slave alive but card dead" from "slave dead".

PROFINET note. On PROFINET the SSL 0x0092 record still applies at the CPU, but at the station level the equivalent of SFC 13 is a slot-level channel diagnostic read via PN record index 0x800A. The technique is identical: walk the records and decode.

Building the Per-Card Health Flag — Integration Pattern

The minimum viable pattern combines the two calls and ORs the results into one boolean array indexed by slot. The pattern below assumes a cyclic OB (OB 1) at the top of which OB 82 will have been processed by RSE (for the HMI), and a separate OB 35 (100 ms) time slice for the diagnostic call so the PROFIBUS bus is not overloaded.

Data Block Layout

DATA_BLOCK DB_Diag
  STRUCT
    DP_DiagBuf  : ARRAY [1..240] OF BYTE;   // SFC 13 destination
    SSL_Header  : ARRAY [1..12]  OF BYTE;   // SFC 51 header
    SSL_Buf     : ARRAY [1..256] OF BYTE;   // SFC 51 destination
    SlotStatus  : ARRAY [0..15]  OF BYTE;   // 16 = healthy, anything else = degraded
    SlotHealthy : ARRAY [0..15]  OF BOOL;
    StationOK   : BOOL;
    LastRetVal  : INT;
  END_STRUCT;
END_DATA_BLOCK

OB 35 Slice (ladder-equivalent STL/ST)

// Step 1: trigger SFC 13 once per cycle to refresh DP slave diagnostic
IF NOT "DB_Diag".SFC13_BUSY THEN
    CALL  SFC  13
         REQ    := TRUE
         LADDR  := W#16#03E8              // IM 153-2 diagnostic address
         RETVAL := "DB_Diag".LastRetVal
         BUSY   := "DB_Diag".SFC13_BUSY
         RECORD := P#"DB_Diag".DP_DiagBuf;
END_IF;

// Step 2: trigger SFC 51 once per cycle to refresh CPU-side SSL slot view
IF NOT "DB_Diag".SFC51_BUSY THEN
    CALL  SFC  51
         REQ    := TRUE
         SSL_ID := W#16#0092
         INDEX  := W#16#0000              // full rack / station view
         RETVAL := "DB_Diag".LastRetVal
         BUSY   := "DB_Diag".SFC51_BUSY
         SZL_HEADER := P#"DB_Diag".SSL_Header
         DR    := P#"DB_Diag".SSL_Buf;
END_IF;

// Step 3: decode SFC 13 result (starts at offset 11, two bytes per slot)
FOR n := 0 TO 15 DO
    IF "DB_Diag".DP_DiagBuf[11 + 2*n] = 16#80 THEN
        "DB_Diag".SlotStatus[n] := 16#FF;     // no entry — leave as unknown
    ELSE
        "DB_Diag".SlotStatus[n] := "DB_Diag".DP_DiagBuf[11 + 2*n + 1];
    END_IF;
    "DB_Diag".SlotHealthy[n] :=
        ("DB_Diag".SlotStatus[n] = 16#20);
END_FOR;

Using the Flag in a Function Block

FUNCTION_BLOCK FB_HeathGate
VAR_INPUT
    RequiredSlot : INT;        // which slot must be healthy
END_VAR
VAR
    bHealthy : BOOL;
END_VAR
BEGIN
    bHealthy := "DB_Diag".SlotHealthy[RequiredSlot];
    // pass to interlock
END_FUNCTION_BLOCK

Now any higher-level FB can demand that a specific slot be healthy (e.g. safety DI card at slot 1) without going through HMI message acknowledgement.

Channel-Level Diagnostics: Overflow, Underflow, Wire Break

For cards that publish channel-level diagnostics (SM 331-7KF02-0AB0 for overflow/underflow/wire break; SM 326F for safety-relevant channel faults), SFC 13 returns channel-related diagnostic records after the module status block. The structure is:

Word Content
0 Channel error vector for the slot (each bit = one channel)
2 Channel fault type code (overflow, underflow, wire break, short to M, etc.)
4 Direction (input / output)
6 Slot number and channel qualifier

Parse the channel error vector (first word) to build a "ChannelFault[n].Health[n]" mask. For an 8-channel SM 331 this gives 8 booleans per slot.

Verification: How to Test the Health Flag

  1. Power-up watch. Force the IM 153-2 diagnostic address into a VAT table and step OB 1. After 100 ms the SlotHealthy array must be filled. Initially slot 0 (IM) is not in the array — verify by spotting 16#20 at slot indices 1..5 in the DP_DiagBuf.
  2. Pull test. With the PLC in STOP, pull the SM 331 from slot 4. Set the CPU to RUN. Within one OB 35 cycle, SlotHealthy[4] must drop to FALSE and SlotStatus[4] must read 16#40 (module not present). Slot 5 (SM 332) must remain 16#20.
  3. Channel fault injection. Open-circuit the sensor on channel 3 of the SM 331. Within one OB 35 cycle the channel error vector bit 3 must be set. Watch the corresponding WinCC message (RSE side) to confirm the cross-reference.
  4. Station loss test. Disconnect the PROFIBUS connector. OB 86 must fire and SlotHealthy[1..5] must all read FALSE. Restore the cable and confirm the array returns to TRUE within ~3 bus cycles (depends on DP timeout).
  5. RETVAL matrix. Force LADDR = 1000 (wrong address) and observe RETVAL = 16#8085 / 8091. Use this matrix to verify error handling.
RETVAL (hex) Cause Remedy
0000 OK, data in buffer —
7000 BUSY active, no result yet Wait, do not retrigger
8085 Address / length error Check LADDR matches HW Config diagnostic address
8086 Own station error CPU-side fault, check diagnostic buffer (SSL 0x00A0)
8091 Record not supported Slave not DP-V1; use identifier-only mode
80A3 Access to a non-existent module Slot address invalid
80B1 Length too short Increase destination area to 128 / 240 bytes
80C3 Resource bottleneck Increase cycle time of OB 35 to 200 ms

Troubleshooting Matrix

Symptom Likely cause Diagnostic step Fix
RSE shows error, no bit available Wizard only writes to WinCC Add SFC 13 call as above Build custom decoder
SlotHealthy[x] always FALSE SFC 13 destination buffer too small Inspect RETVAL Increase buffer to ≥ 128 B
SlotHealthy[0] always TRUE Slot 0 is IM 153-2; module status entry may not appear Use station_status_1/2 bytes (offset 0..5) Use station status, not slot array
RETVAL 8086 every cycle CPU in STOP, OB 35 not running Check CPU run state Restart CPU
Channel fault bit stuck TRUE after fix Diagnostic latch on module; needs acyclic write to clear Issue PN record 0x8028 / DP acyclic write to slot Send "acknowledge" record to the module
Intermittent FALSE on a known-good slot PROFIBUS interference or EM cable issue Check station diagnostics byte 0, bit 5 (diag flag) Repair shield / terminator
SlotHealthy for unused slot returns TRUE Decoder did not hit 0x80 terminator Walk decoder in VAT; verify terminator offset Force terminator detection

RSE vs SFC 13 / SFC 51 — Comparison

Aspect RSE (Report System Error) SFC 13 / SFC 51
Output target WinCC operator messages PLC data block (program-consumable)
Granularity Per slot, per channel (channel-level messages only) Per slot, per channel, per module-status-byte, per station-status-byte
Custom bit mapping No Yes (user-defined)
HMI requirement Mandatory for message routing Optional (can work headless)
Code consumption Indirect (via HMI tags) Direct (boolean array)
Implementation effort Low (wizard) Medium (custom FB)
Cyclic load on PROFIBUS Event-driven, low Cyclic if naively polled; rate-limit via OB 35
Standard compliance Siemens-specific PROFIBus DP-V1 standard diagnostic records

Best practice: use both. RSE for the operator layer (alarm logging, WinCC visibility, message acknowledgement), SFC 13 / SFC 51 for the control layer (interlocks, health gating, batch gating). They coexist without conflict because they consume different data sinks.

Wiring It Up in HW Config

  1. Open HW Config and select the DP slave (ET200M IM 153-2).
  2. Note the Diagnostic address from Properties → DP slave → Diagnostics. This is the LADDR used in SFC 13.
  3. Insert each SM card in its physical slot. The slot number reported by SFC 13 is the HW Config slot, not the logical address.
  4. For cards that support channel diagnostics (6ES7 331-7KF02-0AB0 etc.), enable "Channel diagnostics" in Properties → Inputs → Diagnostics. Without that checkbox the channel-level record is suppressed.
  5. Run RSE from Options → Report System Error to get the operator messages for free.

Safety Note

SFC 13 / SFC 51 read non-safety diagnostic data. For safety-relevant decisions on a SIL/PL application, the safety logic must rely on the safety protocol of the F-CPU / F-module (PROFIsafe or Safety Integrated) — not on SFC 13 / SFC 51. These blocks are for operational health monitoring, not for the safety path.

Field-Proven Tips

  • Rate-limit SFC 13 to a 100–200 ms cycle in OB 35. Polling faster loads the PROFIBUS without adding usable information.
  • Use a single shared DB_Diag instance across the entire program. Multiple SFC 13 calls to the same LADDR stack up as BUSY calls and slow the OB.
  • Trigger SFC 13 from inside OB 82 too, on the first interrupt after startup, to get an immediate diagnostic refresh rather than waiting one OB 35 period.
  • For SFC 51 SSL_ID 0x0092 with INDEX 0, the function returns the full station list — useful for the "whole station alive" boolean. Use INDEX 1..n for a specific rack/slot.
  • Log diagnostic buffer transitions (FALSE → TRUE, healthy → faulty) to a circular log DB so post-trip analysis shows what failed first.

FAQ

Why does RSE not give me a per-card health flag in the PLC program?

RSE writes standardized diagnostic messages to WinCC and does not expose a program-consumable boolean per card. For code-side health flags, read the PROFIBUS DP slave diagnostic frame with SFC 13 "DP_DIAG" and decode the per-slot module status byte (16#20 = OK, 16#30 = faulty, 16#40 = missing).

Can I use SFC 13 on a PROFINET station instead of PROFIBUS?

Yes. SFC 13 still applies at the CPU interface for the slave diagnostic, but on PROFINET the equivalent per-card decoding uses the slot-level channel diagnostic read via PN record index 0x800A. The decode pattern (walk records, mask the per-slot status) is identical.

What is the minimum destination buffer size for SFC 13?

Allocate at least 128 bytes; 240 bytes is recommended to cover a full ET200M with channel-level diagnostics on every slot. An SFC 13 RETVAL of 80B1 ("length error") almost always means the buffer is too short.

Where do I find the LADDR (diagnostic address) for SFC 13?

Open HW Config, click the ET200M IM 153-2 station, open Properties → DP slave → Diagnostics. The address shown there is the value to use as LADDR in W#16# notation. It is independent of the I/O addresses of the cards behind it.

Do SFC 13 and RSE conflict if both are active?

No. RSE consumes OB 82/83/86 events for WinCC rendering; SFC 13 reads the standard DP slave diagnostic record directly from the bus. Both can be active simultaneously. The recommended approach is to use RSE for the operator layer and SFC 13/SFC 51 for the control layer.

How do I detect a single channel fault on an SM 331 (6ES7 331-7KF02-0AB0)?

Enable channel diagnostics in HW Config on the card. After SFC 13 reads the buffer, decode the channel-related diagnostic records that follow the module status block. The first word of each record is the per-channel fault vector (one bit per channel), giving a channel-by-channel health mask usable in the application.

Back to blog