Siemens SIMATIC Block Types Explained: OB, FB, FC, DB Reference

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

Siemens SIMATIC Block Types Explained: OB, FB, FC, DB Reference

SIMATIC S7 Block Architecture Overview

Siemens SIMATIC S7 controllers (S7-300, S7-400, S7-1200, S7-1500) execute STEP 7 programs that are partitioned into discrete code and data blocks. The four primary block types — Organization Blocks (OB), Function Blocks (FB), Functions (FC), and Data Blocks (DB) — form a layered execution model. OBs define the runtime schedule, FBs and FCs encapsulate reusable logic, and DBs store structured data. Selecting the correct block type is the single largest factor in code maintainability, memory consumption, and reusability across an automation project.

The block model is defined in the STEP 7 (TIA Portal) and STEP 7 V5.x programming documentation. See the SIMATIC S7-1200 manual collection – Function Block (FB) for the canonical reference on FB behavior, the SIMATIC S7-1200 Manual – Block Programming Concepts for the surrounding programming model, and the Siemens Industry Online Support portal for the full set of S7-1200 and S7-1500 system manuals, application examples, and firmware release notes.

Every block in the S7 program has three fixed parts:

  1. Block header — block number, author, timestamp, version, family (FB, FC, OB, DB, type/version, array DB).
  2. Interface (parameter interface for FBs/FCs/OB code; data declaration for DBs) — declared variables in the standard sections Input, Output, InOut, Static, Temp, Constant, and Return.
  3. Code (or data) body — the executable code in LAD, FBD, SCL, GRAPH, or STL; or the structured data layout in a DB.

The interface section is the most important contract between a block and its callers. The compiler checks that all calls provide declared input parameters and consume declared output parameters, and that the caller's variable types match the block's signature.

Organization Blocks (OB)

Organization Blocks are the interface between the CPU operating system and the user program. Each OB type is triggered by a specific event: cyclic execution, time-of-day, hardware interrupt, diagnostic interrupt, error, or startup. The CPU firmware dispatches the matching OB and the user code inside it runs to completion (or until interrupted by a higher-priority OB).

The main cyclic OB is OB1. On S7-1200 CPUs, OB1 runs at the lowest user priority (priority 1 by default). On S7-1500 CPUs, OB1 has priority class 26. The scan cycle reads the process image, executes OB1, then writes the process image to the outputs. The minimum cycle time and maximum cycle time (watchdog) are configured in the PLC properties under "Cycle" in TIA Portal.

OB Type Reference

OB Trigger event Priority (S7-1500) Available on
OB1 Cyclic main 26 S7-300/400/1200/1500
OB10–OB17 Time-of-day 2 S7-300/400/1200/1500
OB20–OB23 Time-delay (SFC 32) 3–6 S7-300/400/1200/1500
OB30–OB38 Cyclic interrupt 7–15 S7-300/400/1200/1500
OB40–OB47 Hardware interrupt 16–23 S7-300/400/1200/1500
OB55 Status interrupt 2 S7-1500
OB56 Update interrupt 2 S7-1500
OB57 Profile interrupt 2 S7-1500
OB60 Multicomputing interrupt 25 S7-400
OB80 Time error 26 (fault) S7-300/400/1200/1500
OB81 Power supply error 26 (fault) S7-300/400/1200/1500
OB82 Diagnostic interrupt 26 (fault) S7-300/400/1200/1500
OB83 Module pull/plug 26 (fault) S7-300/400/1200/1500
OB84 CPU hardware fault 26 (fault) S7-1500
OB85 Program execution error 26 (fault) S7-300/400/1200/1500
OB86 Rack/station failure 26 (fault) S7-300/400/1200/1500
OB87 Communication error 26 (fault) S7-1500
OB100 Warm restart 27 S7-300/400/1200/1500
OB101 Hot restart 27 S7-400
OB102 Cold restart 27 S7-300/400/1500
OB121 Programming error Priority of OB that caused it S7-300/400/1200/1500
OB122 I/O access error Priority of OB that caused it S7-300/400/1200/1500
OB123 STOP request — S7-1500

Priority classes are CPU-specific; the table shows S7-1500 values. S7-1200 priorities are documented in the S7-1200 System Manual under "Program execution priorities." Cyclic-interrupt OBs (OB30–OB38) are useful for fixed-rate tasks that must run at a deterministic interval independent of OB1 cycle time. For example, OB35 at 100 ms is a common pattern for PID loop execution and closed-loop control on S7-300/400, and equivalent fixed-rate OBs exist on S7-1500.

