S5 to S7 Conversion: Fixing LIR/TIR and SFC20 Errors

David Krause27 min read
S7-300SiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

S5 to S7 Conversion: Fixing LIR/TIR and SFC20 Errors in FB213, FB214, and CPU944 / CPS430 Programs

Converting legacy SIMATIC S5 programs (CPU 944, S5-135U/155U family) to S7 with the STEP 7 "S5 to S7 Converter" is rarely a one-click operation. The converter handles standard STL logic, timer/counter images, and bit/word memory transparently, but three classes of S5 construct almost always require manual re-engineering:

  1. Indirect register access commands LIR (Load Indirect Register) and TIR (Transfer Indirect Register) – flagged by the converter as Command not defined.
  2. Block move patterns that must be migrated to SFC20 BLKMOV – the converter generates the CALL but leaves SRCBLK and DSTBLK placeholders that must be reconstructed from the original S5 register contents.
  3. Communication standard FBs for the CPS430 (FB213, FB214, and similar CP drivers) – these S5-135U/155U COM software blocks are not part of the converter's library and must be re-implemented against the S7-300/400 CP340/CP341/CP440/CP441 family.

This reference documents each failure class, the underlying root cause in the S5 vs. S7 memory model, and the exact manual fix path. It is written for the engineer who has just opened a converted S7 source file, found lines such as // *** Error in Line 5997 (FB 54): Command not defined. ***, and needs to know what the converter left behind and how to finish the migration.

Scope: The examples below target a CPU 944 (S5-135U/155U) with a CPS430 communication module. The fix patterns apply identically to CPU 928B, CPU 945, CPU 948, and any other S5 CPU that uses the same S5-135U/155U instruction set. The replacement hardware is typically an S7-300 (CPU 315-2 PN/DP, CPU 317-2, or CPU 319-3 PN/DP) with CP340/CP341 for the serial link that the CPS430 previously served.

1. Problem Details: What the Converter Reports

Running the STEP 7 S5 to S7 Converter (menu Options > S5 to S7 Converter in classic STEP 7 V5.x) on a project that contains FB213, FB214, and any block that uses LIR / TIR produces three classes of diagnostic comment in the generated STL source.

1.1 LIR / TIR — "Command not defined"

Source excerpt from converted FB 54:

L   W#16#E400;
L   MB 223;
SLW 1;
+I;
//      LIR 0;
// *** Error in Line 5997 (FB 54): Command not defined. ***
T   MW 252;
L   0;
==I;
S   M 207.3;
BEC;
=   M 232.0;
L   MW 252;
+    -2;
//      LIR 0;
// *** Error in Line 6008 (FB 54): Command not defined. ***
+    -6;
T   MW 230;

The converter has commented out the original LIR 0 statement and inserted an error marker. The S7 instruction set contains no equivalent operator — LIR and TIR do not exist in any S7-300/400 CPU. They must be hand-replaced before the S7 block will compile.

1.2 SFC20 BLKMOV — "Please fill in the parameter list"

Source excerpt from converted FB 150:

L     DBW    8
INC   1
SRW   1
L     8
+I
T     DBW 286
L     DBW    6
L     DBW   12
//CALL SFC 20 (
//   SRCBLK := P#????? BYTE 0 ,
//    RET_VAL := conv_ret_val,
//    DSTBLK := P#????? BYTE 0
//       );
// *** OK in line 14298 (FB 150): Generates CALL SFC20. Please fill in the parameter list. ***

Here the converter has correctly generated the SFC20 call skeleton (the *** OK *** message confirms this) but it has no information about which DB / address range was being moved in the S5 source, because the original S5 block used LIR 0 to load the pointer at runtime. Both SRCBLK and DSTBLK must be resolved by analysing the S5 register-preparation code (the preceding SLW, SRW, INC, and +I statements).

1.3 FB213, FB214 — Silent Drop or Unresolved Reference

FB213 and FB214 (in the S5-135U/155U COM software package for the CPS430) are not part of the standard STEP 5 system library that the converter ships with. The converter typically:

  • Inserts a CALL FB213 / CALL FB214 reference, or
  • Omits the block body entirely and logs a warning such as Block FB213 not found in source library.

Either way, the S7 program will not link until the body of FB213 / FB214 is supplied. Because the CPS430 protocol is not bit-exactly emulated by any single S7 CP, the fix is not a direct block replacement — it is a protocol-level re-implementation using CP340/CP341/CP441 primitives.

