Overview: Detecting FB Instance DBs from Inside the FB
In Siemens SIMATIC S7-300 and S7-400 CPUs programmed with STEP 7 (Classic, up to V5.7), every Function Block (FB) call must be backed by an instance Data Block (instance DB, also written as DI or DB-i). When the same FB is invoked multiple times in a project—once for Motor_1, once for Motor_2, once for a proportional valve—each invocation uses its own instance DB so that the static variables of each call retain their own values. The compiled FB code in the CPU is shared; only the data context changes per call.
The engineering problem this reference addresses is: how can the FB itself, while it is executing on the CPU, determine (a) the number of the instance DB that the operating system just opened for it, and (b) optionally the call-up path—the OB/FB/FC and network number from which it was invoked. Item (a) is fully supported by the CPU at runtime through the DINO register. Item (b) cannot be retrieved from the PLC program with standard STEP 7 language constructs; it must be read offline from the cross-reference (XREF) generated by the STEP 7 editor or by TIA Portal.
Target readers: commissioning engineers, PLC programmers writing reusable library FBs, and diagnostic routines that need to log which instance DB triggered a fault.
Instance DB Architecture in S7-300/400
An FB in S7-300/400 has three variable scopes: IN, OUT, IN_OUT, STAT, and TEMP. The first four are persistent and live in the instance DB opened at call time. TEMP variables live on the L stack and are re-initialized on every call. When the OB/FC/FB issues CALL FB10, DB100, the operating system:
- Saves the previous DB/DI register contents on the L stack.
- Loads the DI register with DB100 (the instance DB number).
- Loads AR2 with the start address of the instance data area inside DB100.
- Transfers the call parameters into the IN/OUT/IN_OUT slots of DB100.
- Branches to the FB code.
From this point until the FB exits, any L DINO instruction returns the number stored in the DI register, i.e. 100 in this example. The same mechanism is used by multi-instances, in which case the DI register points to the offset inside the parent instance DB where the local instance was allocated.
For the standard S7-300 CPU family, an FB may be assigned either a single-instance DB or, starting with certain CPUs that support multi-instances, a sub-structure of an existing instance DB. The DI register mechanism works identically in both cases.
The DINO Register: What It Returns and When
DINO is a pseudo-register exposed by the S7-300/400 STL instruction set that mirrors the contents of the DI register (instance-DB register). When executed inside an FB body, L DINO loads the number of the currently open instance DB into ACCU1. If the FB was called without an instance DB (illegal in normal S7-300/400 operation, but theoretically possible if the DI register was zeroed by a programmer), the loaded value is 0.
| Register / Operand | Meaning | Loaded by |
|---|---|---|
DBNO |
Number of currently open global DB | L DBNO |
DINO |
Number of currently open instance DB | L DINO |
AR1 |
Address register 1 (general pointer) | LAR1 |
AR2 |
Address register 2, points into instance DB on FB entry | LAR2 |
Note that DINO is meaningful only inside an FB. Inside an FC or OB, the DI register may contain any residual value from a previous FB call that has not been overwritten. Do not rely on L DINO outside an FB—it is not defined behavior per the STEP 7 programming manual.
The full instruction list for STL is documented in the Siemens Industry Online Support entry "List of STL operations for S7-300/400" (search ID 90801640 in the support portal).
Reading the Instance DB Number with L DINO (STL)
The canonical pattern is to read DINO at the very top of the FB, store it into a TEMP variable, and use that variable for any logging or indirect DB access during the rest of the call.
// Inside FB100, network 1
// Goal: capture own instance DB number for diagnostic logging
L DINO // ACCU1 := DI register (e.g. 120)
T #t_DbNumber // TEMP INT, now equals 120
NOP 0
The value in #t_DbNumber is a 16-bit integer and can be written into a global diagnostic DB, formatted into a string for an HMI alarm, or used as input to OPN DI[ #t_DbNumber ] for indirect instance access. The pattern works in both STL source and in any FB where a single STL network can be inserted, even if the rest of the FB is written in LAD or FBD.
L DINO after opening another DB with OPN DB in the same network—the DI register is unaffected by OPN DB (which only touches the DB register), but the readability of the code is much better when the capture happens in network 1 before any other DB access.Indirect DB Access via OPN DI[ ]
Once #t_DbNumber holds the instance DB number, the FB can perform fully indirect access to its own instance variables or to any global DB using the indexed OPN variants. The relevant STL instructions are:
| Instruction | Effect |
|---|---|
OPN DI[ #t_DbNumber ] |
Open the instance DB whose number is in #t_DbNumber; identical to opening DI normally |
OPN DB[ #anyDbNum ] |
Open any global DB by number |
L DIB 0 / L DBB 0 / L DIW 0 / L DID 0
|
Read instance-DB byte / word / dword at offset 0 |
T DIB 0 / T DIW 0 / T DID 0
|
Write instance-DB byte / word / dword at offset 0 |
Example: a logging FB that wants to read its own FB number and instance DB number into a global diagnostic DB:
// FB "FB_DiagLogger", network 1
L DINO
T #t_instDB // TEMP INT
L "My_FB_Number" // Global constant WORD = 100
T #t_fbNumber // TEMP INT
// network 2: write into global diag DB (DB900)
OPN DB 900
L #t_instDB
T DBW 0 // diagnostic word 0 = instance DB number
L #t_fbNumber
T DBW 2 // diagnostic word 2 = FB number
// network 3: re-open own instance DB to continue normal execution
OPN DI[ #t_instDB ]
The same indirect pattern works for opening any global DB whose number was loaded from configuration:
OPN DB[ #paramDbNumber ] // #paramDbNumber came from IN input
L DBW 10
T MW 200
Limitations: Call-Up Path Cannot Be Read at Runtime
The original question asked two things: (1) which instance DB is assigned to a given FB call, and (2) in which block and network the call was made. Item (1) is solved by L DINO. Item (2) is not solvable at runtime by standard STEP 7 language constructs. The S7-300/400 CPU does not maintain a runtime call stack that the user program can read; the BSTACK (block stack) shown in the online fault diagnostics is built from internal data structures that are not exposed via STL or SCL.
To answer the second part, the engineer must generate and inspect the offline cross-reference (XREF) in STEP 7:
- In the SIMATIC Manager, select Options → Cross-Reference.
- Choose User program as the scope and Used by as the filter.
- Open the FB in the XREF list to see every
CALL FBxlocation and the corresponding instance DB.
For TIA Portal the equivalent is Project tree → right-click the FB → Cross-references, or Show usage from the context menu of an FB call. See the TIA Portal online help entry "Using cross-references" on the Siemens Industry Online Support portal.
DINO, DBNO, or the address registers will fail. AR2 holds the start address of the instance data, not the return address. The block return address is stored internally in the BSTACK and is not accessible to the user program.Detecting the Number of Calls from the FB
Once the FB knows its own instance DB number, it is straightforward to count how many times it has been called by incrementing a word in a global DB keyed by that number. This is a common pattern when the FB must publish a "I am instance N" tag to an HMI.
// FB_DiagLogger, network 10: count calls per instance DB
L DINO
SLD 1 // shift to word alignment for DBW access
LAR1 // AR1 := instance DB number * 2 (byte offset)
OPN DB 901 // global counter DB, 2 bytes per instance
L DBW [AR1,P#0.0]
+ 1
T DBW [AR1,P#0.0]
This produces a histogram in DB901: at byte offset 2 * DB_Number, the integer count of how many times the FB was entered with that instance DB. The CPU 315-2 PN/DP and higher have plenty of work memory for such a diagnostic DB; reserve it in Hardware → CPU Properties → Memory under STEP 7 V5.5+ to avoid later download/online changes.
Multi-Instance DBs (S7-400 and Selected S7-300 CPUs)
STEP 7 V5.x supports multi-instances: a child FB can be declared as STAT of a parent FB, in which case the child's instance data lives inside the parent's instance DB. The DI register mechanism still works. L DINO from inside the child FB returns the number of the parent instance DB, not the offset. To compute the child's offset inside the parent, read the first byte of the child instance via L DID [AR2,P#0.0]—the value is a pointer that can be processed further with LAR1.
Multi-instance capability was originally restricted to S7-400 CPUs; from STEP 7 V5.1 SP3 and CPU firmware V2.x it is also enabled on selected S7-300 CPUs (CPU 315-2 PN/DP, CPU 317, CPU 319). Verify the specific CPU order number (6ES7 315-2EH14-0AB0 etc.) and firmware version in the Siemens Industry Online Support product page before relying on multi-instance in an S7-300 design.
TIA Portal and S7-1200 / S7-1500 Differences
The mechanism above applies to S7-300/400 with classic STEP 7. For S7-1200 and S7-1500 programmed in TIA Portal, the situation differs:
- The
DINO/DBNOSTL registers do not exist in SCL or in TIA Portal STL; the optimized block access model hides them. - Inside an SCL FB,
"MyInstance".MyStaticVarsyntax provides fully direct access without needing the instance DB number. - The instance DB number can still be obtained via the system attribute
{S7_Interface = 'DB'}and the standard functionGET_INSTANCE(SCL) or the system function blockRD_SINFOin S7-1500. - TIA Portal exposes the cross-reference from the project tree; this remains the only way to find the call-up block and network.
For new designs prefer the multi-instance / parameter-instance model in TIA Portal: declare the FB as a STAT of another FB or as an INOUT parameter of type "FB<n>"; the compiler manages the DB number automatically and the call-up path is no longer needed by user code.
Cross-Reference Tool Workflows for Static Analysis
Where runtime detection ends, the STEP 7 cross-reference tool begins. Two workflows are typical:
- Where-used for a single FB — In SIMATIC Manager, right-click the FB and select Where Used (F11). The result lists every block that calls it, together with the network number and the assigned instance DB. This is the only authoritative source for the call-up block and network.
- Cross-reference for the whole program — Options → Cross-Reference produces a tabular report that can be filtered by address, block, or symbol. Save the report as text or CSV for documentation and code review.
For library FBs intended for re-use across many projects, export the XREF of the library project as part of the release documentation. Engineers integrating the library will want to know which instance DBs the library FB will create in their project.
Practical Commissioning Example
The following snippet implements a self-identifying FB that logs its instance DB number and a timestamp into a global ring buffer DB every time it is called. It is appropriate for commissioning diagnostics where many instances of the same FB run in a machine and a fault must be traced to a specific motor or valve.
FUNCTION_BLOCK FB_SelfLog
// =============================================================
// Self-identifying diagnostic FB for S7-300/400
// Compatible with STEP 7 V5.4+, STL or LAD with single network STL block
// =============================================================
VAR
t_instDB : INT; // own instance DB number
t_index : INT; // ring buffer write pointer
END_VAR
VAR_TEMP
s_info : DWORD;
END_VAR
BEGIN
NETWORK 1 // capture identity
L DINO;
T #t_instDB;
NETWORK 2 // advance ring buffer pointer in DB910
OPN DB 910;
L DBW 0; // current write index
+ 2;
L 200; // ring length = 100 entries * 2 bytes
MOD;
T DBW 0; // store new index
SLD 3;
LAR1; // AR1 := index * 8 (each entry = 6 bytes)
NETWORK 3 // write entry: [InstDB INT][Timestamp DWORD]
L #t_instDB;
T DBW [AR1,P#0.0];
CALL SFC 1 // SFC1 READ_CLK, returns system time in PDT format
RET_VAL := #s_info;
L DBD [AR1,P#2.0];
T DBD [AR1,P#2.0]; // store timestamp at offset 2
END_FUNCTION_BLOCK
During commissioning, dump DB910 from the PG to inspect the last 100 calls in chronological order. This is significantly faster than navigating the cross-reference offline when the machine is producing faults every few seconds.
Troubleshooting Matrix
| Symptom | Likely cause | Verification | Resolution |
|---|---|---|---|
L DINO returns 0 inside FB |
FB was called without instance DB (illegal in S7-300/400) or DB register was zeroed by a programmer action | Check the CALL FBn, DBm statement in the calling block |
Correct the call to include a valid instance DB; recompile |
L DINO returns a different DB number than expected |
FB was opened by a multi-instance parent; DINO returns the parent DB | Inspect the parent FB's STAT declaration | Use pointer arithmetic on AR2 if the child offset is needed |
| Indirect OPN DB[ ] faults with SF LED on CPU | DB number is outside the loaded work memory range | Check CPU diagnostic buffer via STEP 7 PLC → Module Information | Reduce the variable holding the DB number; verify the DB is downloaded to the CPU |
| Cross-reference missing a call | Block was changed and not recompiled; XREF is generated against the offline program | Recompile all blocks, re-run Where-Used | Save and recompile the entire S7 program from SIMATIC Manager |
| Cross-reference in TIA Portal does not show instance DB | FB was declared as multi-instance or as a parameter instance; no separate instance DB exists | Open the parent FB declaration | No action needed—instance data lives in the parent DB |
| Code compiles but program crashes at first call | Using DINO outside an FB context |
Move the L DINO line into the FB body only |
Remove the line from FCs/OBs |
| Instance DB changes number after download | STEP 7 reallocated DBs after offline/online block changes | Use PLC → Download User Program to Memory Card instead of partial download | Pin instance DB numbers via Block Properties → Number to keep them stable across downloads |
Safety and Operational Notes
Self-identifying diagnostic logic should be confined to non-safety-critical code paths. On F-CPU variants (S7-31xF, S7-41xF) the F-runtime signature checksums the F-block contents but not the diagnostic FB; nonetheless, keep the diagnostic code out of F-blocks to avoid affecting the safety signature. Standard S7-300 CPUs (6ES7 31x series) and the F-variant (6ES7 31xF series) share the same STL instruction set, including L DINO.
Reserve a contiguous block of instance DB numbers for application FBs (e.g. DB100..DB199) and another range for diagnostic FBs (e.g. DB900..DB999) to make the global diagnostic layout predictable. This convention also makes the ring-buffer DB index arithmetic in the example above straightforward.
What does the L DINO instruction actually load in an S7-300 FB?
The number of the instance Data Block (DI) that the CPU opened for the current FB call. Inside an FB, executing L DINO loads this 16-bit number into ACCU1. It is the only fully reliable runtime way for the FB to know its own instance DB number without parameters being passed in.
Can the FB detect which OB or FC called it?
No. The S7-300/400 CPU does not expose the call-up block or network number to user programs. The block stack (BSTACK) shown in the online diagnostic buffer contains this information, but it is generated from internal CPU structures that are not accessible via STL or SCL. Use the STEP 7 cross-reference tool (Options → Cross-Reference, or right-click → Where Used) for offline detection.
Does L DINO work inside an FC or OB?
It is defined behavior only inside an FB. Outside an FB, the DI register may hold any residual value from a previous FB call. Do not place L DINO in FCs, OBs, or global SCL code; the result is undefined.
How does the S7-1500 / TIA Portal replace this technique?
S7-1500 blocks use optimized access and no longer expose the DI register. Inside an SCL FB, access instance data directly as "Instance".StaticVar. For the instance DB number, use the system function GET_INSTANCE in SCL or RD_SINFO for diagnostic information. The cross-reference is available from the project tree.
Why does my instance DB number change after a partial download?
STEP 7 reallocates DB numbers when blocks are inserted or removed in offline mode. To stabilize instance DB numbers across online changes, open Block Properties → Number and pin the desired DB number, or perform a full download to the memory card instead of incremental online changes.