Problem Overview
A Siemens CPU 319-3 PN/DP (6ES7318-3EL01-0AB0 and related variants in the S7-300 family) unexpectedly transitions from RUN to STOP immediately after a STEP 7 / TIA Portal download completes. The SF (Group Fault) LED illuminates, the RUN LED extinguishes, and the STOP LED turns on. The diagnostic buffer contains two linked entries generated by the CPU operating system:
- Event ID 16#4562 — STOP durch Programmierfehler (OB nicht geladen oder nicht möglich, bzw. kein FRB vorhanden)
- Event ID 16#2522 — Bereichslängenfehler beim Lesen, Instanz-DB, Bitzugriff, Zugriffsadresse: 0
The Event ID 16#2522 is the actual programming fault (area-length error on a bit access to byte/bit address 0 inside an instance DB). Event ID 16#4562 is the consequence: the CPU attempted to call OB 121 to report the fault, found it absent, and dropped to STOP. OB 121 is not the cause of the failure — it is the diagnostic vehicle the operating system uses to announce the failure. Treat the symptom (missing OB) and the cause (the underlying programming error) as two separate work items.
Diagnostic Buffer Decoding
Open the CPU diagnostic buffer in STEP 7 V5.x via PLC → Diagnostic/Setting → Diagnostic Buffer, or in TIA Portal via Online & diagnostics → Diagnostics buffer. Translate the two leading events:
| Field | Event 10 — 16#4562 | Event 11 — 16#2522 |
|---|---|---|
| Meaning (EN) | STOP due to programming error (required OB not loaded / not possible / no FRB available) | Area-length error on read, instance DB, bit access, address 0 |
| FB number | 876 | 876 |
| Block address | 2750 (relative MC7 code offset) | 2750 |
| Previous operating state | RUN | — |
| Requested operating state | STOP (internal) | — |
| Requested OB | — | OB 121 (Programming Error OB) |
| Trigger timestamp | 16:10:32.898 30.09.2010 | 16:10:32.895 30.09.2010 |
The two events are 3 ms apart and share the same FB 876 reference and the same block address 2750. The 3 ms delta reflects OB-call resolution time inside the scan. Event 11 (16#2522) is generated first; Event 10 (16#4562) follows because OB 121 is missing on the target CPU and the operating system escalates to STOP.
Technical Background: OB 121 and the S7 Error OB Family
The S7-300/400 operating system reserves a numbered set of error OBs that the CPU calls automatically when a synchronous fault is detected. Each OB is the user’s chance to react to a specific class of error and keep the CPU in RUN. The two OBs most often confused by maintenance engineers are:
| OB | Name | Triggered by |
|---|---|---|
| OB 121 | Programming Error OB | Accessing a non-existent bit/byte/word/DWord, illegal type conversion, BCD error, range error on system functions |
| OB 122 | I/O Access Error OB | Direct I/O access to a missing or faulty module, or accessing I/O area outside the process image |
Per the official Siemens TIA Portal reference Programming error organization block (OB 121) (S7-300, S7-400): “The CPU operating system calls OB 121 whenever an event occurs that is caused by an error related to the processing of the program.” If OB 121 is not loaded in the CPU, the operating system cannot hand control to user code, and the CPU transitions to STOP on the first programming error encountered in the scan cycle. This is the documented and expected behavior — it is not a hardware defect.
The same documentation states: “If OB 121 is not programmed, the CPU changes the operating mode from RUN to STOP.” S7 also provides SFC 36 / SFC 37 (MSK_FLT / UNK_FLT) so that user code can mask (suppress) specific error events from triggering OB 121 at all — a useful technique for legacy code segments that intentionally probe hardware states.
Root Cause Analysis
Event ID 16#2522 carries the structural information needed to localize the bug. The three fields that matter are:
-
Object class — Instanz-DB: The faulting access is to an instance data block, not a shared (global) DB. Instance DBs are generated automatically by the compiler and mirror the
VAR,VAR_TEMP, andVAR_IN_OUTdeclarations of the parent FB. -
Access type — Bitzugriff: A bit-level (
A,AN,O,ON,S,R,=,X) read or write is being executed. -
Access address — 0: The address decoded is byte 0, bit 0 of the instance DB. In an S7 instance DB, address 0 is the first bit of the first
VAR_INPUTorVARelement declared in the FB header.
Address 0 in an instance DB is normally a valid location — it is the LSB of the first static or input variable. The fact that the CPU raises a range-length error on it means that the actual instance DB currently loaded on the CPU is shorter than the FB 876 code expects. The most common cause: the FB 876 interface (the VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, or VAR block) has been edited — for example, a new variable was inserted at the top of the declaration table, or an existing variable was renamed and the offset shifted — while the corresponding instance DB was not regenerated. The compiler assigns new offsets during the build, but the runtime still holds the old, smaller DB image downloaded earlier.
Secondary causes that produce identical diagnostics include:
- A multi-instance call (
FB 876instantiated as a static variable inside another FB) where the parent FB’sVARsection was modified but the parent’s instance DB was not recompiled. - An
ANY-pointer orVARIANTinput pointing at an instance DB that has been deleted and recreated with a different number, leaving a stale reference in FB 876. - A hand-edited DB layout (manual data view editing) that changed the offset of an existing BOOL element, but the FB source code in the project was not updated.
- Cross-project copy/paste that re-numbered the FB (876 in this case) and the instance DB inconsistently.
Why the Temporary OB 121 Workaround Works
Loading a blank OB 121 shell into the CPU changes the operating-system reaction: when 16#2522 fires, the OS calls OB 121, executes an empty body, returns to the scan, and the CPU stays in RUN. The fault still happens on every cycle — only the system reaction is suppressed. This explains the three observable behaviors in the field:
- The CPU stays in RUN after OB 121 is installed.
- Output behavior of the affected machine is unpredictable, because the bit access at address 0 returns
FALSEand any downstream logic depending on that bit is wrong. - Removing the OB 121 shell — or downloading a new program without it — re-introduces the STOP, which is why the workaround feels like it has to be repeated every download.
Step-by-Step Permanent Resolution
Prerequisites
- STEP 7 V5.5 + SP4 / HF7 or TIA Portal V16 or later with the CPU 319 GSD/ HSP installed.
- The current offline project (must match the FB 876 source already in the online CPU).
- Read/write access to the CPU (PG/PC interface, online connection).
- Backup of the CPU program (PG → Upload station to PG) before making changes.
Procedure (STEP 7 V5.x)
- Upload the current program from the CPU: PLC → Upload Station to PG (Software). This guarantees the offline and online versions of FB 876 are reconciled.
- Open FB 876 in the SIMATIC Manager → S7 Program → Blocks. Right-click the block and select Object Properties → General Part 2 to confirm the FB number and the timestamp.
-
Open the interface of FB 876. Record the order and data types of every
VAR_INPUT,VAR_OUTPUT,VAR_IN_OUT, andVARelement. Compare the order with the version stored in the CPU (right-click the online block → Compare). - Locate the instance DB called by FB 876. From the call tree (Options → Reference Data → Program Structure) find the instance DB number. Double-click it.
- Recompile the instance DB: right-click the instance DB → Generate Instance DB. The compiler writes a fresh image whose length and offsets match the current FB 876 interface.
- For a multi-instance call, recompile the parent FB’s instance DB the same way. Confirm the parent FB’s static section still references FB 876 at the correct relative offset.
- Build a fresh OB 121 from the standard library (Libraries → Standard Library → System Function Blocks) and add it to the S7 program. Use SFC 6 / SFC 13 / SFC 17 inside OB 121 to write the fault information into a status DB so the fault is not silently swallowed.
- Compile and download the full Blocks container to the CPU. The CPU stays in RUN.
- Reset diagnostic buffer and run the machine for at least one full production cycle. Confirm no new 16#2522 entries appear.
Procedure (TIA Portal V16+)
- Online → Upload from device (software) to bring the live CPU program into the TIA project.
- Open Project tree → PLC_1 → Program blocks → FB [876].
- From Tools → Call structure, identify the instance DB for FB 876.
- Right-click the instance DB → Compile → Software (rebuild all blocks). TIA regenerates the instance DB from the current FB interface.
- Add OB 121 from Add new block → Organization block → OB 121 (Programming error). Optionally call
WR_USMSG(SFC 17) inside OB 121 to log the fault via the diagnostic buffer of any HMI that subscribes to the PLC diagnostics. - Download the entire program to the CPU. Use Consistent download if the project setting allows it.
Sample OB 121 Skeleton (SCL)
// OB121 - Programming Error Handler
// Reads the OB121 start info and writes a compact entry to DB9000
// so maintenance staff see one line per fault, not a 192-event buffer.
VAR_TEMP
info : OB121_ERROR_BITS;
blk : WORD; // Block number from OB121 header (local)
ofs : WORD; // Block-relative offset (local)
ret : INT; // Return code from WR_USMSG
END_VAR
IF "Diag".Enable = TRUE THEN
info := OB121_ERROR_INFO;
blk := info.BLKNR;
ofs := info.BLKOFFSET;
"Diag".LastFaultFB := blk;
"Diag".LastFaultOffset := ofs;
"Diag".LastFaultCode := info.FLT_ID;
"Diag".LastFaultTime := RTM_TOD(0); // current TOD
ret := WR_USMSG(MSG_ID := 1001, EVENT := info.FLT_ID);
END_IF;
The exact field names of OB121_ERROR_INFO and OB121_ERROR_BITS depend on the TIA / STEP 7 version. In STEP 7 V5.5 the local tags are OB121_EV_CLASS, OB121_FLT_ID, OB121_PRIORITY, OB121_OB_NUMBR, OB121_BLK_TYPE, OB121_BLK_NUMBR, OB121_BLK_OFFSET, and OB121_FLT_REG. Reference the official OB 121 documentation for the complete local-data layout.
Instance DB Reconciliation Deep-Dive
When FB 876’s interface has been changed, three artifacts must move in lockstep: the FB source, the instance DB image, and any background DB that the FB touches via UDT. A reliable reconciliation procedure is:
- Compare online vs. offline on FB 876 first. The Block comparison tool in STEP 7 V5.x (or Compare → Online/offline in TIA) will surface interface drift.
- Delete the instance DB from the offline project.
- Compile all blocks in the S7 program. The compiler regenerates the missing instance DB from the current FB.
-
Cross-check every call site of FB 876 in the program structure. If any caller passes an
ANYparameter that points at the instance DB, verify the pointer’s DB number still matches. - Download and clear the diagnostic buffer.
Verification and Testing
After the recompile and download, perform the following verification sequence before returning the machine to production:
- Diagnostic buffer must be clean. After one hour of operation, no entries with IDs in the 16#25xx or 16#45xx ranges should appear. Tolerate no more than one 16#4562 entry on the first scan after download (this is the historical fault already cleared).
- Watchdog test. Force the original error back into the program (e.g. temporarily add a bit-access to address 0 of a short DB) and confirm that OB 121 fires, the status DB updates, and the CPU stays in RUN. This proves the OB 121 path is functional, not just present.
- Cold restart test. Perform a complete restart (MRES) to ensure the new blocks are persisted to flash and survive a power cycle.
- Compare reference data. Regenerate the program structure, cross-reference, and assignment lists. Save them under version control. This becomes the baseline for the next engineering change.
Troubleshooting Matrix
| Symptom | Diagnostic ID | Likely cause | Action |
|---|---|---|---|
| CPU goes to STOP on first scan after download | 16#4562 / 16#2522 | Missing OB 121 + area-length error in instance DB | Install OB 121, recompile the instance DB |
| CPU stays in RUN but outputs toggle randomly | 16#2522 in diagnostic buffer, no STOP | OB 121 installed but instance DB still wrong; bit read returns 0 | Recompile instance DB, do not rely on OB 121 suppression |
| STOP immediately after PG stop/cancel | 16#4562 only | Last download did not include OB 121 | Add OB 121 to the project, not only to the online folder |
| STOP with block address in the 3000–4000 range | 16#4562 / 16#25xx | Multi-instance FB where parent instance DB is out of date | Recompile parent FB’s instance DB |
| STOP with FLT_REG nonzero | 16#2522 + FLT_REG = DB number | Access to a deleted or re-numbered DB | Recreate the referenced DB or fix the ANY pointer |
| STOP on FBs that are not in the project | 16#4562 + FB number 0 | Compiler generated a stub and the system has no call target | Rebuild all blocks from source |
Preventive Engineering Practices
- Always ship OB 121 (and ideally OB 122) with every S7-300/400 program. Treat them as mandatory system blocks, not optional ones. Even a no-op OB 121 is better than a missing one.
- Add a permanent status DB updated by OB 121/122. Maintenance crews reading the HMI diagnostic page can identify the FB and offset of the last programming error without connecting a programmer.
- Version-control the S7 project at the source level (TIA Portal multi-language or STEP 7 V5.x source files exported via Source files). This is the only way to detect FB-interface drift between two stations that should have identical code.
- Use UDTs for any structured instance data that more than one FB shares. A UDT change regenerates every dependent DB automatically.
- Reserve OB 80, OB 85, OB 86, OB 87, OB 121, OB 122 from the start. A CPU with all error OBs installed will degrade gracefully through nearly every common fault class (time error, module failure, rack failure, communication failure, programming error, I/O error) without dropping to STOP.
- Run a periodic diagnostic-buffer sweep. A small script that logs the buffer to a CSV file once per shift catches latent 16#25xx events that OB 121 is silently absorbing.
FAQ
Does installing OB 121 fix a CPU 319 STOP fault?
No. OB 121 only changes the operating-system reaction to programming errors. If the CPU drops to STOP with Event ID 16#4562, installing OB 121 keeps the CPU in RUN, but the underlying bit-access fault at address 0 of the instance DB is still present and must be corrected by recompiling the affected FB’s instance DB.
Why does Event ID 16#2522 point at address 0 of an instance DB?
Address 0 in an instance DB is the first bit of the first declared variable. An area-length error on address 0 means the instance DB loaded on the CPU is shorter than the FB expects, almost always because the FB interface was edited and the instance DB was not regenerated.
What is the difference between OB 121 and OB 122?
OB 121 handles programming errors (bad access to a DB, type conversion errors, BCD errors, range errors on system functions). OB 122 handles I/O access errors when a direct read or write targets a missing, faulty, or powered-down module. Both should be installed in any production S7-300/400 program.
How do I permanently add OB 121 to my STEP 7 project so I do not have to copy it after every download?
Open the offline S7 program in SIMATIC Manager or TIA Portal, right-click the Blocks container, choose Insert New Object → Organization Block, and select OB 121. Compile the project and download the full Blocks container. From that point on, OB 121 is part of every download.
Can I mask specific programming errors so OB 121 is never called?
Yes. SFC 36 MSK_FLT masks synchronous errors of a specific class so the operating system no longer triggers OB 121 for them, and SFC 37 UNK_FLT unmasks them. Use masking sparingly: it is appropriate for legacy probe code that intentionally inspects module presence, not for hiding real bugs in production logic.