Note: OBs cannot be called by the user program with a normal call instruction. They are dispatched exclusively by the CPU firmware in response to an event. Inside an OB, you can call FBs and FCs (CALL FBx.DBx, CALL FCx) but you cannot call another OB. The same code that needs to run in multiple OBs must be wrapped in a single FB/FC that each OB calls.

Function Blocks (FB)

A Function Block is a code block with its own associated data block — the instance DB. The instance DB holds the FB's input, output, in-out, and static variables across scans. Each call of an FB in the user program references a specific instance DB, giving the FB its own persistent state.

Per the SIMATIC S7-1200 documentation, the FB definition is a code template; the runtime state lives in the instance DB. Reusing the same FB with multiple instance DBs creates multiple independent "instances" — the classic pattern for modeling a fleet of identical motors, valves, or PID loops.

The instance DB is automatically generated by the TIA Portal compiler the first time the FB is called. The compiler allocates a DB number, computes the offset of every variable in the interface, and downloads both the FB and the DB to the CPU. If you change the interface of the FB after a first download, every instance DB that references it becomes "inconsistent" until it is recompiled and re-downloaded.

Single-Instance vs. Multi-Instance

By default, every FB call in STEP 7 generates a dedicated instance DB. An FB can also be declared as a multi-instance, in which case its instance data is embedded inside another parent FB's instance DB. Multi-instance is the recommended pattern for building hierarchical type structures without proliferating DBs in the project tree.

To use a multi-instance, declare the nested FB as a Static variable inside the parent FB's interface:

FUNCTION_BLOCK "Press_Control"
VAR
    s_Valve1   : "Valve_Type";   // multi-instance of FB200
    s_Valve2   : "Valve_Type";
    s_Pump1    : "Pump_Type";    // multi-instance of FB300
    s_Heater1  : "Heater_Type";  // multi-instance of FB400
END_VAR
BEGIN
    "Valve_Type_DB"(s_Valve1);   // call on multi-instance, data in parent's instance DB
    "Valve_Type_DB"(s_Valve2);
    "Pump_Type_DB"(s_Pump1);
    "Heater_Type_DB"(s_Heater1);
END_FUNCTION_BLOCK

FB Interface Declaration Example (SCL)

FUNCTION_BLOCK "Motor_Control"
{ S7_Optimized_Access := 'TRUE' }
VAR
    // --- Inputs ---
    i_StartCmd   : BOOL;          // momentary start
    i_StopCmd    : BOOL;          // momentary stop
    i_SpeedSet   : REAL;          // setpoint, rpm
    // --- Outputs ---
    o_Running    : BOOL;          // 1 = drive enabled
    o_AtSpeed    : BOOL;          // 1 = at setpoint window
    o_Fault      : BOOL;          // 1 = drive tripped
    // --- InOuts ---
    io_HMI       : "HMI_Type";    // bidirectional HMI mirror
    // --- Statics (retained) ---
    s_RampTime   : TIME := T#10s; // retained across scans
    s_RunHours   : REAL;          // retained
    s_State      : INT;           // 0=Idle, 1=Starting, 2=Run, 3=Fault
END_VAR
BEGIN
    // implementation
END_FUNCTION_BLOCK

Functions (FC)

Functions are parameterless or parametered code blocks that return a single value of any elementary or structured type. They use the L stack (local stack) for temporary variables; these do not persist across calls. An FC has no instance DB, so calling an FC twice with different inputs does not preserve state between calls — the FC is a pure transformation.

Use FCs for stateless computations, conversions, scaling, and shared utility logic. They consume less work memory than FBs because there is no persistent instance DB to load. FBs of identical functionality have a non-trivial memory overhead per instance (every static variable, including any nested multi-instance FBs, is copied into the instance DB).

If the FC's return type is VOID (the default in SCL), the function performs side effects on its IN/OUT/OUT parameters and on global data (M, DBs). If the FC's return type is non-void, the block returns a single value of that type to the caller — useful for math, conversion, and lookup functions.

FUNCTION "Scale_Raw_To_Eng" : REAL
VAR_INPUT
    i_Raw       : INT;      // 0..27648 (Siemens normed value)
    i_LowEng    : REAL;     // engineering value at 0
    i_HighEng   : REAL;     // engineering value at 27648
END_VAR
VAR_TEMP
    t_Scaled    : REAL;
