1. Overview: The S5 to S7 Migration Problem
When you convert a Siemens SIMATIC S5 program that uses BS 60 references and OB 160 calls, the STEP 7 / TIA Portal converter either flags the statement as a syntax error or generates a SF (System Fault) on the S7 CPU at the first execution. The reason is architectural: BS (system status) registers and the variable time-loop OB 160 are S5-115U hardware features that have no direct equivalent in the S7-300 / S7-400 / S7-1500 register set. A successful migration requires understanding what the original S5 instructions did at the silicon level so the behavior can be re-implemented with S7-300 instructions.
The example below shows a typical migration task. The source is a SIMATIC S5-115U STL program that performs a counted block transfer with a per-iteration delay. The destination is a STEP 7 V5.x or TIA Portal STL program for an S7-300 CPU (for example, CPU 315-2 PN/DP, order number 6ES7315-2EH14-0AB0 or later).
SF and a diagnostic buffer entry such as OB not loaded or not possible (event ID 0x8001 in STEP 7 classic diagnostic buffer format).2. BS Registers in S5-115U: Why They Don't Exist in S7
BS in S5-115U nomenclature refers to the system status byte area of the operating system. BS 60 is the 61st byte (zero-indexed) of the internal system data area. It is not a freely usable marker; its meaning depends on the operating mode of the CPU and on the bus peripherals configured. In an S5-115U CPU that has a SINEC L1 slave interface configured, BS 60 carries the address of the CBS (Coordination Byte Send) used by the L1 protocol handler. Other BS bytes serve the scan-time accumulator, the interrupt stack, and the process-image update flags.
The S7-300 / S7-400 / S7-1500 architectures eliminated the BS area in favor of:
- The local stack (L stack) for block-private temporaries.
- The process image of inputs (PII) and outputs (PIQ) for I/O consistency.
- System status lists (SSL) queried with SFC 51
RDSYSST(S7-300/400) or withRD_SINFO/RDRECon S7-1500. - Direct I/O access (I/O area with
:Pqualifier) for time-critical access outside the process image.
There is no BS area in S7 and there is no global mapping. If your S5 source touches BS 60, locate the original intent in the S5-115U manual and re-implement it with a system function or a hardware-aware user program. The Siemens Industry Online Support portal hosts the legacy S5-115U manual (entry search by order number 6ES5 998-xABxx) and is the authoritative source for the BS mapping.
3. OB 160: Variable Time Loop on the S5-115U
OB 160 on the S5-115U (CPU 941, 942, 943, 944 family) is a Variable Time Loop provided by the operating system to generate a CPU-independent wait time. From the S5-115U instruction list:
OB 160 simulates operation execution times. This makes you independent of the different operation execution times of the various CPUs and you can program wait times uniformly for all CPUs of the S5-115U range. The waiting time must be loaded into ACCU 1 in microseconds. Range: 120 to 65535 (78H to FFFFH).
Example from the S5-115U manual:
L KF +1000 // Load 1000 us (1 ms) into ACCU 1
JU OB 160 // Wait 1 ms, then return
The S7-300 family does not provide an OB 160. Time-based waits in S7 are produced with:
| Mechanism | Use Case | Typical Precision |
|---|---|---|
| IEC timers SFB 4 / SFB 5 (TON, TOF) | Standard on-delay / off-delay | 1 ms tick base (S7-300) or 1 ms times multiplier |
| SFC 47 "WAIT" | CPU-busy wait, ms-granular | 1 ms (S7-300) / 100 us (S7-1500) |
| OB 1 cycle-time accumulator + flag | Loop-body delay via cycle counting | One OB 1 cycle (1-10 ms typical) |
| Time-of-day / hardware timer (SFB 1, or S5TI_TIM via the S5 migration tool) | Reuse of S5 timer semantics | 10 ms base on the S5 timer area |
For the per-iteration delay in a counted block-move loop, the S5 OB 160 inside the loop is almost always a workaround for the S5-115U scan-time variation between the 941 / 942 / 943 / 944. On S7-300 the cleanest replacement is SFC 47 "WAIT" with a microsecond-equivalent wait parameter. If the original 1 ms wait is non-critical, you can usually drop it entirely because the S7-300 OB 1 cycle is bounded and the modern scan-time jitter is far smaller than on the S5-115U range.
4. Decoding the Original S5 STL Source
The two S5 networks in the source perform a counted data-block-to-data-block word copy. The parameter interface is implicitly defined by the function block header (not shown) and exposes:
-
#_DB- target data block number (AUF #_DB opens the DB). -
#DW- first target data word (offset in 16-bit words, written to MW 220). -
#ANZ- number of words to copy (loop counter, written to MW 220 as a seed and incremented each pass). -
#WERT- per-iteration value placed into MW 222 (the loop body writes#WERTindirectly through AR1).
The loop body in Network 2 saves ACCU 1, ACCU 2, and the status word around an indirect store, increments the pointer, and continues until the counter rolls over. The body also calls OB 160 (the line flagged // CALL OB 160; Need to be replace), which is the only statement in the loop that has no S7 equivalent. The SPB M001 branch uses RLO set by the preceding INC 1 to loop while the counter is still non-zero.
Once you understand that intent, the BS 60 reference disappears from the conversation: BS 60 is not touched directly by this snippet, but the S5-115U system code may be using BS 60 internally for the L1 CBS pointer, which is why the snippet is referenced in a migration context. The S7-300 port should not contain any BS reference and should re-implement only the documented user intent of the loop.
5. S5-to-S7 STL Opcode Translation Table
The snippet uses only S5-115U STL operations. The following table maps each to STEP 7 V5.x / TIA Portal STL on the S7-300. The mnemonics shown are German (default for S5); STEP 7 also supports English, but the converter preserves the German form, so it is useful to read both.
| S5 Mnemonic | English S5 | S7-300 Equivalent | Notes |
|---|---|---|---|
AUF #_DB |
CDB |
OPN DB [#_DB] |
Open a data block. S7-300 allows OPN DB with a 16-bit word operand from CPU 31x firmware V2.0 onward; older firmware requires LAR1 and OPN DB [AR1,P#0.0]. |
L #DW |
L #DW |
L #DW |
Local interface variable load. Identical in S7 FB/FC parameter interface. |
T MW 220 |
T MW 220 |
T MW 220 |
Marker word store. Identical in S7, but global M is non-re-entrant; re-bind to TEMP for IEC 61131-3 compliance. |
T MW 222 |
T MW 222 |
T MW 222 |
Identical semantics, same re-binding caveat. |
TAK |
TAK |
TAK |
Swap ACCU 1 / ACCU 2. Identical. |
L STW |
L STW |
L STW |
Load status word. Identical. |
L MB 221 |
L MB 221 |
L MB 221 |
Identical. |
SLW 4 |
SLW 4 |
SLW 3 |
Shift left word. On S5-115U the 4-bit shift converts a word index to a packed byte address. On S7-300, the canonical conversion is SLW 3 (word index x 8 bytes). See Section 8. |
LAR1 |
LAR1 |
LAR1 |
Load AR1 from ACCU 1. Identical. |
L #conv_akku1 |
L #conv_akku1 |
L #conv_akku1 |
In/out parameter on FB. Identical once the S5 STAT variable is mapped to a TEMP/STAT on the S7 FB. |
T DBW [AR1,P#0.0] |
T DBW [AR1,P#0.0] |
T DBW [AR1,P#0.0] |
Indirect DBW write via AR1. Identical syntax in S7-300. |
INC 1 |
INC 1 |
+ 1 (or INC 1 where supported) |
STEP 7 replaces INC with the + arithmetic operator. The semantics of "increment ACCU 1 by 1" are preserved. Note that + does not set RLO; a separate <I test is required to drive a conditional jump. |
SPB M001 |
JC M001 |
JC M001 |
Conditional jump if RLO = 1. S5 SPB = S7 JC. |
JU OB 160 |
CALL OB 160 |
Replace with CALL SFC 47 with the wait parameter in microseconds, or remove if not functionally required. |
See Section 3. |
JU FB / JU OB / JU PB / JU SB |
CALL FB / CALL OB / CALL PB / CALL SB |
CALL FB / CALL FC / CALL OB / CALL SFB / CALL SFC |
S5 PB/SB blocks must be converted to FC/FB on S7; the S5 conversion tool can re-parse most PB into FCs. |
BS xx |
n/a | No equivalent | Resolve by reading the S5-115U manual and re-implementing intent with SFC 51 RDSYSST, SFC 20 BLKMOV, or PROFIBUS DP I/O. |
6. Building the S7-300 Replacement Architecture
Two practical replacement strategies are available. Choose based on the S5 block type you are converting.
6.1 Strategy A: Re-implement as a System Function (FC) wrapper
Best for PB (program blocks) and SB (step blocks) that contain a self-contained copy routine. Encapsulate the loop in an S7-300 FC with the same parameter interface as the original S5 PB. Use marker words (MW 200..MW 254) for the loop counter and the pointer seed, or pass them as IN/OUT parameters and let the caller allocate them in an instance DB.
6.2 Strategy B: Lift the snippet into an FB with multi-instance capability
Best when the loop body is one of several copy operations in a larger S5 FB. The S5 parameters #conv_akku1, #conv_akku2, #conv_stw are already FB STAT/TEMP variables; re-create them as TEMP in the S7 FB and assign them via a STAT block of the multi-instance DB. The S7 FB multi-instance model is the cleanest target for re-entrancy: every OB that calls the FB gets its own static state.
For both strategies, define a clean interface:
| Parameter | Direction | Type | Original S5 | S7-300 |
|---|---|---|---|---|
i_DB |
INPUT | WORD / INT | #_DB |
DB number to open |
i_DW |
INPUT | WORD / INT | #DW |
First target DW |
i_ANZ |
INPUT | INT | #ANZ |
Number of words to copy |
i_WERT |
INPUT | WORD / INT | #WERT |
Per-iteration value |
i_WaitMs |
INPUT | INT | (none, implicit in OB 160) | Optional per-iteration wait in ms (0 = no wait) |
o_status |
OUTPUT | WORD | (none) | Return value: number of words actually written, or a status / error code |
Marker words MW 220, MW 222, MB 221 used in the S5 source must be replaced with TEMP variables in the S7 FB, not with the global bit memory (M) area, to keep the routine re-entrant and IEC 61131-3 compliant. Re-entrancy is essential: the S5-115U has no multi-instance concept, but the S7-300 OB priority model (OB 1, OB 35, OB 40, ...) can call the same FB concurrently, and global M will be clobbered if you do not re-bind.
7. Network 1 Replacement in STEP 7 STL
The S5 Network 1 sets up the pointer seed (MW 220) and the value (MW 222) before entering the loop. The S7-300 equivalent:
// S7-300 STL, Network 1 - setup
// Replaces S5 Reseau 1: AUF #_DB; L #DW; T MW 220; L #ANZ; T MW 222
OPN DB [#i_DB] // Open target data block
L #i_DW // Load first DW offset
T #t_ptr_seed // Save as loop pointer seed (TEMP WORD)
L #i_ANZ // Load count
T #t_counter // Save as loop counter (TEMP INT)
L #i_WERT // Load per-iteration value
T #t_value // Save for the loop body
Notes:
-
OPN DB [#i_DB]accepts a 16-bit operand on S7-300 (CPU 31x) as of firmware V2.0. For older CPU 312 / CPU 313 with firmware V1.x, the DB number must be loaded into ACCU 1 first and the indirect formOPN DB [AR1,P#0.0]used afterLAR1. - All markers
MW 220/MW 222are now TEMP variables#t_ptr_seed/#t_value. The instance DB carries them per call. - If the FB is configured with optimized block access (the default in TIA Portal from V13 onward), indirect access to instance data via AR1 must use the AR2-based standard access path; either disable optimized access for this FB, or pass the data via a global DB that you control with a fixed layout.
8. Network 2 Loop Replacement in STEP 7 STL
The S5 loop body saves ACCU 1, ACCU 2, and the status word, computes the byte offset, performs the indirect store, increments the pointer, and loops. In S7-300, two implementation choices are common. The literal translation follows:
// S7-300 STL, Network 2 - loop body
// Replaces S5 Reseau 2: ... SPB M001 ; with OB 160 removed
M002: NOP 0
L #t_value // Load per-iteration value
T #t_akku1 // Save ACCU 1 (was #conv_akku1)
TAK // Swap ACCU 1 / ACCU 2
T #t_akku2 // Save ACCU 2 (was #conv_akku2)
L STW // Load status word
T #t_stw // Save status word
// Build byte pointer: word offset to byte address
L #t_ptr_seed // Pointer seed (16-bit word offset)
SLW 3 // Convert word offset to byte offset
LAR1 // AR1 := byte pointer
L #t_stw
T STW // Restore status word
L #t_akku2
L #t_akku1
T DBW [AR1, P#0.0] // Indirect write into target DB
// Increment pointer seed (16-bit word units)
L #t_ptr_seed
+ 1
T #t_ptr_seed
// Increment and test loop counter
L #t_counter
+ 1
T #t_counter
L #t_counter
L #i_ANZ
<I // S7-300: ACCU 2 < ACCU 1 ?
JC M002
Three important corrections versus a literal S5-to-S7 line-for-line translation:
- The S5 snippet shifts the byte pointer left by 4 (
SLW 4) and usesLAR1. In S5-115U bit-memory addressing, that effectively converts a 16-bit "data word index" to a byte address. In S7-300 the canonical conversion isSLW 3(left-shift by 3 multiplies the word index by 8 bytes per word). The extraSLW 1in the S5 source corresponds to the 115U's byte-into-word packing; S7 stores data block words in pure byte addressing, so the shift count changes. - The S5
SPB M001uses RLO from theINC 1operation:INCsets RLO when the result is non-zero, so the loop continues while the counter is non-zero. The S7 replacement tests the counter directly with<I/JCbecause STEP 7's+instruction does not set RLO. The S7 idiom is the most common and the easiest to read at the maintenance stage. - If a per-iteration wait is functionally required (per Section 3), insert
CALL SFC 47with a wait time in microseconds immediately before theJC M002branch:
L #i_WaitMs // e.g., 1 (1 ms)
ITD
SLD 3
CALL SFC 47 // WAIT
IN: WT
L #t_counter
L #i_ANZ
<I
JC M002
SFC 47 documentation: SFC 47 "WAIT" pauses the user program for the number of microseconds passed in WT (range 1 us to 32767 us on S7-300, 100 ns to 1 s on S7-1500). A 1 ms wait is more than the S7-300 SFC 47 minimum, so pass WT := 1000 (microseconds). The CPU remains in RUN, OB 1 cycle time grows by exactly the wait amount, and the time-interrupt OBs (OB 30..OB 38) are not serviced during the wait. If the loop must remain interruptible, replace SFC 47 with an OB 35 cycle-tick counter or an IEC timer.
9. The CBS Coordination Byte on SINEC L1
If the original S5-115U was used as a SINEC L1 slave, BS 60 carried the address of the CBS (Coordination Byte Send) used by the L1 protocol handler. The S5-115U manual (CPU 941 to 944 family) documents this in chapter 12.2.3. On S7-300, the SINEC L1 interface is no longer present. The migration path depends on what the higher-level system expects:
| Original S5-115U + L1 Topology | S7-300 Replacement | Notes |
|---|---|---|
| L1 master, multiple S5 slaves | PROFIBUS DP master (CPU 31x with DP port) talking to S5-95U slaves (or migrated slaves) | Use SFB 52 / SFB 53 RDREC / WRREC in place of L1 coordination bytes. The S5-95U can act as a DP slave with a stock GSD file. |
| L1 slave, the program reads/writes the CBS pointer at BS 60 | PROFIBUS DP slave, exchange data via the S7-300 DP slave interface (GSD / GSDML) | Drop the BS 60 pointer logic; the DP master sets the input image directly into the S7-300 process image. |
| Standalone S5-115U, no L1 traffic, BS 60 unused | No equivalent needed; remove the BS 60 reference entirely | Verify the original program does not touch BS 60 indirectly via system blocks (FY 60 / FY 61 on the S5-115U sometimes alias BS 60). |
| Point-to-point link via L1 to a third-party device | Serial interface (CP 340 / CP 341 / CP 440 / CP 441) or PROFINET IO | Use the PtP parameter assignment tool to set up the protocol on the CP. |
If you are uncertain whether the L1 interface is active, the S5-115U manual chapter 12.2.3 lists the system data area assignments. On S7-300, no byte behaves like BS 60. The closest S7-300 analogy is the SSL (system status list) partial list 0x0019 / 0x0119, which returns Communication status information. Query with SFC 51 RDSYSST if the original program used BS 60 for diagnostics. The S7-300 SFCs are documented in the Siemens Industry Online Support portal under entry "Standard and System Functions for S7-300/400."
10. CPU 941-944 Reference Matrix and Chapter 12.2.3
The S5-115U CPU family covered by the S5-115U manual (chapter 12.2.3) is summarized below. Use this table to confirm which CPU your original program targeted before you port the BS 60 logic.
| CPU | Order Number (S5-115U) | Scan Time Reference | OB 160 Available | BS 60 / CBS Role |
|---|---|---|---|---|
| CPU 941 | 6ES5941-7UB11 | 70 ms / 1 K AWL operations | Yes | Standard: scan-time accumulator. L1 slave: CBS pointer. |
| CPU 942 | 6ES5942-7UB11 | 30 ms / 1 K AWL operations | Yes | Same as 941. |
| CPU 943 | 6ES5943-7UB11 / 6ES5943-7UB21 | 18 ms / 1 K AWL operations | Yes | Same as 941; -7UB21 adds integrated L1 slave port. |
| CPU 944 | 6ES5944-7UB11 / 6ES5944-7UB21 | 10 ms / 1 K AWL operations | Yes | Same as 941; -7UB21 adds integrated L1 slave port. |
The reference for chapter 12.2.3 is the S5-115U Programmable Controller, CPU 941/942/943/944 System Manual. Confirm the exact chapter numbering against the manual edition bundled with the S5 package you are migrating from; Siemens released several editions (6ES5998-xAB01, -xAB11, and later printings). Use the Siemens Industry Online Support entry search with the order number 6ES5 998-xABxx to retrieve the matching PDF.
11. Commissioning, Verification, and Troubleshooting
11.1 Offline static checks
- Open the converted FB/FC in STEP 7 and confirm no S5 mnemonics (
AUF,JU PB,SPB,SLDin their S5 sense) survive. The cross-reference view (Ctrl+Shift+F3 on the classic STEP 7 editor) on the S7 project should show zero hits in the converted block for any of the S5-only mnemonics. - Confirm all markers used in the S5 source have been re-bound to TEMP or to a clearly documented DB.
- Confirm any OB 160 calls have been replaced with SFC 47 "WAIT," IEC timers, or removed entirely. Use the project-wide Find in Project dialog with the search strings
OB 160andOB160(no space) to catch both forms. - Run PLC > Check Block Consistency across the S7 program. Resolve every warning before downloading.
11.2 Online commissioning on the S7-300 CPU
- Download the converted blocks to the CPU in STOP mode.
- Switch to RUN-P. Open the diagnostic buffer (PLC > Module Information > Diagnostic Buffer) and confirm no
SFentries. - Trigger the calling OB 1 segment manually with the Monitor/Modify tool. Verify the target DB is populated correctly by reading back DBW offsets through the Monitor view.
- Use the S7-300 cycle-time viewer (SFC 78
READ_RTM+ SFC 79SET_RTM, or the PLC > Module Information > Scan Cycle Time tab) to confirm the loop body does not exceed the configured OB 1 max cycle time (default 150 ms on S7-300, 6 s on S7-1500). If it does, extendOB1_PRG_TIMEvia HW Config or shorten the loop with a different copy strategy (for example, SFC 20BLKMOVfor bulk copy). - On the first full run, set a breakpoint on the loop label
M002and single-cycle to confirm the pointer arithmetic is correct for the first three iterations.
11.3 Troubleshooting matrix
| Symptom on S7-300 | Likely Root Cause | Fix |
|---|---|---|
CPU goes to SF, diagnostic buffer OB not loaded or not possible (event ID 0x8001) |
OB 160 still referenced in the converted block | Replace with SFC 47 or remove |
CPU goes to SF, Area length error reading/writing (event ID 0x8032) |
Pointer seed out of range, or target DB too short for the #ANZ count |
Check target DB length; clamp i_DW + i_ANZ in the FB; or use SFC 24 TEST_DB
|
| Copy succeeds but data is wrong by one word | Incorrect shift count when converting word offset to byte offset | Use SLW 3 for S7 (not SLW 4 as on the S5-115U) |
| Copy succeeds, but inconsistent data when called from OB 35 and OB 1 | Global markers MW 220 / MW 222 still used; two priority classes clobbering each other | Re-bind to TEMP variables inside the FB; raise the L stack size in HW Config |
| Copy takes much longer on S7-300 than on S5-115U | Per-iteration wait removed; loop body now dominated by OB 1 overhead | Either accept the speedup (usually desired) or add SFC 47 with the original wait value |
| Copy completes but communication to a downstream L1 device fails | BS 60 was acting as the CBS pointer; L1 stack has no S7-300 replacement | Re-target to PROFIBUS DP, replace L1 coordination bytes with PROFIBUS I/O |
| Converting an FB that uses S5 timer area (T 0..T 31) produces wrong time bases | STEP 7 timer semantics differ; S5 timers run on 100 ms base, S7 default is 10 ms | Use S5TI_TIM from the S5 conversion tool, or migrate to IEC timers explicitly with the documented time base |
| Indirect OPN DB on CPU 312 / CPU 313 returns Parameter assignment error | Older CPU firmware does not accept OPN DB [#i_DB]
|
Switch to LAR1; OPN DB [AR1,P#0.0] or upgrade CPU firmware |
12. Frequently Asked Questions
What is BS 60 on an S5-115U?
BS 60 is the 61st byte of the S5-115U system data area. In a CPU with the SINEC L1 slave interface (CPU 943-7UB21 / 944-7UB21) it holds the address of the CBS (Coordination Byte Send) used by the L1 protocol handler. In a CPU without the L1 port, BS 60 participates in the scan-time accumulator. S7-300 / S7-400 / S7-1500 have no BS area; consult the S5-115U manual chapter 12.2.3 to find the intent and re-implement with SFC 51 (RDSYSST) or PROFIBUS DP I/O.
Why does the CPU stop when the S5 block runs on S7?
The S7-300 CPU rejects the S5-only statements BS 60 and OB 160 as unknown opcodes. The CPU enters STOP with a diagnostic buffer entry such as OB not loaded or not possible (event ID 0x8001) on the first scan. Convert the BS 60 reference per the S5-115U manual and replace the OB 160 call with SFC 47 "WAIT" or remove it.
How do I replace an S5 OB 160 variable time loop on S7-300?
Use SFC 47 "WAIT" with a microsecond parameter. For a 1 ms wait, call SFC 47 with WT := 1000. If the wait must not block higher-priority OBs, use an OB 35 cycle-tick counter or an IEC timer (SFB 4 "TON" / SFB 5 "TOF") instead.
Can the STEP 7 S5/S7 converter handle OB 160 and BS registers automatically?
No. The converter stops at the first unknown operand and either leaves a syntax error in the generated S7 block or aborts the conversion. Manual code review is required for every block that contains OB 1xx (other than OB 1, OB 100, OB 101, OB 102) or any BS reference. Run Check Block Consistency after every conversion pass.
Do I have to keep the per-iteration wait from OB 160 in the S7 replacement?
Usually not. The OB 160 wait in an S5 source is most often a defensive idiom to mask the S5-115U scan-time jitter across the CPU 941/942/943/944 family. On S7-300 the scan-time jitter is far smaller and a 1 ms wait inside a tight loop is usually redundant. Evaluate the calling context: if the wait paced a peripheral, throttled a bus, or debounced a relay, replace the wait with a hardware interrupt (OB 40) or a time-tick OB (OB 30..OB 38). If the wait was purely cosmetic, drop it.