Configuring OB122 and PROFINET Diagnostics in TIA Portal

David Krause14 min read
SiemensTIA PortalTutorial / 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

Configuring OB122 and PROFINET Diagnostics in TIA Portal

OB122 is the I/O Access Error Organization Block in SIMATIC S7-1200 and S7-1500 controllers. The CPU operating system calls OB122 when an instruction in the user program attempts to read or write I/O data and the access fails. A common field symptom is a CPU fault at startup or during a running process when a distributed PROFINET device becomes unreachable, returns bad data, or has a hardware address conflict. Configuring OB122 correctly lets the controller react to the fault instead of stopping, and lets the engineer identify exactly which slot or device caused the error.

This reference clarifies what OB122 does, what it does not do, and how to pair it with the Diagnostics Error OB (OB82), the DeviceStates instruction, and RALRM to build a complete PROFINET fault reaction in TIA Portal V16 or later. The examples target an S7-1516-3 PN/DP CPU with firmware V2.9 running on a PROFINET IO line, but the same block semantics apply to the S7-1200 family (firmware V4.4 or later) and the ET 200SP / ET 200MP distributed I/O.

Important boundary. OB122 fires on direct I/O access errors (PQB, PIB, PII, PIW, IDB, IDW, and the S7-1500 slice accesses %IW0:P). It does not fire when the PROFINET cable is unplugged and no I/O is being accessed in the current OB cycle. For a missing PROFINET device you need the Diagnostics Error OB (OB82) and the DeviceStates instruction. The two OBs complement each other; configure both.

1. Prerequisites

  • SIMATIC S7-1200 (FW 4.4+) or S7-1500 (FW 2.0+); S7-1500 recommended for full PROFINET diagnostics surface.
  • TIA Portal V16, V17, or V18. The DeviceStates instruction was introduced with V14; RALRM is available from V13 SP1.
  • Configured PROFINET IO network in the Devices & Networks editor with at least one IO device assigned to the CPU's PROFINET interface.
  • System constants enabled (Options > Settings > PLC programming > General > Generate system constants).
  • OB122 must be created and downloaded; the CPU will otherwise go to STOP with diagnostic buffer entry "OB122 not programmed".

2. OB122 Temporary Interface

OB122 carries the following Temp variables that describe the failed access. They are read-only and valid only inside the OB.

Tag Type Description
OB122_EV_CLASS BYTE Event class: 0x39 = error event with acknowledgement
OB122_SW_FLT BYTE Software fault code (e.g., 0x01 read, 0x02 write)
OB122_FLT_REG WORD Source/destination address of the failed access
OB122_8x WORD Block number in which the error occurred
OB122_MEM_ADDR WORD Memory address of the instruction that triggered the error
OB122_BLK_TYPE BYTE Block type (OB/FB/FC/DB)
OB122_PRIORITY BYTE Priority class of the OB in which the access was attempted
OB122_IO_NUMBER WORD Number of the I/O area (input or output) that failed
OB122_BLK_NUM WORD Block number
OB122_PRG_ADDR WORD Logical address (slot/I/O offset) that returned an error
OB122_DATE_TIME DATE_AND_TIME Time stamp of the error event

The OB122_PRG_ADDR is the value to compare against the device's start address in the device view. The OB122_FLT_REG is the peripheral address (P-address) of the failed access in the linear I/O image.

3. OB82 vs. OB122: Selecting the Right OB

Engineers often confuse the two error OBs. Use the table below as a decision matrix.

Condition Triggers OB82 (Diagnostic Error) Triggers OB122 (I/O Access Error)
PROFINET device pulled from network, no read in progress Yes No
PROFINET device pulled, user program reads PIW in OB1 Yes Yes
Channel diagnostics (wire break, short circuit, overtemperature) on a smart module Yes No
Direct peripheral access to a slot that is not configured No Yes
Substitute value behavior triggered No Yes (subsequent read returns 0)
Module removed under power (SM in central rack) Yes Only if accessed in same cycle
Substitute value behavior. For an S7-1500 you can configure the IO device's substitute value behavior in the device properties under "IO cycle / substitute values". With substitute values enabled, the CPU does not call OB122 on a missing device; it returns zeros (or the configured substitute). Disable substitute values during commissioning to force OB82 + OB122 to surface the fault.

4. System Constants and Hardware IDs

System constants in TIA Portal expose the compile-time hardware identifiers of every PROFINET device, module, submodule, and interface. They are essential for fault identification in OBs because the I/O error does not carry the device's PROFINET name, only its logical I/O addresses.