END_VAR
BEGIN
    t_Scaled := INT_TO_REAL(i_Raw) / 27648.0 * (i_HighEng - i_LowEng) + i_LowEng;
    "Scale_Raw_To_Eng" := LIMIT(MIN(i_LowEng, i_HighEng), t_Scaled, MAX(i_LowEng, i_HighEng));
END_FUNCTION

The above FC is fully stateless: it takes three inputs, returns one output, and leaves no memory footprint between calls. Place it in a "Utilities" program block and call it from any other FB, FC, or OB that needs a scaling conversion.

Data Blocks (DB)

Data blocks store structured or unstructured data used by the program. There are two DB types:

  • Instance DB — generated automatically when an FB is called, or manually when you need an instance of a known FB type. Holds the FB's working data: Inputs, Outputs, InOuts, Statics. The data layout mirrors the FB interface.
  • Global DB — defined by the user and accessed by any FB, FC, or OB. Holds shared variables, recipes, configuration, machine state, and HMI-mirrored data.

DBs can be declared as optimized (symbolic-only, with no fixed address layout) or standard (with explicit absolute addresses). Optimized access is the default for S7-1200/S7-1500 and is required for symbolic-only access from SCL and GRAPH. Standard access exists for backward compatibility with S7-300/400 and for HMI panels that need a fixed memory map.

Note: S7-1500 and S7-1200 (firmware V4.0+) use optimized DBs by default. S7-300/400 use standard (non-optimized) DBs unless you specifically enable optimized access. Mixing optimized and standard access in the same project can break HMI and third-party OPC connections — pick one mode per DB and document it.

DB Element Declarations

DATA_BLOCK "DB_MachineState"
{ S7_Optimized_Access := 'TRUE' }
VAR
    b_Ready          : BOOL;       // retained
    b_AutoMode       : BOOL;       // retained
    i_RecipeNumber   : INT;        // retained
    r_SpeedSet       : REAL;       // not retained
    s_LastFault      : STRING[40]; // retained
END_VAR
BEGIN
END_DATA_BLOCK

Each variable has an explicit Retain attribute in the variable properties. On power loss, retained variables are restored from non-volatile storage; non-retained variables are reset to their initial values (or zero, if no initial value is declared).

Block Interface Layout (IN/OUT/IN_OUT/STAT/TEMP/RETURN)

Every FB, FC, and the code section of an OB declares variables in fixed interface sections. The semantics differ by section.

Section Scope Retention Where declared
Input (IN) Read-only inside the block Set by caller, per call FB, FC
Output (OUT) Write-only inside the block Returned to caller, per call FB, FC
InOut (IN_OUT) Read/write, passed by reference Caller-supplied storage FB, FC
Static (STAT) Block-internal, retained Persists in instance DB FB only
Temp (TEMP) Block-internal, scratch Lost on block exit OB, FB, FC
Return (RETURN) Block return value Per call FC (and FB function block with return)
Constant (CONST) Read-only, block-scope Compile-time FB, FC, OB (S7-1500)

IN_OUT is a pointer-like reference in S7-300/400; on S7-1500 it is fully symbolic. Either way, modifying an IN_OUT parameter inside the block modifies the caller's variable. Use IN_OUT for large structured data (e.g., HMI mirror structs) to avoid copying the entire structure on every call.

Memory Model: I, Q, M, L, DB, and Retain

The S7-1500 CPU work memory is divided into named areas:

  • Inputs (I) — process image of physical inputs, refreshed at the start of OB1. Also accessible via direct peripheral access (PIW, PIB) outside the process image.
  • Outputs (Q) — process image of physical outputs, written at the end of OB1. Direct peripheral access via PQW, PQB bypasses the process image.
  • Bit Memory (M) — general-purpose flags, addressable absolutely or symbolically. The size of the M area is configurable in the PLC properties.
  • Temporary Local (L) — stack storage for TEMP variables during block execution. The L area is allocated when the block is entered and released when the block exits.
  • Data (DB) — structured data in data blocks, retained or non-retained.

Retain behavior is configured in the PLC properties for bit memory, S7 timers, S7 counters, and individual DB variables. On power loss, retained values are restored from the non-volatile storage area. TEMP variables are always lost on block exit, and I/Q are refreshed on each OB1 cycle.

Note: Always mark variables that represent process state (counts, positions, machine modes, last-fault record) as retain in the DB or M area, otherwise a power cycle will reset them and the process will start from a cold state.

Programming Language Support