2. Root Cause: Why the S5 Constructs Have No Direct S7 Equivalent

2.1 The S5 System Data Area and LIR / TIR

In SIMATIC S5 (CPU 944 / 928B / 945 / 948), the S5 CPU exposes a 256-word System Data Area (RS area) starting at word address 0. The area holds:

Word Typical contents Use
RS 0 Accu 1 (low word) Result of last arithmetic / transfer
RS 2 Accu 1 (high word) Result of last arithmetic / transfer
RS 4 Condition codes NZ, N, P, OV, OS, OR, STA, ER
RS 6..9 Accu 2 / 3 / 4 Extended accumulators (CPU 945/948)
RS 10..29 Address / scratch Used by COM software (FB200..249)
RS 30..255 Reserved / CP-specific Peripherals, CP scratchpads

The S5 instruction LIR <address> reads the word at the absolute address formed by the contents of Accu 1 (interpreted as a 16-bit pointer) into Accu 1. The S5 instruction TIR <address> writes Accu 1 to that address. In the example above, LIR 0 reads the system data area word at the offset held in Accu 1 (which had just been set to W#16#E400 + (MB223 * 2), i.e., a CP430 scratchpad offset).

The S5-300/S7-300/400 architecture is fundamentally different. The two 32-bit accumulators are integrated with the operand processing and there is no externally addressable system data area — the equivalent information lives in internal CPU registers that cannot be read by the user program. The S7-300/400 instruction set therefore has no LIR / TIR. The converter reports Command not defined because no ST-AWL opcode exists to generate.

2.2 Why SFC20 Placeholders Appear

The S5 block-move idiom was:

L   DBW 12     // source offset
LIR 0          // load source word from system data area (or CP scratchpad)
L   W#16#80    // marker for the converter
JU  M023       // jump to the move section

The S5 program used the CP's scratchpad / the CPU's system data area as an intermediate "any-pointer" buffer. SFC20 BLKMOV in S7 expects a fully-qualified ANY pointer for SRCBLK and DSTBLK — the pointer's structure (data block number, byte offset, repetition count) must be in the accumulator as a 10-byte ANY when the SFC is called. The converter cannot infer the pointer from the S5 LIR sequence, so it inserts P#????? BYTE 0 placeholders and asks the engineer to resolve them.

2.3 Why FB213 / FB214 Do Not Survive Conversion

FB213 and FB214 in the S5-135U/155U COM software package for the CPS430 are protocol drivers (typically send / receive with handshake) that the converter does not have an equivalent for in the S7 standard library. CPS430 supported RS-232 / RS-422 / TTY / 20 mA current loop with selectable protocols (ASCII, 3964R, RK512). The S7 equivalents are:

S5 hardware S7-300 replacement S7-400 replacement Protocol support
CPS430 (ASCII) CP340-1 (6ES7 340-1*); 1 channel CP440-1 (6ES7 440-1*) ASCII, 3964R
CPS430 (RK512) CP341-1 (6ES7 341-1*); 1 channel CP441-1 / CP441-2 (6ES7 441-1*/-2*) ASCII, 3964R, RK512, Modbus RTU
CPS430 (modular) CP342-5 / CP343-1 (PROFIBUS / Ethernet) — only if partner supports it CP443-1 / CP443-5 PROFIBUS DP / PROFINET / TCP

The S5 block interface of FB213 / FB214 (typically a "send / receive interface DB" with control byte, length, source / destination DB numbers) is preserved conceptually on the S7 CP, but the call wrappers and error codes differ. The S5 FB body must be re-written using the S7 CP's own FBs (FB7 / FB8 for CP340, FB7 / FB8 / FB9 / FB10 for CP341, etc.).

3. Conversion Tool Behavior — What the Converter Actually Does

The classic STEP 7 S5 to S7 Converter is an AWL/STL rewriter. It performs the following classes of transformation:

S5 construct Converter action Result
U, UN, O, ON, S, R, =, FP, FN on bits Direct translation Compiles cleanly
L PB / L PW / L PY (periphery) Direct translation to P# area Compiles cleanly; verify addressing
LIR 0 / TIR 0 Commented out, error marker inserted Manual fix required
DO DN / DO DW (data block indirect) Translated to OPN DB [...] + direct DBB/DBW/DBD Compiles; verify dynamic DB range
SPA / SPB / SPP / SPM / SPO / SPS Translated to JU / JC / JP / JM / JO / JOS Compiles
Block-move via register scratchpad Generated SFC20 CALL with P#????? placeholders Manual parameter fill-in required
FB213, FB214, FB200…FB249 (COM) Skipped / unresolved reference Manual re-implementation
Timer / Counter (S5 T 0..127, C 0..127) Translated to S7 IEC timers / counters with instance DB Compiles; watch for time-base differences
Process images (PII / PIQ) Translated 1:1 Compiles; verify on the new CPU's process-image size

Two diagnostic markers are emitted by the converter:

  • // *** Error in Line X (FB n): Command not defined. *** — a hard failure. The block will not compile until the marked line is fixed.
  • // *** OK in line X (FB n): Generates CALL SFCnn. Please fill in the parameter list. *** — a soft failure. The CALL has been generated correctly; only the parameter bindings are missing.

4. Step-by-Step: Fixing the Converted Source

4.1 Prerequisites

  • STEP 7 V5.4 / V5.5 (the S5 to S7 Converter is part of the install; it is not included in TIA Portal).
  • STEP 7 reference manual "System Software for S7-300/400 System and Standard Functions" (the SFC/SFB reference; see Siemens entry 1214574).
  • For CP340: CP340 manual (entry 1118417) and the PtP_PARAM setup tool.
  • For CP341: CP341 manual (entry 1118419).
  • For CP441-1 / CP441-2: CP441 manual (entry 1117740).
  • For the S5 source itself: a STEP 5 programming environment (PG 720 / PG 740 with STEP 5 V7.x) so the engineer can browse the original LIR 0 context and the system data area offsets the S5 program expected.
  • Functional specification of the S5 program: knowing which DB / byte range was being moved and which CP430 scratchpad byte corresponded to which protocol field.

4.2 Fixing LIR / TIR in a Converted Block

The fix is block-by-block. For each LIR 0 site the engineer must answer two questions from the S5 source:

  1. What was the address that the S5 code was loading from? (Typically an offset into the CPU's system data area, the CP's dual-port RAM, or a COM software buffer.)
  2. Where does the S7 program need that value? (Often: as the SRCBLK / DSTBLK ANY pointer of an SFC20 BLKMOV, or as the length / control bytes passed to a CP send / receive FB.)

For the example from the converted FB 54, the original S5 logic was:

L   W#16#E400          // base address of the CP scratchpad
L   MB 223             // CP job number * 2 (set by the COM software)
SLW 1
+I                     // Accu1 = W#16#E400 + (MB223 * 2)
LIR 0                  // Accu1 := word at (W#16#E400 + 2*MB223)
T   MW 252             // store the loaded word

The pattern is: the S5 code was reading the CP430 status word for a particular CP job (job number in MB223) and storing the 16-bit status into MW252. In S7 the equivalent is a direct symbolic read of the CP's status word, or a call to the S7 CP's status-return FB (e.g. FB8 RECEIVE on CP340 returns the actual bytes received, removing the need for the status indirection).

A typical S7 replacement for the snippet above is:

// S7 replacement for "LIR 0" reading CP340 / CP341 status
L   W#16#E400          // symbolic: "CP_JOB_BASE"
L   MB 223
SLW 1
+I
LAR1                    // load Accu1 into AR1 (area-crossing pointer)
L   W [AR1, P#0.0]      // read the 16-bit word at the resolved offset
T   MW 252

Notes:

  • LAR1 loads the computed pointer into Address Register 1. L W [AR1, P#0.0] dereferences AR1 as a 16-bit read in the area that AR1 points to (which must be set with the area identifier bits in the standard S7 way).
  • If the original LIR 0 was reading from the CPU's system data area (RS 0..255) — for example, the condition codes word at RS 4 — the S7 equivalent is no instruction at all: the condition-code information is already in the S7 status word / BR bit, accessed via A== / A<> / AN OV / etc.
  • If the original LIR 0 was reading from a CP's dual-port RAM at an address like 0xE400, then in S7 you must use the CP's symbolic I/O area (e.g. PQW 256..PQW 270 on a CP340 in slot 4) or the instance-DB of the CP's parameter assignment module.

4.3 Fixing SFC20 BLKMOV Placeholders

The converter has produced:

//CALL SFC 20 (
//   SRCBLK := P#????? BYTE 0 ,
//    RET_VAL := conv_ret_val,
//    DSTBLK := P#????? BYTE 0
//       );
// *** OK in line 14298 (FB 150): Generates CALL SFC20. Please fill in the parameter list. ***

For each SFC20 call, the engineer must recover from the S5 source: the source DB number, source byte offset, source length, and the same for the destination. In the example, the S5 code immediately preceding the CALL SFC 20 was:

L   DBW  8        // load source length
INC 1
SRW  1            // /2  (round up to word count)
L   8
+I               // DBW 8 / 2 + 8 = source byte offset into the COM DB
T   DBW 286       // store computed offset for later
L   DBW  6        // destination length
L   DBW 12        // destination DB number

The reconstructed S7 call is therefore:

// Source: DBW 8 bytes starting at (DBW 8 / 2 + 8) in the COM-DB
L   DBW  8
L   2
/I                // length / 2
L   1
+I                // round up
L   8
+I
SLD  3
L   DBW 12        // source DB number
+   DBNO_2        // 0x8400_0000 + (DB# << 16)
T   #srcblk       // store the ANY pointer

L   DBW  6        // destination length
L   DBW  6        // destination byte offset = DBW 6 itself
SLD  3
L   DBW  4        // destination DB number
+   DBNO_2
T   #dstblk

CALL SFC 20 (
   SRCBLK   := #srcblk,
   RET_VAL  := #ret_val,
   DSTBLK   := #dstblk );

Where DBNO_2 is the constant 0x84000000, the area-identifier bits that mark the ANY pointer as DB-area-32-bit-aligned. The cleanest approach in practice is to build the ANY in two static temps of type ANY / POINTER in the FB's static area, or to populate the SFC20 inputs symbolically in the calling instance.

4.4 Re-implementing FB213 / FB214 for the CPS430

The CPS430 was an S5-135U/155U CP that handled serial point-to-point links. The standard COM software that drove it exposed an interface DB that the user's FBs (FB213 send, FB214 receive, etc.) called. The interface DB layout was typically:

Offset Field Type Meaning
DBB 0 KBN / job number BYTE Identifies which CP job is being addressed
DBB 1 Function BYTE 0x01 = SEND, 0x02 = RECEIVE, 0x04 = FETCH, 0x08 = CONTROL
DBW 2 SSNR / CP number INT Logical CP interface number (1..15)
DBW 4 A-NR / job number INT CP job number (1..15)
DBW 6 Source / Dest DB INT DB to read from / write to
DBW 8 Source / Dest offset INT Byte offset into that DB
DBW 10 Source / Dest length INT Number of bytes to send / receive
DBW 12 Coordination byte INT Status / error code from CP

The S7 replacement is a thin SCL / STL wrapper that translates this interface into a call to FB7 P_SEND and FB8 P_RECV on a CP340, or to FB7 P_SEND / FB8 P_RECV / FB9 P_FETCH / FB10 P_CONTROL on a CP341 / CP441. The wrappers preserve the S5 interface DB so that no caller program needs to be changed.

A minimal S7 STL re-implementation of FB213 (SEND) for a CP340-1 is:

// Wrapper FB: S5 FB213 SEND replacement for CP340-1
// Interface DB layout preserved (DBW 0..12) for caller compatibility.
// CP340: 1 ASCII channel, FB7 P_SEND, FB8 P_RECV, instance DB = CP340_IDB.

FUNCTION_BLOCK FB213_S5
VAR
    cp_send   : UDT100;     // instance of FB7 P_SEND
    s5db      : BLOCK_DB;   // pointer to the S5-compatible interface DB
END_VAR
BEGIN
    // Read S5 interface DB
    L     DBB  0;           // job number
    T     #s5_job_no;
    L     DBB  1;           // function code
    L     B#16#01;
    ==I;
    JC    SEND;
    L     DBB  1;
    L     B#16#02;
    ==I;
    JC    RECV;
    JU    END_FB;

SEND:
    // Build ANY for the source data
    L     DBW 10;           // length (bytes)
    SLD   3;
    L     DBW  8;           // source byte offset
    SLD   3;
    OD;
    L     DBW  6;           // source DB number
    SLD   16;
    OD;
    L     DW#16#84000000;   // DB area identifier
    OD;
    T     #srcblk;

    CALL FB7, CP340_IDB (
        REQ       := TRUE,
        LADDR     := CP340_ADDR,         // e.g. 256
        DONE      := done_flag,
        ERROR     := error_flag,
        STATUS    := status_word,
        SD        := #srcblk,
        LEN       := #s5db.DBW 10 );

    // Translate CP340 status to S5 coordination byte (DBW 12)
    L     #status_word;
    T     #s5db.DBW 12;
    JU    END_FB;

RECV:
    // Build ANY for the destination
    L     DBW 10;
    SLD   3;
    L     DBW  8;
    SLD   3;
    OD;
    L     DBW  6;
    SLD   16;
    OD;
    L     DW#16#84000000;
    OD;
    T     #dstblk;

    CALL FB8, CP340_IDB (
        REQ       := TRUE,
        LADDR     := CP340_ADDR,
        NDR       := ndr_flag,
        ERROR     := error_flag,
        STATUS    := status_word,
        RD        := #dstblk,
        LEN       := recv_len );

    L     #status_word;
    T     #s5db.DBW 12;

END_FB:
END_FUNCTION_BLOCK

This wrapper preserves the S5 caller's call sequence and DB offsets, which means the call sites in the rest of the program (FCs that called FB213 / FB214 directly) do not need to be modified — they continue to call the same FB names with the same interface DBs, and the wrapper translates the calls to the S7 CP primitives.

5. The S5 vs. S7 Memory Model in One Diagram

The fundamental reason the S5 idioms do not translate is that the S5 CPU exposed a flat, addressable system data area and a separate operand area, while the S7 CPU integrates them. The diagram below is a side-by-side of the address spaces.

S5 CPU 944 memory model System data area (RS) 0..255 — LIR/TIR target Process I/O (P) 0..127 byte / 0..127 word Flag / Merker (M) 0..255 byte / 0..255 word Timers (T) 0..127 Counters (C) 0..127 Data blocks (DB) 0..255 CP scratchpad (e.g. CPS430 @ E400..E7FF) Accu 1..4 (internal, no addressing) Condition codes (CC1/CC0/OR/STA/RLO/ER/OS/OV) LIR 0 reads from any of the above by absolute 16-bit address S7-300/400 memory model No user-accessible system data area Process I/O (PI/PQ) — direct or via process image Flag / Merker (M) same semantics Timers / Counters (T/C) via IEC instance DB Data blocks (DB) same semantics, but loadable/unloadable CP I/O area (PAE/PAA) symbolic to CP340/CP341 Two 32-bit accumulators (internal, no addressing) Status word (CC1/CC0/OV/OS/OR/STA/RLO/BR) Address registers AR1 / AR2 (loaded with LAR1/LAR2) Indirection: area-crossing via AR1/AR2 + P#byte.bit offsets

6. Hardware Replacement Strategy for the CPU 944 + CPS430

6.1 Selecting the S7-300 Replacement CPU

The CPU 944 is an S5-135U / S5-155U CPU. Typical pin-compatible replacement: an S7-300 CPU 319-3 PN/DP (6ES7 318-3*0) with sufficient work memory and a PROFIBUS interface, or for smaller applications, a CPU 315-2 PN/DP. Key sizing parameters to check before replacement:

Parameter CPU 944 (typical) S7-300 candidate Decision
Work memory 64 KB / 128 KB CPU 319-3: 4 MB code + 8 MB data S7 has more; OK
Bit memory 2048 (M 0.0..M 255.7) 8192 (M 0.0..M 1023.7) typical OK
Timers 128 (T 0..127) 2048 (T 0..2047) typical OK
Counters 128 (C 0..127) 2048 (C 0..2047) typical OK
DBs 0..255 1..16000 (max DBs) OK
DP / PN interface none on CPU 944; via CP built-in on 315-2 / 317-2 / 319-3 Advantage S7

6.2 Selecting the S7 CP Replacement for the CPS430

Match the S7 CP to the protocol that the CPS430 was running on the plant network. The match is by protocol, not by module name:

CPS430 protocol Wiring S7-300 CP Order number Function blocks
ASCII, RS-232, no handshake X27 / V.24 CP340-1 6ES7 340-1AH02-0AE0 FB7 / FB8
ASCII, RS-422 / RS-485 X27 / V.24 CP340-1 6ES7 340-1BH02-0AE0 FB7 / FB8
ASCII, TTY / 20 mA X27 / V.24 CP340-1 6ES7 340-1CH02-0AE0 FB7 / FB8
3964R, RK512, Modbus RTU X27 / V.24 CP341-1 6ES7 341-1AH02-0AE0 FB7..FB10
High-speed 3964R, Modbus, custom X27 / V.24 CP341-1 (with loadable driver) 6ES7 341-1*02-0AE0 FB7..FB10 + loadable driver
Modbus RTU, RS-422/485, multi-drop X27 CP341-1 6ES7 341-1BH01-0AE0 FB7..FB10 + Modbus driver
S7-400 equivalent (1 ch.) X27 CP440-1 6ES7 440-1CS00-0YE0 FB9..FB11
S7-400 equivalent (2 ch.) X27 CP441-1 / CP441-2 6ES7 441-1AA*-0AE0 / -2AA*-0AE0 FB9..FB13 + loadable driver

For configuration, use the PtP_PARAM tool supplied with the CP340 / CP341 driver CD; for CP441 use COM 141 (S7-400). These tools produce a parameter DB that the FB wrappers read at startup.

Protocol driver licenses: Modbus RTU and 3964R on the CP341 / CP441 require a loadable driver purchased separately. Part numbers: 6ES7 870-1AA01-0YA0 (Modbus master, CP341), 6ES7 870-1AB01-0YA0 (Modbus slave). The CP340-1 ships with ASCII only.

7. Verification After Conversion

  1. Block-consistency check: open the S7 program in STEP 7, select the program folder, press F5 (Compile). The compiler must report zero errors. Any remaining *** Error in Line comments are unresolved.
  2. Cross-reference: use Options > Reference Data > Display to ensure that the renamed / re-implemented FB213, FB214 wrappers are referenced from all the FBs / FCs that originally called them.
  3. Simulation: run the converted S7 program in S7-PLCSIM with a simulated CP340 (PLCSIM does not simulate the CP340/341 directly; the simulation is normally done by disconnecting the CP from the S5 environment and exercising the wrapper in PLCSIM with the same S5 interface DB structure). For protocol-level simulation, use the CP340/341/441 Simulation tool supplied with the driver CD or a third-party terminal emulator on the partner side.
  4. Online test: in the first plant trial, place the S7 in STOP, then RUN, with a single partner device on the former CPS430 line. Watch the wrapper's status word (DBW 12 of the S5 interface DB) and confirm that it transitions through the S5 documented state sequence (BEFEHL_UEBERNOMMEN → BEARBEITUNG_LAEUFT → BEARBEITUNG_BEENDET).
  5. Long-duration run: leave the line in operation for at least 24 hours and verify that no coordination-byte values other than the documented S5 success code (typically 0) appear.

8. Troubleshooting Matrix

Symptom Likely cause Fix
Converter log: Command not defined. Command not defined. in lines 5997 / 6008 of FB 54 Original S5 had LIR 0 in two places Replace both with LAR1 + L W [AR1, P#0.0] or remove the indirection (if the status was the condition code, use the S7 status bit directly)
SFC20 RET_VAL returns 8091 (DB not loaded) The destination DB referenced in the ANY pointer is not loaded in the S7 CPU Add OPN of the destination DB before the SFC20 call, or load the DB into work memory with SFC20 / SFC21 / SFC22
SFC20 RET_VAL returns 8092 (ANY pointer write error) Length byte of the ANY pointer is zero, or the byte-offset + length exceeds the DB size Verify the DBW 8 + DBW 6 arithmetic that the S5 code used to compute the length and the offset
CP340 / CP341 STATUS = 0x0A (timeout on hardware) Wiring mismatch (RS-232 vs RS-422), wrong termination Match wiring to the S5 CPS430 wiring; for RS-485 enable / disable termination per the CP manual
CP340 STATUS = 0x0E (frame error) Baud rate / parity / data bits not matching the partner Use PtP_PARAM to set the CP340 to the same baud / parity as the partner; the S5 default was often 9600 / 8E1
CP341 / CP441 STATUS = 0x0800 (no driver loaded) The 3964R / Modbus driver has not been loaded onto the CP Load the driver using the CP configuration tool, then power-cycle the rack
Wrapper FB213 / FB214 never sets DONE The CP job has not been triggered (REQ not pulsed) Set REQ with a rising-edge trigger (FP) and a 1-cycle pulse; do not hold REQ continuously for CP340 (this is a one-shot, not a level-triggered signal)
Communication works in one direction only Half-duplex wiring with the wrong direction control on the RS-485 driver Enable hardware flow control (RTS/CTS) on the CP340-1 or use the CP441-2 with RS-485 adapter
DBW 12 of the S5 interface DB is always 0xFF The wrapper has not been loaded, or it is not in the OB1 call sequence Check that OB1 calls the wrapper FB (or that the wrapper is part of the cyclic OB)

9. Alternate Controller Notes

For an S5-115U / S5-135U / S5-155U program being migrated to a non-Siemens platform, the LIR / TIR fix does not translate directly. Key differences:

  • Allen-Bradley Logix (CompactLogix / ControlLogix): S5 flag (M) bytes map to Logix tag bool arrays; S5 data blocks map to Logix user-defined types (UDTs). The S5 block-move via SFC20 is replaced by a COP instruction in ladder logic, or by MEMCOPY in structured text. See the Rockwell SIMATIC S7 to Logix5000 Application Conversion Guide (Logix-AP008).
  • Schneider Modicon (M340 / M580): S5 data blocks map to Modicon located or unlocated variables; block moves become MOV_BLK in Unity Pro. Note that Modicon does not have a direct equivalent to the S5 system data area; the S5 flag / process / DB model is collapsed into a single address space.
  • PLC-5 / SLC 500 (legacy Allen-Bradley): the migration target is older than the S5 source itself and is not recommended except for very small control programs.
These are alternate-platform notes only. The S5 to S7 migration in this article is platform-pure; no cross-vendor code rewriting is performed by the S5 to S7 Converter.

10. Field Commissioning Checklist

  1. Document the original S5 program: list of FBs / FCs / DBs, all LIR / TIR occurrences, all DO / DO DW indirect DB accesses, the CPS430 interface DBs.
  2. Run the S5 to S7 Converter; export the conversion log.
  3. Filter the conversion log for *** Error and *** OK ... Please fill in the parameter list lines; that filter list is the manual-fix work package.
  4. Resolve every LIR / TIR site by replacing with the S7 AR-based indirection or by removing the indirection entirely if the value is now available symbolically.
  5. Resolve every SFC20 call by populating SRCBLK and DSTBLK as ANY pointers in the static / temp area of the FB.
  6. Re-implement FB213 / FB214 as S7 wrappers around the CP340 / CP341 FBs.
  7. Compile, download, and run PLCSIM for at least one full process cycle.
  8. Connect the S7 station to the partner device on the former CPS430 line, with the partner in monitor mode if possible.
  9. Run for the documented cycle time, then run overnight, then run a full weekend.
  10. Archive the original S5 source and the S5 to S7 Converter log alongside the S7 project — they are the authoritative audit trail for the conversion.

11. Summary of the Fixes

Converter error Underlying S5 construct S7 fix
Command not defined (LIR / TIR) Indirect access to system data area / CP scratchpad via 16-bit pointer in Accu1 Replace with LAR1 + L W [AR1, P#0.0] (AR-based indirection) or remove indirection if the value is now available symbolically from the CP instance
Please fill in the parameter list (SFC20) Block move with pointer prepared in scratchpad Build ANY pointers in the FB static / temp, bind to SRCBLK / DSTBLK
FB213 / FB214 unresolved CPS430 send / receive wrappers from the S5 COM software Re-implement as S7 wrappers around FB7 P_SEND / FB8 P_RECV on a CP340-1 or CP341-1; preserve the S5 interface DB layout
FB54 still references status from LIR CP430 status readback into MW252 Read the CP340 / CP341 status word from the FB instance / status parameter; do not indirect through an AR

12. Quick-Reference Pointer Recipes

The three S7 ANY-pointer patterns most commonly needed in the S5 to S7 fix work:

12.1 ANY pointer for a DB region (most common)

// Length (bytes)
L     #len;
SLD   3;                      // shift left 3 to occupy the 16-bit length field
// Byte offset
L     #byte_offset;
SLD   3;
OD;                           // OR: length occupies top 16, offset middle 16
// DB number
L     #db_no;
SLD   16;
OD;
// Area identifier 0x84 = DB, 0x02 = 16-bit length spec
given the L W#16#8400_0000 / form as used
OD;
T     #any_ptr;

12.2 ANY pointer for a flag / merker region

L     #len;
SLD   3;
L     #byte_offset;
SLD   3;
OD;
L     DW#16#8300_0000;       // area identifier for flag area
OD;
T     #any_ptr;

12.3 ANY pointer for the process I/O area (PI/PQ)

L     #len;
SLD   3;
L     #byte_offset;
SLD   3;
OD;
L     DW#16#8100_0000;       // area identifier for inputs (PI)
OD;
T     #any_ptr_pi;

L     #len;
SLD   3;
L     #byte_offset;
SLD   3;
OD;
L     DW#16#8200_0000;       // area identifier for outputs (PQ)
OD;
T     #any_ptr_pq;

Area identifier encoding (top byte of the ANY pointer): 0x81 = PI, 0x82 = PQ, 0x83 = M, 0x84 = DB, 0x85 = DI, 0x87 = L (local). Always OR in 0x0000_0002 in the bottom byte if you need a 16-bit-aligned specification; leave at 0x04 for byte-aligned 32-bit length. The patterns above use the standard 0x__00_0000 area identifier with the length in the next 16 bits.

What does "LIR 0" mean in a SIMATIC S5 program?

LIR 0 is the S5 instruction Load Indirect Register with operand 0. The CPU reads the 16-bit word at the absolute address held in Accu 1 (interpreted as a pointer) into Accu 1. Operand 0 means the address is treated as a flat 16-bit pointer, which the S5 CPU maps into the system data area (RS 0..255), the CP scratchpad (e.g. CPS430 at 0xE400..0xE7FF), or the data block area, depending on the high bits of the pointer. The instruction does not exist in the S7-300/400 instruction set, which is why the S5 to S7 Converter reports Command not defined and comments out the line.

Why does the S5 to S7 Converter insert "P#????? BYTE 0" placeholders in SFC20 BLKMOV calls?

The S5 source built the source / destination pointer at runtime by storing the DB number, byte offset, and length into a scratchpad word and then calling the S5 block-move routine. The converter cannot reconstruct that runtime pointer statically, so it generates the SFC20 CALL shell but leaves SRCBLK and DSTBLK as P#????? BYTE 0. You must populate the ANY pointers manually from the S5 code that prepared the pointer (typically the SLW / SRW / +I sequence immediately preceding the call), then bind them to the SFC20 inputs.

How do I replace an S5 CPS430 with an S7-300 CP?

Match the S7 CP to the protocol the CPS430 was running: CP340-1 (6ES7 340-1*A02-0AE0) for ASCII on RS-232 / RS-422 / RS-485 / TTY; CP341-1 (6ES7 341-1*A02-0AE0) for 3964R, RK512, and Modbus RTU (loadable driver license required). The S5 FB213 / FB214 send / receive wrappers must be re-implemented as S7 wrappers around FB7 P_SEND and FB8 P_RECV on the CP. Use the PtP_PARAM tool (CP340) or COM 141 tool (CP441) to configure baud rate, parity, and frame.

Why does FB213 / FB214 not appear in the converted S7 project?

FB213 / FB214 belong to the S5-135U / S5-155U COM software package for the CPS430, which is not part of the S5 to S7 Converter's source library. The converter logs an unresolved block reference for them. The fix is to write equivalent S7 wrappers (typically using FB7 P_SEND / FB8 P_RECV on a CP340-1 / CP341-1) that preserve the S5 interface DB layout, then call those wrappers from the same FBs / FCs that called FB213 / FB214 in the S5 source.

Can I keep the original S5 CPU 944 in service while I migrate?

Yes. The standard migration practice is to keep the S5-135U / S5-155U rack on the plant network during the cutover, parallel the CPS430 line with a CP340 / CP341 on the new S7-300 rack, and run the S5 and S7 programs side by side for a defined burn-in period. Once the S7 station has demonstrated correct coordination (DBW 12 of the S5 interface DB remains at the documented success code for at least one full plant cycle plus a 24-hour hold), the S5 rack is decommissioned and the S7 station takes over the line.

Does the S5 to S7 Converter run inside TIA Portal?

No. The S5 to S7 Converter is a feature of the classic STEP 7 V5.x environment (STEP 7 Manager). It is not present in TIA Portal. To migrate an S5 program to TIA Portal, you must first run the S5 to S7 Converter in classic STEP 7 to produce an S7-300/400 S7 program, then migrate that intermediate S7-300/400 program into TIA Portal using the TIA Portal "Migrate project" function. The S5 → S7 step has to be done in classic STEP 7 regardless of the long-term target platform.

What SFC20 RET_VAL values are most common after a faulty S5 to S7 conversion?

The four most common SFC20 RET_VAL values from a faulty S5 to S7 conversion are: 0x0000 success (no error), 0x8091 "DB not loaded" (the destination DB referenced in the ANY pointer is not in work memory), 0x8092 "ANY pointer write error" (the length byte in the ANY pointer is zero or the offset+length exceeds the DB size), and 0x80A1 "offset error" (the byte offset in the ANY pointer is negative or outside the DB). Verify the source and destination DBs are loaded, the length computed from the S5 DBW 8 arithmetic is non-zero, and the offset+length is within the DB size as declared in the DB definition.

Back to blog