To view them, open the PLC's PLC tags table and switch the view to System constants. Typical constants generated for an ET 200SP station named IO_Device_1 include:

  • IO_Device_1 — HW identifier of the IO device head module
  • IO_Device_1~HeadModule — HW identifier of the head module itself
  • IO_Device_1~Slot_1 — HW identifier of slot 1 (first I/O module)
  • IO_Device_1~Slot_1_Channel_0 — HW identifier of a single channel for granular diagnostics

Pass these constants to RALRM, DeviceStates, and GET_DIAG. The HW identifier is a DINT; do not use the device number from the configuration tree, which is a project-local index and can change when you add or remove devices.

5. The DeviceStates Instruction

DeviceStates reports the operational state of every PROFINET device or every module/submodule of a given IO device. It is the only standardized way to enumerate which distributed device is currently Faulted, Disabled, or Not accessible.

5.1 Interface

// SCL signature
{ S7_tech := 'always' }
#RET_VAL  : DINT;          // 0 = OK; non-zero = error code (e.g. 0x80B1, 0x80B3)
#MODE     : UINT;          // 1 = summary, 2 = devices, 3 = modules, 4 = submodules
#LADDR    : HW_IO;         // HW identifier of the IO system or device (0 = local CPU master system)
#DEST     : ARRAY[*] OF BOOL; // receives one BOOL per index, packed

5.2 MODE values and meaning

MODE Scope DEST interpretation
1 PROFINET IO system summary Index 0 = number of available devices; Index 1 = number of faulted devices; Index 2 = number of disabled devices; Index 3 = number of not-accessible devices
2 IO device states One BOOL per device; TRUE = available, FALSE = not available. Index 0 reserved.
3 Modules of a specific IO device One BOOL per module of the addressed device
4 Submodules of a specific module One BOOL per submodule

5.3 Practical SCL example

The following FB reads the device summary once per PROFINET update cycle and stores counts in a global DB for the HMI to display. Drop it into OB1 or, preferably, into a cyclic interrupt OB (OB30 to OB38) at 100 ms.

FUNCTION_BLOCK "FB_DeviceStateMonitor"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR
    aAvailable   : ARRAY[0..15] OF BOOL;   // Mode 2 results
    aModules     : ARRAY[0..31] OF BOOL;   // Mode 3 results for one device
    iRet         : DINT;
    iFaultedCnt  : INT;
    iAvailCnt    : INT;
END_VAR
BEGIN
    // ---- Step 1: System summary (MODE = 1) ----
    iRet := DeviceStates(
        MODE  := 1,
        LADDR := 0,                    // Local PROFINET system on the CPU
        DEST  := aAvailable);          // Indices 0..3 = summary counts

    IF iRet <> 0 THEN
        #iFaultedCnt := -1;            // Negative marker for "instruction failed"
        RETURN;
    END_IF;

    // ---- Step 2: Per-device availability (MODE = 2) ----
    iRet := DeviceStates(
        MODE  := 2,
        LADDR := 0,
        DEST  := aAvailable);

    // Count TRUE entries using SUM/loop; SCL example uses a small loop
    iAvailCnt   := 0;
    iFaultedCnt := 0;
    FOR #i := 1 TO 15 DO
        IF aAvailable[i] THEN
            iAvailCnt   := iAvailCnt + 1;
        ELSE
            iFaultedCnt := iFaultedCnt + 1;
        END_IF;
    END_FOR;

    // ---- Step 3: Module-level granularity for a known device ----
    iRet := DeviceStates(
        MODE  := 3,
        LADDR := "IO_Device_1",         // System constant from device view
        DEST  := aModules);
END_FUNCTION_BLOCK
Array sizing. The DEST array must be large enough to hold the largest possible response, otherwise the instruction returns 0x80B3 (insufficient destination size). For a 16-device PROFINET line, declare at least 17 elements for MODE = 2 (index 0 is reserved). Always check the RET_VAL before consuming the array.

6. The RALRM Instruction for Detailed Alarms

RALRM (Read Alarm) returns the full diagnostic record of the IO device that just raised the alarm that brought the CPU into OB82. It is the diagnostic equivalent of "drill down to the channel". The instruction reads the call environment of OB82 (OB82_MDL_ADDR, OB82_IO_FLAG, OB82_RACK_NUMBER) and writes a structured TINFO / AINFO response.

6.1 Typical error codes in RET_VAL

RET_VAL (hex) Meaning
0x0000 Alarm was read successfully
0x80A1 OB82 start information is wrong (TINFO/AINFO length)
0x80A2 OB82 was not called by a PROFINET IO device
0x80A3 No alarm pending at the time of the call
0x80C0 Internal error in the firmware

6.2 SCL skeleton