OB, FB, FC, and DB bodies can be written in LAD (Ladder), FBD (Function Block Diagram), SCL (Structured Control Language), GRAPH (S7-1500 on selected CPUs), or STL (Statement List, S7-300/400 only). The block container and interface are language-independent; only the code section differs. A single project can mix languages — for example, a sequencer in GRAPH inside a wrapper FB written in SCL, called from a LAD OB1.

Language S7-300/400 S7-1200 S7-1500 Best for
LAD Yes Yes Yes Bit logic, safety, electricians
FBD Yes Yes Yes Bit and math, two-sided wiring
SCL Yes (optional) Yes Yes Math, loops, data structures, recipes
STL Yes No No Legacy, fine control (S7-300/400 only)
GRAPH Yes (optional) No Yes (selected CPUs) Sequential state machines

Block Call Hierarchy, Nesting, and Watchdog

The maximum nesting depth for FBs and FCs is CPU-specific. S7-1500 supports up to 16 nested FB/FC calls in a single execution path; S7-1200 supports up to 8. Exceeding the depth triggers an OB121 (programming error) and the CPU goes to STOP, depending on the configured error handling.

Each FB call passes the instance DB number as the block ID parameter:

// LAD/FBD: call FB10 with instance DB 100
CALL "Motor_Control", "iDB_Motor_1"
i_StartCmd := "DB_Control".b_Start
i_StopCmd  := "DB_Control".b_Stop
o_Running  => "DB_Control".b_Running
o_Fault    => "DB_Control".b_Fault

The instance DB is automatically generated by the compiler in optimized mode. In SCL, the call is reduced to a single line:

"DB_Control".b_Running := "Motor_Control"(i_StartCmd := "DB_Control".b_Start, i_StopCmd := "DB_Control".b_Stop).o_Running;

To prevent OB1 from exceeding the cycle watchdog, monitor the cycle time in the PLC properties. If the scan grows beyond the maximum cycle time, configure a hardware interrupt on the cycle-time overflow event, or split the program across cyclic interrupt OBs (OB30–OB38) at fixed rates.

Side-by-Side Block Comparison

Property OB FB FC DB (instance) DB (global)
Has instance DB No Yes (own) No — —
Has static variables No Yes No — —
Called by CPU firmware FB, FC, OB FB, FC, OB Referenced by FB Any code
Number limit (S7-1500, reference CPU) CPU-specific 8 000 8 000 6 000 6 000
Code size limit (S7-1500) — ≤ 512 KB ≤ 512 KB — —
DB size limit (S7-1500) — — — ≤ 16 MB ≤ 16 MB
Retain support No (TEMP only) Per STAT variable No (TEMP only) Per element Per element
Default access mode (S7-1500) Code Optimized Optimized Optimized Optimized

Reference CPU values are typical for the S7-1500 entry-level family (e.g., CPU 1511-1 PN, order number 6ES7511-1AK02-0AB0). The exact limits for a given order number are in the device's manual under "Block limits" or "Resource limits."

Block-Type Selection Checklist

  1. Will the block need to remember state between scans? Use FB with an instance DB.
  2. Is the block a pure calculation, conversion, or stateless utility? Use FC.
  3. Is the data shared across multiple blocks, independent of any one FB? Use a global DB.
  4. Is the data tied to a specific FB instance and you want to keep the project tree clean? Use a multi-instance inside the parent FB.
  5. Is the code triggered by a CPU event, not by a call? Use the matching OB type.
  6. Is the code part of the cyclic main scan? Place it inside OB1 (or a cyclic interrupt OB for high-priority fixed-rate tasks).
  7. Is the code part of a sequential state machine with steps and transitions? Use GRAPH inside an FB.
  8. Is the code reused across multiple machines as a library? Use a Type FB with versioning for master/library distribution.

Commissioning, Online View, and Diagnostics

In TIA Portal, attach the online view to the project and expand the Program blocks tree. The instance DB shows the live values of all STAT, IN, OUT, IN_OUT variables. Force tables operate on absolute I/Q/M addresses. Watch tables can monitor both absolute and symbolic values, with periodic update and trigger on threshold. To step into a call from OB1, place a breakpoint inside the FB/FC code; the online debugger enters the called block on the next scan and highlights the active network.

For S7-1500, the built-in Web Server exposes the variable status of the CPU online; a read-only XML/JSON view of DB contents is available at the configured HTTP endpoint, with role-based access for read-only and read/write users. Enable the Web Server in the PLC properties, configure the user list, and open the URL in a browser to inspect live data without a TIA Portal online session.

