S5 to S7 Migration: System Flags, TNB and OB31 Conversion Reference
Overview
The Siemens SIMATIC S5 family (S5-90U, S5-95U, S5-100U, S5-115U, S5-135U, S5-155U and the related H/F fail-safe variants) programmed in STEP 5 used a number of language constructs that have no direct equivalent in STEP 7 (S7-300/400) or in TIA Portal (S7-1200/1500). Four recurring obstacles appear during S5 to S7 migration in real STEP 5 source files: (1) the meaning and configurability of reserved system flags S 0.0, S 1.4, and S 28.3; (2) the runtime behaviour of TNB 0 followed by a floating-point comparison; (3) FB calls issued without a parameter list; (4) the legacy error organization block OB 31. This reference documents each construct, identifies what the S5 CPU actually executes, and gives a STEP 7 / TIA Portal migration pattern that preserves the original runtime behaviour.
S5 Memory Areas and the S-Flag Space
STEP 5 segregates bit memory into four addressable areas:
| Area | Symbol | S7 equivalent | Notes |
|---|---|---|---|
| Process input image | I |
I |
Same role; S7 expands to two process images (PII 0 / PII 1) |
| Process output image | Q |
Q |
Same role; S7 expands to two process images (PIQ 0 / PIQ 1) |
| Flags (work flags) | F |
M |
S5: 2048 bytes standard; S7: 4096 bytes typical on S7-300/400 |
| System flags | S |
no direct area | Driven by the S5 operating system; must be replaced with software timers / counters |
| Timers | T |
IEC_Timer DBs |
S5: 256 timer words; S7-300/400: 256/512 timers; S7-1200/1500: unlimited IEC instances |
| Counters | C |
IEC_Counter DBs |
S5: 256 counter words; S7: same upper bound on S7-300, unlimited on S7-1500 |
| Data words | D |
DB |
S5: 256 DBs of 256 words; S7: 65535 DBs (CPU-dependent) |
The system flag area (S) is the one that causes the most confusion during conversion. Unlike F, the S area cannot be written by the user program; the operating system updates selected bits at fixed rates, and a few bits are tied to communication processors or special-function groups. When the STEP 5 source comments a system flag (e.g. "1 s generator" on S 0.0 or "1 minute generator" on S 1.4) the comment is documentation - the bit toggles at the period the OS assigns.
System Flag Assignments by CPU Family
Only a subset of the 256 system flag bits has a published meaning. The assignments vary by CPU family. The table below lists the most commonly referenced bits:
| Bit | S5-95U / S5-100U | S5-115U (CPU 941-944) | S5-135U / S5-155U |
|---|---|---|---|
| S 0.0 | clock generator (period depends on CPU subtype) | clock generator (period depends on CPU subtype) | clock generator (period depends on CPU subtype) |
| S 0.1 | clock generator | clock generator | clock generator |
| S 0.2 | clock generator | clock generator | clock generator |
| S 0.3 | clock generator | clock generator | clock generator |
| S 0.4 | clock generator | clock generator | clock generator |
| S 0.5 | clock generator | clock generator | clock generator |
| S 0.6 | clock generator | clock generator | clock generator |
| S 0.7 | clock generator | clock generator | clock generator |
| S 1.4 | application-specific | application-specific | may be assigned to special-function group |
| S 28.3 | application-specific | application-specific | may be assigned to special-function group |
S 0.0 as "1 s generator" and S 1.4 as "1 minute generator". The exact period depends on the S5 CPU type and sometimes on the CPU firmware build. The S5-115U CPU 941/942/943/944 manuals list the published clock-generator periods, but they do not always include 1 s on S 0.0 or 1 minute on S 1.4. Treat the comment as a project-specific documentation hint rather than a documented CPU fact, and verify against the CPU manual before assuming a bit toggles at the named period.Replacing S-Flag References in STEP 7
Three replacement strategies exist, in increasing order of safety:
-
Direct substitution with a software clock generator. Use
S_PULSE(S7-300/400) orTP(S7-1200/1500) with the required period and a self-reset rung to emulate the toggling bit. This is the most common choice when the original program pollsS x.yas a 50% duty-cycle clock. - Edge-triggered replacement. If the original program reads the bit only on its positive edge, drop the substitution entirely and use a single-shot pulse block triggered by an IEC timer.
- Hardware replacement with a real-time clock. If the program depends on wall-clock minute boundaries, read the CPU clock and compare in the cyclic OB - the S5 S-flag system was never intended for minute-of-clock behaviour.
For the bit S 28.3 specifically, no CPU manual documents a clock function on this bit. The S5-115U and S5-135U manuals list only a handful of named system flags; everything else is application-specific. When converting a reference to S 28.3:
- Search the original S5 program for any write to
S 28.x- the S5 OS does not write system flags, so a write must be a compiler artifact and any read of the same bit is undefined. - If no write exists, treat the read as dead code or as a stale bit carried over from an older project.
- If the bit truly affects process behaviour, replace it with an
M-flag (memory flag) and update both the producer and the consumer of the bit during conversion.
The TNB Statement Family
STEP 5 provides three block-transfer statements:
| Statement | Operand size | Use |
|---|---|---|
TNB |
byte | copy a string of bytes between two memory areas |
TNW |
word | copy a string of words (each word = 2 bytes) between two memory areas |
T |
word | copy one word |
All three use the same accumulator convention. Before the statement runs, the CPU expects:
- ACCU 2 (full 32 bits): source address (where the data is read from)
- ACCU 1 (low word only): destination address (where the data is written to)
-
ACCU 1 (right byte): number of bytes / words to transfer (constant if the explicit form is used, e.g.
TNB 5, otherwise taken from ACCU 1-L)
The explicit-constant form TNB <n> loads n into ACCU 1-L automatically. When the destination is the only accumulator reference (e.g. when DO FW or DO DW was used previously to compute the source) the source is taken from ACCU 2-L.
TNB 0 - The Zero-Byte Copy
The statement TNB 0 is legal STEP 5 syntax. The CPU loads 0 into ACCU 1-L, then runs the transfer routine with a count of zero. The result is:
- No bytes are copied between the source and destination pointers.
- The condition code is set according to the transfer result - because all zero requested bytes were "transferred" (trivially), CC1 = 0 (no overflow).
- ACCU 1 and ACCU 2 are otherwise unchanged.
The user's source shows the typical idiom that follows TNB 0:
L FY 255 ; ACCU1-L = byte from flag area
TNB 0 ; zero-byte transfer (no memory effect)
>=F ; 32-bit floating-point compare ACCU2 vs ACCU1
JC =M001 ; jump if ACCU2 >= ACCU1
A =#MAX ; load formal parameter "MAX"
S F 201.4 ; set flag 201.4
The interesting instruction here is the >=F comparison. Because TNB 0 does not touch the accumulator contents except for the implicit count load, >=F compares the value in ACCU 1 against whatever was in ACCU 2 at the start of the network. Since L FY 255 loads a single byte into the low byte of ACCU 1-L and zero-extends the high byte, the floating-point interpretation of ACCU 1 depends on the previous load history.
L KB 13 leaves ACCU 1 = 13, then the next L pushes 13 into ACCU 2 and loads ACCU 1 fresh), the comparison yields a meaningful boolean. If ACCU 2 contains a non-float bit pattern from a previous load (e.g. a counter word), the >=F instruction computes nonsense. Always reconstruct both operands before trusting a TNB-based comparison.Tracing the User's Segment 2
Reading back to the immediately preceding segment:
SEGMENT 1:
:L FY 255
:L KB 13
:<F
:R F 202.5
:JC =M001
:T FY 255
:S F 202.5
:R F 254.0
:***
The segment flow:
-
L FY 255pushes the current byteFY 255into ACCU 1, moving the previous ACCU 1 into ACCU 2. -
L KB 13pushes13into ACCU 1, moving the previously loaded value into ACCU 2. -
<Fcompares ACCU 1 vs ACCU 2 as 32-bit float. ACCU 1 =13.0, ACCU 2 = float(previous FY 255). Result boolean(13 < ACCU2). - If ACCU 1 < ACCU 2,
R F 202.5clears the flag. ThenJC =M001jumps to M001. - Otherwise (ACCU 1 >= ACCU 2), control falls through, transfers the new value to FY 255, sets F 202.5, clears F 254.0.
Segment 2 then executes with ACCU 2 still holding 13.0 (from the last L KB 13), and ACCU 1 freshly loaded with the new FY 255 (which is also 13 after the previous transfer). The comparison FY255 >= 13.0 evaluates to true on every scan after the first time the conditional path executed, and JC =M001 always fires. This is dead code in the long run; during S5 to S7 migration you can replace the entire segment with a direct conditional set on F 201.4.
STEP 7 Equivalent
// Migration of the user's Segment 2 to STEP 7 STL
L "FY255" ; load the byte (now M 255 or a renamed flag)
L 1.300000e+001 ; explicit constant 13.0
>=R ; 32-bit real compare (replaces >=F)
JC M001
U "MAX" ; instance-DB or local variable
S "F201_4" ; map to M 201.4 or a renamed flag
Note the explicit double L sequence - the S7 compiler refuses an >=R if only one operand is loaded, so the conversion forces the second L to appear where the S5 code relied on accumulator inference.
FB Calls Without Parameter List
STEP 5 function blocks are declared with a parameter header of the form:
:SPA FB 100 // (or :SPB FB 100 symbolic)
NAME : MYBLOCK
A : IN1
E : OUT1
D : STATE
B : MODE // (B = formal parameter, BYTE type)
TIMER : TMR1
COUNT : CTR1
The header is parsed once at FB-generation time. The parameter names are stored in the FB body and the instance DB is sized to match. At call time, STEP 5 expects the call site to supply actual parameters:
:SPA FB 100
A =I 0.0 // actual = I 0.0 for IN1
E =Q 8.0 // actual = Q 8.0 for OUT1
D =DW 10 // actual = DW 10 for STATE
B =FY 200 // actual = FY 200 for MODE
TIMER =T 1 // actual timer T 1
COUNT =C 5 // actual counter C 5
If the call site omits one or more lines, STEP 5 still compiles the program and runs the FB. The omitted formal parameters take whatever value the instance DB contained from a previous call - effectively the FB runs with stale state. This is rarely intentional and usually the result of incomplete editing in the original S5 project.
STEP 7 Compiler Behaviour
STEP 7 (and TIA Portal) refuse such a program at compile time. The error messages are:
- STEP 7 V5.x: "FB xyz: Aufrufparameter unvollständig" ("Call parameters incomplete")
- TIA Portal V15+: "The call of FB xyz does not have a complete parameter list"
Migration Options for an Incomplete FB Call
- Complete the parameter list from the FB header. Open the original FB in STEP 5, read the formal parameters at the top of the source, and copy them into the call. For each omitted parameter, supply a default (0 for numeric types, FALSE for booleans, an empty string for STRING, T#0ms for timers, C#0 for counters).
- Pre-load the instance DB with defaults in the startup OB. In S7-300/400 OB 100 or TIA Portal startup OB, transfer the same DB defaults that the original S5 instance DB would have contained at first run. The FB then sees stable inputs as in STEP 5.
- Rewrite the FB to read memory directly. Replace each formal parameter read with a direct memory reference (M-flag, DB, or input image). This option is most invasive but yields the cleanest TIA Portal code and removes the FB call signature entirely.
OB 31 - Special Function Group Error
The organization block OB 31 exists only in the higher-end S5 CPU families (S5-135U, S5-155U, S5-155H). It is invoked by the operating system when an error is detected in the special-function group - for example a hardware fault on a communication processor (CP) or a failure in the coordinated task layer. The OB is optional; if the program does not contain an OB 31, the CPU enters STOP on the first occurrence of the underlying error.
STEP 7 / TIA Portal has no 1:1 replacement. The S7 organization block hierarchy is different:
| S5 construct | S7 candidate | Purpose |
|---|---|---|
| OB 31 - special function group error | OB 80 - time error | Cyclic watchdog, OB run-time overrun |
| OB 121 - programming error | Indirect addressing fault, type error | |
| OB 122 - I/O access error | Missing module, I/O fault during access | |
| OB 85 - priority class error | OB not loaded, update of PI when OB missing | |
| OB 86 - rack / station failure | PROFIBUS DP slave lost, rack removed | |
| Manual watchdog retrigger inside OB 31 | SFC 43 / SFB 33 "RE_TRIGR" | Restart the S7 cyclic watchdog timer |
Mapping the OB 31 Pattern
The user's source sets a single bit inside OB 31 and uses it elsewhere as a condition. To migrate:
- Read the OB 31 source in STEP 5 and identify the bit that is SET (e.g.
S F 254.0). - Decide whether the bit is read only inside OB 31 (in which case you can delete it) or outside (in which case it must be replicated).
- Map the bit to a memory flag, an instance-DB bit, or a global DB bit in S7.
- Place the
Sinstruction inside the appropriate S7 OB - typicallyOB 121for programming errors,OB 80for time errors. The OB must be loaded into the S7 CPU firmware image; missing OBs cause the CPU to STOP on the first occurrence of the underlying error. - If the original S5 program relied on OB 31 to reset the cyclic watchdog, add
CALL SFC 43(S7-300/400) or a call toRE_TRIGRin the replacement OB.
// OB 121 (Programming error) replacement for the user's OB 31
SET ; RLO = 1
S "S5_OB31_Bit" ; the bit formerly set inside OB 31
SAVE ; preserve RLO to BR
Putting It Together - S5 to S7 Conversion Order
When converting a STEP 5 program to STEP 7 / TIA Portal, apply the following order to minimise re-work:
- Translate the S5 program using the STEP 7 Migration Tool (or the older S5 to S7 Converter) for an STL pass. The tool documents unsupported constructs in a log file.
- Resolve each
S-flag reference by mapping to the documented S5 clock generator or to a user flag. - For every
TNB <n>, determine whethernis a runtime variable. Ifn = 0, decide whether the surrounding comparison is meaningful. - For every FB call, complete the parameter list. Use the FB header from the original S5 source as the master.
- For every OB 31 reference, choose a destination S7 OB based on the underlying error class. Add the new OB to the S7 CPU hardware configuration so it is loaded into the firmware image.
- Run the STEP 7 compiler and resolve all remaining errors.
- Download to the S7 CPU and monitor with the online watch table.
- Run the verification checklist below.
Verification Checklist
| Check | Method | Pass criterion |
|---|---|---|
| Clock generators replaced with software timers | Watch table cross-check vs S5 online values | Identical period and duty cycle |
| TNB 0 comparisons resolved | Single-step with break-point on the comparison | CC1 bit matches S5 behaviour |
| FB parameter defaults match instance DB | Online dump of instance DB vs S5 instance DB | Byte-for-byte identity after first scan |
| OB 31 replacement OB exists in the CPU | Hardware configuration check | OB loaded, priority set, no STOP on first trigger |
| Watchdog retrigger present | Search the program for SFC 43 / SFB 33 calls | Found in every cycle where OB 31 originally was used to reset the watchdog |
| System flags fully replaced | Cross-reference search for the byte S
|
No remaining references |
| Data area remapping complete | Cross-reference search for F, D
|
All references migrated to M / DB
|
Common Pitfalls During Conversion
-
Implicit accumulator results. STEP 5 lets you skip the second
Lbefore a comparison if the previous segment left the right value in ACCU 2. STEP 7 insists on both operands. Missing the secondLproduces a compiler error, not a runtime warning. - FB multi-instance DBs. STEP 5 used a single instance DB per FB. STEP 7 multi-instance model allows a single DB to back several FB calls; the conversion tool sometimes generates a single instance DB per call site, which inflates memory. Consolidate after conversion.
- Timer / counter area differences. S5 has a fixed pool of 256 timer words and 256 counter words. S7-300/400 also has fixed pools (256/512 depending on CPU). S7-1200/1500 has no fixed pool - timers and counters are IEC instances. Migrate S5 timer/counter references to IEC blocks when moving to S7-1200/1500.
-
Byte vs word addressing. S5
FY 255reads byte 255 from the flag area. S7MB 255reads byte 255 from the memory area. If the original S5 code usedFW 255(word) it reads bytes 255 and 256 in big-endian order. STEP 7 is little-endian, so the same word address gives a different numeric value. Always check the byte order during conversion. - Absolute vs symbolic addressing. S5 allowed mixed absolute / symbolic references inside one network. STEP 7 / TIA Portal disallows mixing in some configurations. Standardise on either absolute or symbolic addressing after conversion.
- OB priority levels. S5 OB priorities were fixed by OB number. S7 OB priorities are configured in the hardware configuration. The S5 OB 1 (cyclic) had priority 1; the equivalent S7 OB 1 also has priority 1 by default but is configurable. Verify the priority mapping.
Recommended STEP 7 / TIA Portal Migration Settings
For a clean conversion:
- Use STEP 7 V5.7 (or TIA Portal V18+) as the destination environment. Earlier STEP 7 versions do not support some S5 statement forms.
- Select "Compile STL after conversion" so the compiler reports every missed construct immediately.
- Set the destination CPU firmware build to the latest available for the chosen S7 model. Newer firmware builds support more IEC blocks and more OB types.
- Enable the "Generate instance DB per FB call site" option if the S5 program called the same FB from multiple sites with different actual parameters.
- Disable the "Optimise block access" option on data blocks during initial conversion. Once the program runs, enable it block-by-block and re-verify.
FAQ
What does S 0.0 do in a Siemens S5 program?
S 0.0 is one of the system-flag clock generator bits driven by the S5 operating system. The exact period depends on the CPU type (S5-95U, S5-100U, S5-115U, S5-135U, S5-155U); the user comment in the source file labels it as a "1 s generator" but the S5-115U CPU 941/942/943/944 manuals list the published clock periods and may not match that comment. Treat the bit as a clock signal and replace it with an IEC timer block (TP / S_PULSE) during S5 to S7 migration.
What does TNB 0 actually do in STEP 5?
TNB 0 is a zero-byte block transfer. No memory is copied, but any floating-point comparison that follows (e.g. >=F) uses whatever values remain in ACCU 1 and ACCU 2. The instruction is sometimes used as a structural marker or as a no-op that preserves the previous accumulator state; you should reproduce the comparison operands explicitly in STEP 7.
Can a STEP 5 FB be called without a parameter list?
Yes. STEP 5 allows it because the FB header is bound to the instance DB at FB-generation time, not at call time. The omitted parameters take the value already present in the instance DB from a previous call. STEP 7 / TIA Portal refuses the missing parameters - you must either add the parameter list to the call, pre-load defaults in OB 100, or rewrite the FB to read memory directly.
How do I replace OB 31 in S7?
Map the original S5 OB 31 to the closest S7 organization block - typically OB 80 (time error), OB 121 (programming error), OB 122 (I/O access error), or OB 86 (rack failure) depending on the original OB 31 trigger source. Place the OB 31 instructions in the new OB, add the OB to the CPU hardware configuration, and call SFC 43 / SFB 33 "RE_TRIGR" if the original program needed to retrigger the watchdog.
Why does the S5 comparison >=F after TNB 0 always jump to M001 in my segment?
Because ACCU 2 still contains the value loaded before TNB 0 (from the previous segment, here L KB 13) and ACCU 1 is loaded with the same FY 255 byte that was just transferred. The two values are typically equal, so the result of the 32-bit floating-point comparison is "greater-or-equal" and the jump is taken every scan. Replace the comparison with a direct conditional set in STEP 7 and verify with a watch table.