iRet := RALRM(
    OB             := 82,              // Must be 82 for diagnostics OB
    HW_ID          := 0,               // Local system
    LADDR          := OB82_MDL_ADDR,   // From OB82 temp area
    IO_FLAG        := OB82_IO_FLAG,    // 0=input, 1=output
    TINFO          := aTInfo,          // ARRAY[*] OF BYTE, >= 32 bytes
    AINFO          := aAInfo,          // ARRAY[*] OF BYTE, >= 34 bytes (extended)
    NEW_PTR        := bNewAlarm);

The first two bytes of AINFO hold the channel number; bytes 4..5 hold the channel error type; the remaining bytes carry the vendor-specific diagnostic payload for PROFINET. Decode bytes 6+ using the device's GSD file or the TIA Portal "Online & Diagnostics" view to map the raw bytes back to the engineering-friendly text.

7. Step-by-Step: Configuring OB122 in TIA Portal V18

  1. In the project tree, expand Program blocks on the CPU, double-click Add new block, and select Organization block > OB122 (I/O access error). Confirm the priority (default 7, the same as OB1; lower than the OB1 priority will cause the error OB to interrupt cyclic execution).
  2. Open the new OB122 and add a single line of logic to set a global flag, for example:
    SET on a coil named "IO_Fault_Latched". The point is not to write the recovery logic here, but to be able to observe the OB firing in the watch table.
  3. Compile and download to the CPU. To prove OB122 is wired, temporarily add a peripheral read of a non-existent slot:
    L PIW 1000 — if slot 1000 is unused, the CPU will call OB122 immediately on the next scan.
  4. Add OB82 the same way (Organization block > OB82, priority 26 by default). In OB82, call DeviceStates with MODE = 1 to latch the fault count and call RALRM to capture the channel-level error.
  5. In the IO device properties (Device view > properties > "IO cycle / substitute values"), set substitute value behavior to No substitution during commissioning. This guarantees the CPU will call OB82 and OB122 when the device disappears rather than silently replacing values.
  6. For the diagnostic interrupt in OB82, ensure the module is configured to issue a channel diagnostic. For an ET 200SP digital input module, enable "Diagnostic > Wire break" and "Diagnostic > Short circuit" in the module parameters.
  7. Compile hardware (HW) and software (SW), download both to the CPU, and go online.

8. Verification

Use the following checks to confirm the configuration is operational.

  1. Watch table test: with OB122 downloaded, force a fault by unplugging the PROFINET cable of any device whose process data is read every cycle. The watch table bit "IO_Fault_Latched" should rise to TRUE within one OB82 cycle (default 1 ms for PROFINET update time on a 1 ms line). IO_Diag_Count should increment by 1.
  2. Diagnostic buffer: in Online & Diagnostics > Diagnostic buffer, look for entries of type "Diagnostic interrupt from PROFINET IO" with the device's PROFINET name and slot number. If only "I/O access error" entries appear, OB82 is not being called; if only "Diagnostic interrupt" entries appear, OB122 is not configured.
  3. LEDs: the CPU's BF (Bus Fault) LED will stay lit on the affected port; the SF (System Fault) LED lights if the device is not substituted and the user program is reading it. Both clear automatically when the device returns.
  4. PROFINET trace: in the TIA Portal "Online & Diagnostics" of the IO device, start the Trace for "Port statistics" to see CRC errors, link-down events, and discarded frames. Useful for catching intermittent cabling faults that never produce a full OB122 call.

9. Troubleshooting Matrix

Symptom Likely cause Fix
CPU goes to STOP, diagnostic buffer "OB122 not programmed" OB122 was not downloaded, or project was compiled without it Add OB122 explicitly, compile, full download (not delta)
CPU stays in RUN when PROFINET device is unplugged, OB122 not called Substitute value behavior is active; program does not read the slot Disable substitute values; force a read of the affected PIW in OB1
OB122 called, but OB122_PRG_ADDR = 0 Failed access was to the bit memory or DB, not to peripherals Verify the I/O tag is a P (peripheral) address and not %M
DeviceStates RET_VAL = 0x80B3 Destination array too small Increase DEST to at least number of devices + 1
RALRM RET_VAL = 0x80A2 OB82 not called by a PROFINET IO source (called by a CPU itself) Confirm OB82 is generated and the IO device is assigned to the CPU, not just visible in the topology
OB122 fires cyclically, hundreds of times per second Faulted read in OB1; no substitute Read a different slot, or wrap the access with a DeviceStates gate
OB82 fires for a device that is fully wired and healthy GSD mismatch between TIA project and actual device revision Update GSD, recompile hardware, replace device & diagnostics view

