Siemens S7 Data Blocks: Global vs Instance DB Architecture Reference
This reference consolidates field-proven guidance for designing STEP 7 / TIA Portal user programs around Data Blocks (DB). It addresses the most common question asked by engineers migrating from the Rockwell/Allen-Bradley (A-B) Logix platform: should the application use Global DBs with Functions (FC), or Instance DBs tied to Function Blocks (FB)? The guidance below covers block memory layout, the FC/FB call model, byte-ordering rules, IEC timer/counter selection, Organization Block (OB) usage, User-Defined Types (UDT), and structured design patterns that scale from a single conveyor to multi-section plant code.
1. Data Block Architecture in S7
Data Blocks are the storage containers for variable user data in the S7 user program. Unlike the Process Image (PII/PIQ), Bit Memory (M), or Local / Temp (L) stack, DBs are addressable as named memory regions that survive between scans and can be referenced by every block in the program. Per the official TIA Portal V20 programming reference, "Data blocks thus contain variable data that is used by the user program" and sit alongside OBs, FBs, and FCs as first-class elements of the program.
Two physical flavors of DB exist:
| DB Type | Storage Class | Created By | Structure Source | Typical Use |
|---|---|---|---|---|
| Global DB (GDB) | Global, named | Engineer / compile | Manual declaration in the DB editor or via UDT | Shared recipes, HMI tags, cross-section data, communication buffers |
| Instance DB (IDB) | Global, named, but logically owned by one FB | Auto-generated at FB call | Mirrors the FB's VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_STATIC, VAR_TEMP declaration | Per-equipment state (one DB per motor, valve, conveyor, PID loop) |
Both DB types are accessed the same way at runtime (DB1.DBX0.0, DB1.DBW2, DB1.DBD4). The difference is semantic: a Global DB is a free-form data structure you author by hand; an Instance DB is automatically generated to match the declaration of its parent FB. Per Siemens documentation, an Instance DB's STRUCT is locked to the FB interface and cannot be edited directly in the DB editor; changes must be made in the FB and recompiled.
2. Global Data Blocks (GDB) — Technical Details
A Global DB is simply a named area of work memory. It has no associated code block; the engineer declares its STRUCT manually. GDBs are ideal for data that does not belong to a single piece of equipment, including:
- Recipes and machine setpoints read by HMI
- Production counters and shift totals
- Cross-equipment interlocks (e.g.,
Permissive_Common) - HMI message buffers and alarm history
- Communication buffers for
PUT/GET/BSEND/USENDon S7-300/400, or forREAD/WRITEon S7-1200/1500
Per the TIA Portal V20 programming basics manual, Global DBs are part of the standard block set and can be created from Program blocks > Add new block > Data block. The resulting block is downloaded to the PLC and can be opened in online watch without restrictions.
PUT/GET, BSEND/BRCV, or any communication with an S7-300/400 partner that uses absolute addresses, the DB must be non-optimized (set "Disable optimized block access" in the DB attributes). This is a frequent source of 80A1 / 80A2 errors in cross-PLC tag exchanges — see Section 11.
Authoring tip: split a GDB into sections by purpose (Settings, Status, Production, Comm) using comment dividers. Avoid using a single monolithic GDB for an entire machine — it becomes unsearchable past a few hundred tags and bloats online diff views.
3. Instance Data Blocks (IDB) — Technical Details
An Instance DB is the runtime memory of a Function Block (FB). When an FB is called with a Call instruction, you either name an existing IDB or let the compiler auto-generate a single-instance or multi-instance IDB. The IDB's STRUCT is rebuilt from the FB declaration every time the FB's interface is recompiled.
Standard FB declaration layout:
FUNCTION_BLOCK FB_Conveyor
VAR_INPUT
i_Start : BOOL; // Start command from HMI or upstream
i_Stop : BOOL; // Stop command (NC contact)
i_SpeedSetpoint : REAL; // Hz or %
END_VAR
VAR_OUTPUT
q_Running : BOOL;
q_Fault : BOOL;
q_ActualSpeed : REAL;
END_VAR
VAR_IN_OUT
io_Motor : BOOL; // shared drive enable signal
END_VAR
VAR
s_TON_Run : TON; // IEC on-delay, STATIC retention
s_LastStart : BOOL; // edge-detection bit
s_RunTimeSec : DINT; // accumulated run time
s_StartPulse : BOOL; // one-shot memory
END_VAR
VAR_TEMP
t_TempDword : DWORD; // scratch / intermediate calc only
END_VAR
BEGIN
// FB body
END_FUNCTION_BLOCK
When FB_Conveyor is called as a single instance, the compiler creates an IDB (e.g., DB_Conveyor_1) containing two substructures: a Input, Output, InOut, and Static view that mirrors the FB declaration. Temp variables are not stored in the IDB; they live on the local stack of the calling OB and must not be used after the FB exits.
Calling the same FB multiple times (e.g., Conveyor_1, Conveyor_2, Conveyor_3) can be done as:
- Single-instance: each call uses its own IDB. Recommended when the equipment instances are independent and the FB may be reused in other projects.
- Multi-instance: each call stores its data inside the IDB of a parent FB. Recommended for tightly-coupled subsystems where the parent is the only caller.
Multi-instance syntax (in a parent FB):
FUNCTION_BLOCK FB_Line
VAR
Conveyor1 : FB_Conveyor; // multi-instance, stored in FB_Line's IDB
Conveyor2 : FB_Conveyor;
Conveyor3 : FB_Conveyor;
END_VAR
4. Functions (FC) vs. Function Blocks (FB)
The choice between FC and FB is the central design decision in any S7 program. The trade-off is summarized below.
| Aspect | FC (Function) | FB (Function Block) |
|---|---|---|
| Memory between calls | None. Local (L) stack is overwritten each call. | Retained in the IDB's Static area. |
| Parameter passing | Inputs only (In, Out, InOut) — no stored state | Inputs, Outputs, InOuts, plus Static for state |
| Multi-instance | No | Yes |
| Timers / counters | Requires separate DB or M-bit flag for each instance | IEC timer/counter declared as STAT occupies the IDB |
| Reusability across projects | High (stateless) | High (state encapsulated in IDB) |
| A-B equivalent | Add-On Instruction (AOI) without state, or a Subroutine | Add-On Instruction (AOI) with internal tags |
Rule of thumb from the field:
- Use an FC when the routine is purely a calculation or conversion (e.g., scaling a 4–20 mA raw value to engineering units, computing a CRC). It is also the fastest path to a first working program under deadline pressure.
- Use an FB when the routine has state: a motor, a valve, a PID loop, a state machine, anything that needs to remember between scans.
Combining both is the typical pattern: the OB calls FBs (one per device instance), and each FB calls shared FCs (for math, scaling, alarm formatting). The shared, non-volatile settings live in a single Global DB; the per-device state lives in IDBs.
5. M Memory, Bit Memory, and When to Avoid It
Bit Memory (M / MB / MW / MD) is the legacy scratch-pad of S7. It is faster to type than DBx.DBWy, but it has three structural problems that scale poorly:
-
No online structure view. Watching
M10.0in the variable table is fine; watching 300 M bits mixed across a machine is not. -
Retentivity is per-byte, not per-bit. A
BOOLinMB10inherits the retentive setting of the entire byte. - No symbol-only access on S7-1200/1500 optimized blocks. Optimized FBs cannot reference M bits symbolically; everything must go through a DB.
Practical guidance: keep M reserved for low-level handshakes (e.g., FirstScan, AlwaysTrue, Heartbeat_100ms) and put all real program state in DBs. This mirrors A-B practice of using program tags (controller-scoped) instead of legacy global tags in older SLC/PLC-5 conventions.
6. Byte Ordering, Data Types, and the Ladder Pitfall
S7 is a big-endian architecture for declared types but the bit/byte numbering of absolute addresses can mislead engineers coming from PLC-5 or Logix. The rule to memorize:
MB0 is the most significant byte of MW0 and of MD0. MB1 is the LSB of MW0; MB3 is the LSB of MD0. This is reversed from the natural reading order of an A-B engineer used to B3:0/0 as the lowest bit of a 32-bit word.
When you execute a MOVE (ladder) or T (STL) instruction, the CPU stores the value according to the target's declared type. If you turn off "Type check of operands" in the compiler settings to silence mismatched-type warnings, the program may compile but execute with wrong byte order. The correct fix is to align source and destination types (INT to INT, REAL to REAL) and to swap bytes explicitly with TAW / TAD when interfacing with a device that delivers little-endian data (most Modbus RTU slaves, some ASCII scales).
Recommended data types by use case:
| Application Value | S7 Type | Range | Notes |
|---|---|---|---|
| Digital I/O, coils, status | BOOL | 0 / 1 | One bit per address |
| Counter, BCD, small integer | INT / WORD | -32768 .. 32767 | Use INT for math, WORD for bit-masks |
| Counter, large integer, accumulator | DINT / DWORD | ±2.1e9 | Default for production counts |
| Analog, scaling, PID | REAL | ±3.4e38 (IEEE-754 32-bit) | Always REAL, never use INT for analog on S7-1200/1500 |
| Time, date, timestamps | TIME, DTL, DATE_AND_TIME | Various | DTL since TIA V13, replaces legacy DT |
| String (HMI display) | STRING[n] | n=1..254 chars | First two bytes are max length and actual length |
7. IEC Timers and Counters — The Right Choice
S7 ships two timer families. S5 timers (SP, SE, SD, SS, SF, SA) are bit-mapped legacy blocks from the S5 era. IEC timers are System Function Blocks found in Libraries > Standard Library > System Function Blocks:
| Block | Function | Inputs | Output |
|---|---|---|---|
| SFB3 | TP — pulse | IN, PT | Q, ET |
| SFB4 | TON — on-delay | IN, PT | Q, ET |
| SFB5 | TOF — off-delay | IN, PT | Q, ET |
| SFB0 | CTU — count up | CU, R, PV | Q, CV |
| SFB1 | CTD — count down | CD, LOAD, PV | Q, CV |
| SFB2 | CTUD — count up/down | CU, CD, R, LOAD, PV | QU, QD, CV |
On S7-1200/1500 the IEC blocks are called TON_TIME / TOF_TIME / TP_TIME / CTU / CTD / CTUD in the Instructions > Timer operations and Counter operations task cards. Their semantics match the A-B TON / TOF / CTU / CTD instructions almost exactly, which makes them the preferred choice for migration projects.
Two IEC timer behaviors to remember:
-
Edge-triggered start. A TON/TOF starts on a rising edge of
IN. IfINis already TRUE on the first scan, the timer does not start. Initialize the timer input from a conditional that produces a clean edge, or callSFB3/SFB4/SFB5withINdriven by a one-shot. -
PT = 0 never passes power. A TON with a preset of
T#0msleavesQ = FALSEforever. S5 timers behaved the opposite way (PT=0 meant "always true"). Always use a positive PT and validate HMI entries for <= 0.
Reading the elapsed time (ET / CV) does not interfere with the running timer. To compute the remaining time, use Remaining := PT - ET in REAL/DINT math. S5 timers require the extra LC (load BCD) and ITD (BCD-to-integer) steps to make the remaining time accessible as a usable number — another reason to standardize on IEC blocks.
8. Organization Blocks (OB) and Startup Behavior
OBs are the entry points the CPU calls; they cannot be called from user code. The most common are:
| OB | Trigger | Use |
|---|---|---|
| OB1 | End of last OB (cyclic) | Main scan |
| OB10–OB17 | Time-of-day interrupt | Scheduled tasks (e.g., hourly report) |
| OB30–OB38 | Cyclic interrupt (S7-300/400) | Deterministic 5/10/20/100/200/500 ms task |
| OB40–OB47 | Hardware interrupt | Fast response to a digital input |
| OB80–OB87 | Error / fault | Default handler; pass through to keep CPU in RUN |
| OB100 | Warm restart (S7-300/400) / startup | Initialize variables, set defaults, write to GDB |
| OB101 | Hot restart (S7-400 only) | Same role, hot-restart semantics |
| OB102 | Cold restart (S7-400 only) | Full re-init of retentive areas |
| OB121 | Programming error | Default handler (often empty) so CPU keeps running |
| OB122 | I/O access error | Default handler (often empty) so CPU keeps running |
The startup OBs (100/101/102) execute once when the CPU transitions from STOP to RUN, before OB1 begins cycling. They are the place to:
- Copy default values into the GDB
Settingsstructure - Initialize edge-detection bits (
s_LastStart := FALSE) - Pre-load recipe parameters from a non-volatile source
- Reset non-retentive counters and production totals
9. User-Defined Types (UDT) for Reusable Structures
A UDT is a user-defined data type, like a struct in C. It can be referenced in the declaration of any DB or FB and it guarantees identical layout across instances. UDTs are the single most effective way to scale a Siemens program from one device to one hundred.
Typical usage — a Motor UDT shared by every motor block:
TYPE UDT_Motor
STRUCT
StartCmd : BOOL;
StopCmd : BOOL;
Running : BOOL;
Faulted : BOOL;
ActualSpeed : REAL;
SetpointSpeed : REAL;
RunHours : DINT;
LastStartTime : DTL;
END_STRUCT
END_TYPE
Reference in a DB:
DATA_BLOCK DB_Equipment
STRUCT
Conveyor1 : UDT_Motor;
Conveyor2 : UDT_Motor;
Conveyor3 : UDT_Motor;
Shared : UDT_CommonSettings; // second UDT for setpoints
END_STRUCT
END_DATA_BLOCK
Reference in an FB's Static area:
FUNCTION_BLOCK FB_Conveyor
VAR
s_Motor : UDT_Motor;
END_VAR
Now an HMI tag like DB_Equipment.Conveyor1.Running is identical in shape to DB_Equipment.Conveyor2.Running. WinCC, TIA HMI, and third-party SCADA systems can use a single tag prefix and an index to address all motors.
UDT edit rule: changing a UDT automatically updates every block that uses it. Always recompile the entire program (not just the changed FB) after a UDT change, and verify IDB sizes in the project tree.
10. Addressing Mode: Symbolic vs. Absolute
Two ways to reference a variable exist:
-
Absolute —
DB1.DBX4.0,MW10,I0.0 -
Symbolic —
Data_Recipe.SpeedSP,Conveyor1.Running
Best practice for new programs: set the project priority to Symbolic in the block-folder properties. This makes the symbol the default, the absolute the fallback, and the ladder editor stops inserting raw DB1.DBX4.0 tags on first use. On TIA Portal V20, optimized blocks enforce symbolic-only access at compile time, so the choice is effectively made for you.
11. Common Errors and Verification Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
| SF LED on; CPU in STOP after download | IDB out of sync with FB declaration | Right-click the FB > Compile > re-download all changed blocks. Delete and re-create the IDB if structure mismatch persists. |
| PUT/GET from S7-1500 to S7-300 returns SF 80A1 | Source DB on S7-1500 is optimized | Open DB attributes > Attributes > uncheck Optimized block access. Recompile and re-download. |
| Online watch shows wrong byte order for an analog value | Source device is little-endian, DB declared as INT | Insert TAW (word swap) or TAD (dword swap) in ladder, or use SWAP in STL. Better: change source to network order. |
Ton with PV=0 never closes Q
|
IEC TON behavior (PT>0 required) | Clamp PV to minimum T#1ms in HMI tag limit, or use TP for one-shot. |
| Timer does not start on first scan | IEC TON is edge-triggered, IN was already TRUE | Reset edge bit in OB100, or feed IN from a one-shot pulse. |
| HMI loses connection to GDB tags | Connection resource exhausted, or access level too low | Check Protection & Security > Connection mechanisms; enable PUT/GET server access for the HMI. |
| Compiling produces "Instance DB cannot be generated" | FB contains an unsupported data type or is recursive | Inspect the FB declaration; ensure no ARRAY of FB (use multi-instance instead) and no PLC-tag-of-PLC-tag. |
12. Migration Checklist: A-B / Logix → S7
For engineers moving from Studio 5000 / RSLogix 5000 to STEP 7 / TIA Portal, the following mapping helps a clean conversion.
| Logix Concept | S7 Equivalent | Notes |
|---|---|---|
| Program Tag (controller scope) | Global DB or Static of a project-wide FB | Prefer GDB for cross-program data |
| Add-On Instruction (AOI) | FB + IDB | One IDB per instance; multi-instance for nested AOIs |
| Subroutine (no state) | FC | Inputs only, no retained memory |
| User-Defined Data Type (UDT in Logix) | UDT | Same purpose, identical layout propagation |
| Produced / Consumed Tags | PUT/GET or BSEND/BRCV across PN/IE | DB must be non-optimized for cross-CPU access |
| Message (MSG) instruction | PUT/GET / BSEND / USEND / TCP native / Modbus blocks | Library: Communication > SIMATIC NET |
| Periodic Task (50 ms) | Cyclic OB (OB30–OB38) on S7-300/400; Cyclic interrupt in TIA | Verify CPU supports the requested phase |
| SFC (Sequential Function Chart) | S7-GRAPH FB | Optional add-on package |
13. Field-Proven Project Layout
For a mid-size machine (one PLC, 10–50 devices, one HMI), the following structure scales cleanly:
- OB1 — calls FB_Line_Control (the master FB) and the standalone FBs for HMI handshake, alarm collection, and recipe handling.
- OB100 — initializes DB_Settings with default values, clears non-retentive counters.
- DB_Settings (GDB, non-optimized for HMI) — recipes, setpoints, machine parameters.
- DB_Production (GDB, retentive) — counters, shift totals, fault history.
- DB_Comm (GDB, non-optimized) — buffers for PUT/GET to subordinate PLCs or drives.
- UDT_Motor / UDT_Valve / UDT_PID — reusable structures.
- FB_Conveyor / FB_Pump / FB_Valve / FB_PID — equipment blocks, each a multi-instance of the master FB_Line_Control or a single-instance with its own IDB.
- FC_Scale_4_20 / FC_Alarm_Format / FC_Linearize_TC — stateless utility routines.
The same UDT_Motor shows up in DB_Equipment for HMI tag prefixing, in the Static of every motor FB, and (if needed) in a Global DB for a section overview panel. One change to the UDT propagates everywhere.
14. References and Standards
Verify behavior against the following official Siemens manuals and standards when implementing these patterns in a certified project:
- TIA Portal V20 — Global Data Blocks (DB)
- SiePortal — Sharing Data Blocks between several S7-1500
- Software Toolbox — How to access Siemens S7 PLC Function and InstanceDB
Should I use a Global DB or an Instance DB for a motor block?
Use an Instance DB. Declare the motor as a Function Block (FB) with Static variables, and call the FB once per motor. The Instance DB is auto-generated with the FB's STRUCT and is the clean way to scale from one motor to one hundred. Reserve Global DBs for cross-equipment settings, recipes, and HMI-visible data that does not belong to a single device.
Why does my TON timer not start on the very first scan?
IEC TON/TOF/TP blocks are edge-triggered. If the input (IN) is already TRUE when the block is first called, the timer does not start. Reset the enable bit in OB100 so the first cycle sees a FALSE-to-TRUE transition, or feed IN from a one-shot pulse generated from FirstScan memory.
Why is my PUT/GET access from another S7-1500 returning an 80A1 error?
The target DB on the source PLC is optimized. Open the DB's Attributes, disable Optimized block access, recompile, and re-download. The DB now exposes absolute offsets that PUT/GET can address. This is the most common cause of cross-PLC DB access faults on S7-1200/1500.
Can I edit the structure of an Instance DB directly?
No. An Instance DB's structure is locked to its parent FB's declaration. To add or modify a variable, edit the FB's interface (VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_STATIC) and recompile. The IDB is regenerated automatically. Direct edits are rejected by the editor to keep the FB and its IDB in sync.
What is the difference between MB0, MW0, and MD0?
They are three views of the same physical bytes. MB0 is the most significant byte of MW0, MB1 is its least significant byte, and MB3 is the least significant byte of MD0. When using MOVE or T instructions, the CPU stores the value according to the target's declared type. Turn off type-checking in the compiler only as a last resort — the runtime byte order is fixed regardless of the editor's tolerance.
How do I retain values across a power cycle?
Mark the GDB or the FB's Static variables as Retain in the block properties. On S7-300/400, the retentivity is also controlled by the CPU's hardware retain area; on S7-1200/1500, declare individual tags as Retain in the IDB/GDB and the CPU stores them in NVRAM. Avoid retaining timers and counters — recompute them on startup from OB100.