Overview
STEP 7 is the Siemens engineering environment used to program the SIMATIC S7-300, S7-400, and the older S7-200 (Micro/Win) and S7-1200/1500 (in the TIA Portal) controller families. Within STEP 7, a user program is never written as a single linear file. Instead, the logic is partitioned into modular blocks that are linked through explicit calls. The four primary block types are Organization Blocks (OB), Function Blocks (FB), Functions (FC), and Data Blocks (DB). Two further families, System Function Blocks (SFB) and System Functions (SFC), are firmware-resident and provide standardised services such as time-of-day, counters, and on-board I/O access. Function block programming in STEP 7 is the discipline of composing these blocks so that the application becomes a tree of reusable, parameterised, and isolated algorithm modules with their own persistent state.
This reference expands on the basic notion of a "function block" as simply a graphic representation of ladder logic. An FB is a re-usable algorithm template that uses an associated Instance Data Block to retain its variables between scan cycles. A program can contain many instances of the same FB, each with its own private data area, allowing the same piece of code to control, for instance, twenty identical pumps with twenty independent sets of timers, setpoints, and alarm flags. The IEC 61131-3 standard (IEC 61131-3:2013) calls this construct a function block instance, and the STEP 7 implementation is one of the most widely deployed realisations of that standard concept.
The same modular structure is also visible in other vendors' environments. The Rockwell Automation 1336-Plus Function Block Programming Manual (1336T-UM007) describes an analogous application-list model for the 1336-Plus drive, and the Wikipedia overview of Function Block Diagram (FBD) language summarises the graphical and IEC origins of the FBD editor used in STEP 7.
STEP 7 Program Structure and Block Model
A STEP 7 project (S7 Program in the S7-300/400 world, or PLC in TIA Portal) is composed of source blocks that the compiler turns into executable compiled blocks loaded to the CPU's load memory. Each block has a fixed header size, a body of code, and (for FBs/DBs) a data area. The CPU executes the operating system, schedules OBs in priority order, and runs the user program by walking the call tree rooted at the cyclic OB (OB1 by default).
| Block Type | Header (bytes) | Has Memory? | Has Instance? | Typical Use |
|---|---|---|---|---|
| OB - Organization Block | varies (20-34) | No | No | Trigger execution by event/priority |
| FB - Function Block | 36 | Yes (STAT) | Yes (instance DB) | Reusable logic with state |
| FC - Function | 20 | No (TEMP only) | No | Pure computation, parameter passing |
| DB - Data Block | varies (24 + data) | Yes (entire block is data) | n/a (DB = instance for FB) | Persistent data storage |
| SFB - System Function Block | 36 | Yes | Yes (instance DB required) | Firmware function with state |
| SFC - System Function | 20 | No | No | Firmware stateless service |
Header sizes above apply to the S7-300/400 platform. TIA Portal S7-1200/1500 blocks use a slightly different internal layout but the same logical structure. Block headers contain the MC7 code length, the interface template length, and the local stack frame for TEMP variables.
Organization Blocks (OBs)
OBs are the only blocks that the CPU operating system schedules automatically. Every FB/FC/DB must be reached through an OB or through a call chain that starts at an OB. Each OB type corresponds to a triggering event and has a fixed priority class, which determines the order in which the CPU interrupts a lower-priority OB to run a higher-priority one. Local data (TEMP) is automatically pushed onto the local data stack on entry and popped on exit, so OBs cannot persist state across calls.
| OB | Event / Class | Default Priority (S7-400) | Default Priority (S7-300) | Behaviour |
|---|---|---|---|---|
| OB1 | Main cyclic scan | 1 | 1 | Runs after startup; lowest priority |
| OB10-OB17 | Time-of-day interrupt | 2 | 2 | Fired at programmed date/time |
| OB20-OB23 | Delay interrupt (S7-400) | 3-6 | n/a | Triggered by SFC32 (START_TIME) |
| OB30-OB38 | Cyclic interrupt | 7-15 | 7-15 | OB35 default 100 ms |
| OB40-OB47 | Hardware interrupt | 16-23 | 16-23 | Triggered by I/O module event |
| OB55-OB57 | Status / update / manufacturer interrupt | 2 | 2 | DPV1 / PN diagnostic |
| OB80 | Time error | 26 | 26 | Cyclic OB overrun or skip |
| OB81 | Power supply error | 26 | 26 | Battery / 24 V failure |
| OB82 | Diagnostic interrupt | 26 | 26 | Module diagnostic event |
| OB83 | Insert/remove interrupt | 26 | 26 | Hot-swap event |
| OB84 | CPU hardware fault | 26 | 26 | MP interface failure |
| OB85 | Program execution error | 26 | 26 | OB not loaded, I/O access fault on started OB |
| OB86 | Rack / station failure | 26 | 26 | PROFIBUS / PROFINET loss |
| OB87 | Communication error | 26 | 26 | GD/PN/DP frame failure |
| OB100 | Warm restart | 27 | 27 | Run-up with non-retentive reset |
| OB101 | Hot restart (S7-400 only) | 27 | n/a | Run-up with all retentive preserved |
| OB102 | Cold restart | 27 | 27 | Full reset, OB1 restart |
| OB121 | Programming error | Of OB that caused it | Of OB that caused it | DB not loaded, type conflict |
| OB122 | I/O access error | Of OB that caused it | Of OB that caused it | Missing module, removed I/O |
OB121 and OB122 are called synchronous errors: they execute in the same priority class as the OB that triggered them, so they cannot interrupt a high-priority OB. If OB121/OB122 is missing, the CPU stops with SF LED and the corresponding error byte in the diagnostic buffer. S7-300/400 OB priority assignments are documented in the SIMATIC S7-300/400 System and Standard Functions reference manual available from the Siemens Industry Online Support portal.
The OB start information is fixed and exposes pre-defined TEMP variables. OB40, for example, provides the address of the triggering channel in OB40_MDL_ADDR and a vector in OB40_POINT_ADDR; OB100 provides the start-up reason in OB100_STRTUP. These variables are not user-defined; they are part of the block's interface template.
Function Blocks (FBs) and Instance Data Blocks
A Function Block is the only STEP 7 construct that owns persistent local data. When the FB is created, the programmer declares an IN, OUT, IN_OUT, STAT, and TEMP interface. STAT variables are stored in the associated Instance Data Block (DBi), which the FB reads and writes on every call. TEMP variables live on the local stack of the calling OB and are re-initialised on each invocation. STAT variables are also accessible symbolically from outside the FB as "InstanceDB".VariableName, which is useful for HMI faceplates.
| Interface Section | Storage | Lifecycle | Notes |
|---|---|---|---|
| IN | Caller passes value; FB stores a copy in instance DB | Per-call (formal parameter) | Re-initialised on each call |
| OUT | FB writes back to instance DB | Per-call (formal parameter) | Value returned to caller at END |
| IN_OUT | FB receives a pointer to caller variable | Per-call (formal parameter) | Modifies caller's variable directly |
| STAT | Instance DB | Persistent across calls | Remembers state |
| TEMP | Local stack of calling OB | Per-call, undefined on entry | Must be initialised before use |
The most common pattern is a single-instance FB where one DB acts as the only instance. STEP 7 also supports multi-instance FBs: an FB may declare a STAT variable of another FB type, embedding the inner FB's instance data inside the outer FB's instance DB. This is the recommended technique for building modular libraries (see SIMATIC S7-300 Programming with STEP 7 manual, chapter on instance DBs).
Minimal FB in FBD (LAD/FBD/STL editor)
FUNCTION_BLOCK FB1
VAR_INPUT
iStart : BOOL;
iStop : BOOL;
END_VAR
VAR_OUTPUT
qMotor : BOOL;
END_VAR
VAR
bRunning : BOOL; // STAT
END_VAR
BEGIN
qMotor := (iStart OR bRunning) AND NOT iStop;
bRunning := qMotor;
END_FUNCTION_BLOCK
The block above, placed in OB1, can be called with three separate instance DBs (DB1, DB2, DB3) to control three independent motors without duplicating the algorithm. The bRunning bit for each motor lives in its own instance DB and never collides with the others. The IEC 61131-3 function block instance notion is the standardisation of this exact pattern.
Functions (FCs)
An FC is a parameterless or parameterised sub-program with no memory. All local data is TEMP, so an FC cannot retain a value from one call to the next. FCs are used for:
- Mathematical calculations (e.g. scaling 4-20 mA to engineering units).
- Boolean logic that does not require latching.
- Reusable code that receives inputs, returns a single output value, and never needs state.
FCs are also the unit of choice for IEC 61131-3 standard functions in STEP 7, such as FC30 to FC45 (e.g. floating-point add/sub/mul/div, square root, log, sin, cos). Custom FCs in the user range (FC1-FC99999) can call these library functions to wrap higher-level operations.
Data Blocks (DBs) and Instance DBs
DBs come in two flavours:
- Global DBs - declared with no associated FB. Used for shared data such as recipe sets, operator setpoints, and inter-FB communication buffers.
- Instance DBs - generated automatically when an FB is inserted into OB1, OB35, etc. The structure of the instance DB exactly matches the FB's STAT, IN, OUT, and IN_OUT declarations.
The two can coexist with the same block number only on different FBs. Modifying an FB's interface after its instance DB has been downloaded requires an "Update Instance" or "Generate Instance DB" step in the offline program. Forgetting this step yields OB85 / OB121 errors at runtime because the instance DB does not match the new interface template.
| Use Case | Recommended Storage | Why |
|---|---|---|
| Pump run-time, last fault, internal mode | FB STAT in instance DB | Encapsulated, copy-paste-able |
| Operator setpoint | Global DB, UDT typed | HMI-friendly, UDT gives structure |
| Recipe data | Global DB, loaded from MMC/SD | Persists in load memory, large size |
| Handshake between FBs | Global DB, or IN_OUT parameter | Avoid hidden coupling |
| Firmware functions (SFB) | System-generated instance DB (DB4-DBn) | Required for SFB call |
STEP 7 supports User-Defined Data Types (UDT) for declaring complex structures that are reused across many DBs. A UDT acts as a template; a DB declared of type UDT1 is automatically populated with the UDT structure, so changing the UDT and re-initialising the DB updates all consumers at once.
System Function Blocks (SFBs) and System Functions (SFCs)
SFBs and SFCs are part of the CPU firmware and do not need to be downloaded. They expose platform features such as:
| Block | Purpose | Storage |
|---|---|---|
| SFC0 SET_CLK | Set CPU time-of-day | None |
| SFC1 READ_CLK | Read CPU time-of-day | None |
| SFC2 SET_RTM | Set run-time meter | None |
| SFC3 CTRL_RTM | Start/stop run-time meter | None |
| SFC4 READ_RTM | Read run-time meter | None |
| SFC6 RD_SINFO | Read start info of OB | None |
| SFC20 BLKMOV | Copy memory area | None |
| SFC21 FILL | Fill memory with pattern | None |
| SFC22 CREAT_DB | Create DB at runtime | None |
| SFC23 DEL_DB | Delete DB at runtime | None |
| SFC24 TEST_DB | Test DB existence | None |
| SFC32 SRT_DINT | Start delay interrupt (OB20) | None |
| SFC33 CAN_DINT | Cancel delay interrupt | None |
| SFC34 QRY_DINT | Query delay interrupt status | None |
| SFC35 MP_ALM | Trigger multithread alarm | None |
| SFC36 MSK_FLT | Mask synchronous errors | None |
| SFC38 UNMASK_FLT | Unmask synchronous errors | None |
| SFC39 DIS_IRT | Disable interrupt | None |
| SFC40 EN_IRT | Enable interrupt | None |
| SFC42 ENABLE_SFC | Enable gated SFC | None |
| SFB0 CTU | IEC up counter | Instance DB required |
| SFB1 CTD | IEC down counter | Instance DB required |
| SFB2 CTUD | IEC up/down counter | Instance DB required |
| SFB3 TP | IEC pulse timer | Instance DB required |
| SFB4 TON | IEC on-delay timer | Instance DB required |
| SFB5 TOF | IEC off-delay timer | Instance DB required |
| SFB32 DRUM | Sequence drum (steps) | Instance DB required |
| SFB52 RDREC | Read record from PN/DP slave | Instance DB required |
| SFB53 WRREC | Write record to PN/DP slave | Instance DB required |
The full list is in the SIMATIC S7-300/400 System and Standard Functions reference manual. The SFB set is a subset of the IEC 61131-3 standard FB library - specifically, the timers and counters (SFB0-SFB5) - that STEP 7 ships in firmware so every project can use them portably.
Programming Languages: LAD, FBD, STL, SCL, GRAPH, HiGraph
STEP 7 supports six editors, all IEC 61131-3 conformant except HiGraph (a Siemens add-on for state-transition graphs). Block source code can be created in any of them and re-compiled on the fly; the on-CPU representation is always MC7 (machine code 7), so switching the editor on a block does not change its behaviour. The choice of editor is therefore a function of the engineer's preference and the type of problem, not a deployment decision.
| Editor | Full Name | IEC 61131-3 Designation | Best For |
|---|---|---|---|
| LAD | Ladder Diagram | LD | Boolean logic, relay-replacement |
| FBD | Function Block Diagram | FBD | Arithmetic, signal-flow |
| STL | Statement List | IL (Instruction List) | Compact code, indirect addressing |
| SCL | Structured Control Language | ST (Structured Text) | Math, loops, data structures |
| GRAPH | Sequential Function Chart | SFC | Sequential machine control |
| HiGraph | State graph | (Siemens-specific) | Asynchronous, mode-rich machines |
The FBD editor is the literal "function block programming" most engineers mean. The Wikipedia entry on Function Block Diagram traces the language's origin to the IEC 1131-3 (now 61131-3) standard and the Hartfiel/CoDeSys heritage. In the STEP 7 FBD editor, AND/OR blocks are operators and box-type instances (timers, counters, FBs) are call sites. The result is a graphical flow that compiles to MC7. Identical functionality is achievable in LAD (LADDER) or STL; the FBD form is usually chosen for signal-flow clarity.
Call Hierarchy and Parameter Passing
STEP 7 calls are static: the call is fixed in the offline program and the compiler resolves the call depth at build time. The maximum nesting depth is 8 in S7-300 and 16 (or 24, firmware-dependent) in S7-400. Exceeding this limit triggers OB85 with the message "OB not loaded / nesting too deep".
Local data is allocated from a fixed-size L stack (local data stack) configured in the CPU properties. Each OB is assigned a local data size; the sum across simultaneously running OBs must not exceed the L stack. A common startup error is to assign OB1 256 bytes and forget to expand the size when OB35/OB40 are added, after which the CPU stops at the second interrupt with "local data conflict".
Parameter passing rules:
- IN/OUT/IN_OUT may be elementary types (BOOL, INT, REAL, BYTE, WORD, DWORD, CHAR, S5TIME, TIME, DATE, TIME_OF_DAY) or complex types (ARRAY, STRUCT, UDT, STRING).
- IN parameters are passed by value (copy in), IN_OUT by reference (pointer).
- Arrays may be passed only with defined limits (e.g.
ARRAY[1..10] OF INT). - Multi-dimensional arrays must be fully bounded in the FB declaration.
Multi-Instance FBs
Multi-instance FBs are a way to embed several instances of one FB (or of many FBs) inside a single outer instance DB. This dramatically reduces DB count and centralises state. The S7-300 supports multi-instance from firmware V3.0 onwards. To use it, declare a STAT variable of FB type inside the outer FB. The instance DB of the outer FB then carries a sub-area for each inner FB.
FUNCTION_BLOCK FB_MotorBank // outer FB
VAR
Pump1 : FB1; // STAT of type FB1, multi-instance
Pump2 : FB1; // second instance of the same FB1
Pump3 : FB1;
END_VAR
BEGIN
Pump1(iStart := I0.0, iStop := I0.1, qMotor := Q4.0);
Pump2(iStart := I0.2, iStop := I0.3, qMotor := Q4.1);
Pump3(iStart := I0.4, iStop := I0.5, qMotor := Q4.2);
END_FUNCTION_BLOCK
The state bits of Pump1, Pump2, Pump3 are now stored under DB100.Pump1.bRunning, DB100.Pump2.bRunning, and so on. The principle is described in the S7-300/400 programming manual; it is also the basis for Siemens' standard library for the S7-300 (e.g. blocks for PID, motor control, communication) which are all packaged as multi-instance FBs.
Best Practices and Field Tips
- Prefer FB over FC for any stateful logic. If your "FC" uses merkers to remember values, refactor it to an FB. This makes the code re-entrant, testable, and IEC-portable.
- Use UDT for shared structures. A UDT acts as a C-style struct. Use it for motor, valve, PID, and alarm record types so a single edit propagates to every DB.
- Reserve OB1 for the call tree. Put the heavy logic in FBs/FCs, keep OB1 to a list of unconditional calls. This gives the scan a single readable structure.
- Configure local data sizes explicitly. Set the local data for OB1, OB35, OB40, OB82 to slightly more than the compiler reports. Reduces OB85 "local data conflict" surprises after changes.
- Use symbolic addressing. Activate "Symbolic Representation" in the block interface. With this, the compiler shows variable names in the editor and the STL becomes readable.
- Mark blocks as "know-how protected" for vendor IP but provide compiled-only libraries so customers can use them without changing them.
- Re-compile after FB interface changes. Always regenerate instance DBs; failing to do so is the most common source of OB85 / OB121 errors in field service.
- Use OB35 (or OB30-OB38) for cyclic tasks. They have higher priority than OB1 and run regardless of OB1 scan time. Common pattern: 100 ms OB35 for PID and 1 s OB32 for slower housekeeping.
- Guard against undefined TEMP. Always initialise TEMP variables before use. Some compilers leave the L stack uninitialised, so reading TEMP on first call yields garbage.
- Document the call hierarchy. Use the "Reference Data > Program Structure" view in STEP 7. It produces a tree showing which OB calls which FB/FC/SFB/SFC, essential for impact analysis during commissioning.
Migration to TIA Portal
STEP 7 V5.x is the classic environment for S7-300/400. New development has moved to TIA Portal (Totally Integrated Automation) for the S7-1200 and S7-1500. The block model is identical - OBs, FBs, FCs, DBs, SFBs, SFCs - but the editor is integrated with the hardware configuration, HMI, and motion commissioning. Existing S7-300/400 projects can be migrated to a TIA Portal S7-1500 using the "Migrate project" wizard, which preserves the block structure. IEC 61131-3 conformance means the FBD, LAD, STL (IL), and SCL (ST) code translates directly. The S7-1200/1500 does not support STL; the closest equivalent is SCL, which is heavily recommended for new code.
Verification Checklist for Function Block Programs
- Use Monitor/Modify in OB1 to step through the call tree and confirm each FB's instance DB updates as expected.
- Open the instance DB with "Monitor" enabled; verify STAT values on each cycle.
- Force an I/O input to trigger the hardware interrupt (OB40) and confirm the OB40 is loaded and the FB it calls is also loaded.
- In the CPU diagnostic buffer, look for OB85, OB121, OB122 events; the date/time of the first occurrence usually points to the block that was just modified.
- Use the cross-reference (Ctrl+Alt+F7) to confirm every variable is used; unused IN/OUT/STAT clutter the FB and obscure the interface.
- Save a final, compiled project archive (zip) before any commissioning trip; the upload-only PC has nothing to load from.
Frequently Asked Questions
What is the difference between an FB and an FC in STEP 7?
An FB (Function Block) has its own memory in the form of an Instance Data Block and can retain STAT values across scan cycles. An FC (Function) has no memory - all its local data is TEMP and is re-initialised on every call. Use an FB whenever the algorithm needs to remember state (timers, setpoints, latches); use an FC for stateless calculations such as scaling and math.
How many instances of one FB can I create?
STEP 7 does not impose a hard limit on the number of instances. The constraint is the CPU work memory: an S7-300 with 64 KB work memory fits roughly 1500 to 3000 simple FB instances, while an S7-400 with several MB fits tens of thousands. The real practical limit is the local data stack depth (8 in S7-300, 16/24 in S7-400) and the cycle time budget.
Why does the CPU stop with OB85 after I add OB35?
Each OB consumes local data stack space, and the L stack size is set in the CPU properties. When you add OB35, you must also raise the local data size for OB35 in the CPU hardware configuration. Otherwise the cyclic interrupt tries to use TEMP space that the L stack has not been extended to provide, and OB85 fires "Local data conflict".
Can I call an FB from another FB without using multi-instance?
Yes, but each inner call must declare its own instance DB. The inner FB's STAT is then in a separate DB rather than embedded in the outer FB's instance DB. Multi-instance is the cleaner pattern because it centralises the data and reduces DB count, but separate instance DBs work fine and are sometimes used to expose the inner state to HMI directly.
What happens if I change the interface of an FB after downloading?
STEP 7 marks the instance DB as out-of-date. You must right-click the FB and select "Instance DB > Update" (or regenerate the instance) before the next download. Forgetting this step leads to OB85 / OB121 errors at runtime because the instance DB structure no longer matches the FB interface. The fix is the explicit update step followed by a full download of the FB and its instance DB.