10. Pattern: Gate the Access with DeviceStates

A robust pattern is to read DeviceStates first and only access the peripheral when the device is reported available. This avoids flooding the diagnostic buffer and keeps OB122 from monopolising CPU time.

// SCL inside a cyclic interrupt OB
IF aAvailable[1] THEN           // Device index 1 = first device on the line
    "ProcessData_DB".Input1 := "IO_Device_1".Channel0.Input;
ELSE
    "ProcessData_DB".Input1 := 0;   // explicit safe default
    "IO_Fault_Latched" := TRUE;
END_IF;

This pattern eliminates nearly all OB122 events on a healthy plant. OB122 becomes the exception handler for the unexpected fault, not the normal path.

11. Alternate Platforms and Compatibility Notes

The same OB semantics exist in the older STEP 7 V5.x environment, but the way the diagnostic OB is named differs: in STEP 7 V5.5, OB82 was called "Diagnostic Interrupt" and used OB82_FLT_ID (BYTE) with values 0x01..0x08 for the standard diagnostic types. When porting a STEP 7 V5 project to TIA Portal, do not assume the tags map 1:1. The OB82_xx tag names in TIA Portal correspond to a slightly different default mapping; the values 0x01..0x08 are preserved, but additional PROFINET-specific codes (0x0A, 0x0B) are now possible.

For an S7-1200 CPU (FW 4.4+), DeviceStates and RALRM are available, but the array size limits and the maximum number of IO devices (8 to 16 depending on CPU model) are smaller than for an S7-1500. Refer to the CPU's manual "Maximum number of IO devices / IO modules" table before sizing the destination array.

Safety note. OBs 82 and 122 are non-failsafe and must not be used as the primary safety response for a PROFIsafe device. PROFIsafe is handled by F-CPU runtime; safety diagnostics live in the F-runtime container and are read with RD_SINFO for safety diagnostics, not RALRM.

12. Field-Commissioning Checklist

  • OB122 generated, downloaded, contains at least one observable side effect (e.g., set a global flag).
  • OB82 generated, contains DeviceStates + RALRM call.
  • System constants enabled in PLC settings.
  • Substitute value behavior = "No substitution" during commissioning.
  • Each IO device has a unique PROFINET device name and a unique IP address.
  • Watch table created with the latched fault bits, a counter, and the DeviceStates mode-1 summary.
  • Diagnostic buffer cleared after each test so new entries are easy to find.
  • PROFINET update time set to 1 ms (or the same as the fastest device requires); mismatch causes sporadic OB82 events that are not real faults.

What is the difference between OB122 and OB82 on a Siemens S7-1500?

OB122 fires on a direct I/O access error while user code is running (e.g., reading PIW of a missing slot). OB82 fires on a diagnostic interrupt from the IO device, which happens when a PROFINET station goes offline or a channel diagnostic (wire break, short circuit, over-temperature) is reported. You should configure both, because OB122 by itself will not fire when a device is unplugged if no I/O is being read in that cycle.

How do I identify which PROFINET device triggered OB82 in TIA Portal?

Inside OB82, copy OB82_MDL_ADDR into LADDR of the RALRM instruction, then call DeviceStates with MODE = 2 and LADDR = 0 to enumerate every device on the local PROFINET system. Cross-reference the failing device by its hardware identifier (system constant) generated by TIA Portal. The PROFINET device name and slot number appear in the diagnostic buffer and in the first bytes of the AINFO payload.

Why does OB122 not fire when the PROFINET cable is unplugged?

OB122 only fires when the user program attempts an I/O access that fails. If the cyclic program never reads the affected slot, the CPU has no instruction to fail on, so the missing device only generates an OB82 diagnostic interrupt. Add a periodic read of the device or enable substitute-value-off mode to force OB122 to also fire on a missing device.

Which TIA Portal version introduced DeviceStates and RALRM?

DeviceStates is available from TIA Portal V14 onwards for S7-1200 V4.2 and S7-1500 V2.0 CPUs. RALRM has been available since STEP 7 V11 / TIA Portal V13 SP1. For best results with the largest destination array and the latest GSD support, use TIA Portal V17 or V18 with the matching CPU firmware.

How can I tell the difference between an OB122 fault and a real program bug?

Check the diagnostic buffer first: an OB122 event is logged as "I/O access error" with the failing peripheral address. The same buffer shows the program counter and the block number. If the address is inside a configured I/O area and the device is missing, it is a real field fault. If the address is 0 or points to the bit-memory or DB area, the program itself is using the wrong address. The OB122_BLK_TYPE and OB122_BLK_NUM tags identify the offending block so you can navigate straight to it from the buffer entry.

Back to blog