For diagnostic data from PROFINET devices, OB82 fires when a diagnostics-capable module (e.g., an SM 1500 with diagnostic interrupts enabled) reports a change — a channel fault, wire break, or short circuit. Inside OB82, read the local data (OB82_MDL_ADDR, OB82_EVENT_CLASS) to identify the slot and channel, set a flag, and decide whether to continue or bring the process to a safe state.

Common Errors and Diagnostics

Symptom Likely cause Resolution
CPU goes to STOP after download Missing or invalid OB; calling FB with deleted instance DB Recompile the project (Project → Compile all), re-download all blocks, verify each FB has a valid instance DB
OB121 "Programming error" DB access on undefined DB; type mismatch in FB call; divide by zero; array index out of range Open Online & Diagnostics → Diagnostics Buffer; correct the offending call; add a guard for the divide and the array access
OB122 "I/O access error" Accessing I/P address with no module inserted, or module in STOP Verify hardware configuration; assign a substitute value (OB122.SAMPLE_IF_FAULT) or insert the module
Static variable does not retain Retain attribute not set on the variable or DB Open the DB in offline view, mark the variable as "Retain" in the properties (Set in IDB / Retain)
"Instance DB inconsistent" FB interface changed but instance DB not recompiled Right-click the FB → "Compile and download blocks" to refresh all instance DBs
Call from FC to FB without instance DB specified Unspecified instance at call site Open the call site, select a valid instance DB in the FB box, or convert the FB to a multi-instance
OB does not exist / "OB not loaded" OB needed for the configured event (e.g., diagnostic interrupt) is missing Add the appropriate OB from the project tree; if not needed, disable the source of the event
Cycle time exceeds watchdog Long-running code path inside OB1 or cyclic OB Split logic across cyclic interrupt OBs; move non-critical tasks to a lower-priority OB; increase the cycle watchdog
Watch table shows wrong values for a multi-instance Wrong instance selected in the watch table Use the path of the multi-instance variable in the watch table, not the FB number

For S7-1500, the CPU's diagnostic buffer records the OB, the program counter, and the block stack at the time of the error. Right-click the diagnostic buffer entry and select "Open block" to jump directly to the offending instruction. Export the buffer (right-click → Export) to a CSV for offline analysis and inclusion in a service report.

FAQ

What is the difference between an FB and an FC in SIMATIC S7?

An FB (Function Block) uses a dedicated instance data block to hold its static variables, so it remembers state between scans. An FC (Function) has no instance DB; its variables live on the local L stack and are lost when the FC exits. Use FB for stateful logic (motors, valves, PID loops) and FC for stateless calculations (scaling, conversion, math).

Can I call one OB from another OB?

No. OBs are dispatched exclusively by the CPU firmware in response to a specific event. You cannot call an OB with the CALL instruction. Use FBs and FCs for code that needs to be shared between execution contexts, and trigger the FB/FC from each OB that needs it.

Why does my FB's static variable reset to zero on CPU restart?

Retain is not configured. Open the instance DB (or the multi-instance parent) in offline view, select the variable, and enable the "Set in IDB" / "Retain" attribute in the Properties pane. After a STOP/RUN or power-cycle, the variable will be restored from the non-volatile storage area.

What is the maximum number of blocks on an S7-1500 CPU?

Number limits are CPU-model-specific. Reference CPUs (e.g., CPU 1511-1 PN, 6ES7511-1AK02-0AB0) support up to 8 000 FBs, 8 000 FCs, 6 000 instance DBs, and 6 000 global DBs. The exact limits are listed in the S7-1500 System Manual for the specific order number.

What is the purpose of OB82 in a diagnostic setup?

OB82 fires when a diagnostics-capable module (e.g., an SM 1500 with diagnostic interrupts enabled) reports a change — a channel fault, wire break, or short circuit. Inside OB82, read the local data (OB82_MDL_ADDR, OB82_EVENT_CLASS) to identify the slot and channel, set a flag, and decide whether to continue or bring the process to a safe state.

Should I use a global DB or an instance DB for machine state?

If the data belongs to a single FB instance (one motor, one valve), put it in the FB's instance DB. If the data is shared across many FBs and OBs (overall mode, totalizers, recipe selection), put it in a global DB. Multi-instance FBs can hold their own sub-state inside a parent's instance DB while still being called from a global context.

Back to blog