Siemens BLKMOV: Symbolic Copy of a Partial BOOL Array in STEP 7
1. Overview
Engineers moving alarm or status bitfields between data blocks frequently hit a hard constraint in STEP 7: BLKMOV (FC20/FC21/SFC20 BLKMOV and the SCL/STEP 7 V15+ instruction MOVE_BLK) operates on a byte-granular source/destination area, not on individual bits. When the source is a ARRAY[0..31] OF BOOL and the target requires only the first eight bits, neither a fully symbolic call nor a partial symbolic slice is accepted by the editor in the S7-300 toolchain. The classic work-around uses an absolute pointer such as P#DB1802.DBX44.0 BYTE 8, which couples the call to a fixed DB number and byte offset and breaks every time the upstream block is recompiled or restructured.
This reference documents the underlying mechanics, the S7-300 versus S7-1200/S7-1500 behavior delta, and five production-proven workarounds that keep the source fully symbolic:
- SCL
AT-view overlay on a byte/word array - STL
ANY-pointer assembly with symbolic DB and runtime offset - Wrapper FC/FB with
IN_OUTof a byte-array slice -
SFC20 BLKMOVwith pointer math fromAR1/AR2 - Bit-shifting into a
WORD/DWORDstaging buffer
2. BLKMOV Mechanics and the ANY-Pointer
Both the legacy STL BLKMOV in the S7-300 standard library and the S7-1500 MOVE_BLK instruction accept an ANY source and an ANY destination. The ANY pointer is 10 bytes laid out as follows:
| Byte | Content | Meaning |
|---|---|---|
| 0..3 |
10# 16# 00 00 (S7-300) or 10# 16# 00 00 (S7-1500) |
ID + type marker; 10 hex for S7-300 STL, sometimes 10 for TIA; 16 for full S7-1500 pointer |
| 4..5 | Length in bits or bytes (WORD) | Repetition factor: byte count for non-BOOL types, bit count only for the legacy BLKMOV BOOL overload |
| 6..7 | DB number (WORD) | 0 for non-DB areas; otherwise the DB number |
| 8..9 | Area code (BYTE) + byte offset high nibble |
84h=DB, 81h=M, 82h=E (input), 83h=A (output), 80h=L (temp) |
| 9..11 | Byte offset (DWORD) | Bit-addressable offset within the chosen area |
The S7-1500 BLKMOV reference page states explicitly: "If a block of data type BOOL is moved, the tag must be addressed absolutely and the specified length of the area must be divisible by 8". This single rule is the root cause of the symbolic-failure symptom reported by the S7-315 user.
3. Why Symbolic Partial Copy of a BOOL Array Fails
STEP 7 enforces two independent rules that combine to make a symbolic slice of a ARRAY[..] OF BOOL unusable on every S7-CPU family:
- Byte alignment. The source length is interpreted in bytes. A request for "8 bits" is rounded up to 1 byte; the editor issues a compile error because the symbolic array slice does not carry a guaranteed byte boundary.
-
Length divisibility. When the underlying area is declared
BOOL, the length must be a multiple of 8 bits. The CALL lineSRCBLK := "MyAlarm" BYTE 1is therefore rejected even on a 1500; the length is 1 byte (= 8 bits), so the absolute form works but the symbolic short-form does not, because the compiler cannot prove that the next 7 bits after bit 0 are not allocated to a differentBOOLtag in the same DB.
The compile error seen in the editor is typically 0800 0001 in S7-300 / STEP 7 V5.x ("type identification error") or LIC001 / LEN001 on TIA Portal ("length does not match the data type").
4. S7-300 vs S7-1200 / S7-1500 Behavior
| Property | S7-300 / S7-400 (STEP 7 V5.x) | S7-1200 / S7-1500 (TIA Portal) |
|---|---|---|
| Instruction name | FC20 BLKMOV / SFC20 BLKMOV
|
MOVE_BLK (renamed) or legacy BLKMOV
|
| Source/destination parameter type | ANY |
VARIANT + length, plus ANY for STL compatibility |
| Symbolic BOOL slice | Not allowed; absolute BYTE n only |
Same: "addressed absolutely" per the official S7-1500 BLKMOV manual
|
| Length units | Bytes for non-BOOL, bits only when source is BOOL array |
Always bytes; BOOL must be byte-aligned and multiple of 8 |
| Symbolic full-array copy | Yes (entire array passed as ANY) |
Yes |
| Symbolic partial slice (e.g. 8 of 32 bits) | No | No |
For an S7-315 (firmware V3.3 and later) and S7-1500 firmware V2.0 / V2.5 / V2.9, the partial-copy restriction is identical. Choosing a 1200/1500 does not unlock a symbolic slice; it just changes the error-message wording.
5. Workaround 1 — SCL AT-View Overlay
The cleanest answer is to keep the symbolic BOOL array and to declare a second view over the same memory region as a byte/word array. The two declarations are guaranteed by the compiler to occupy the same offsets inside the same DB. From V5.4 SP5 of STEP 7 onward the AT construction is supported in SCL; the Siemens knowledge contribution 21946854 demonstrates the technique in detail.
Declare inside DB1802 (or a wrapper DB that uses AT on the alarm symbol):
DATA_BLOCK "DB_AlarmShadow"
STRUCT
b1 AT "AlarmBlock".alarm[0] : ARRAY[0..3] OF BYTE; // overlaps bits 0..31
END_STRUCT;
END_DATA_BLOCK
Alternative: local AT view inside the calling SCL block:
VAR
abAlarms : ARRAY[0..31] OF BOOL; // populated by upstream block
abBytes AT abAlarms : ARRAY[0..3] OF BYTE; // shared memory, byte-granular
END_VAR
// copy first byte (bits 0..7) into a 1-byte symbolic area in DB1803
"DB_AlarmShadow".firstByte := abBytes[0]; // purely symbolic
The AT view is fully symbolic, survives any upstream restructuring of the BOOL array, and lets the engineer use MOVE_BLK with a length of 1 (or 4 for the whole alarm word). On S7-300 firmware < V3.3 the AT keyword is parsed but the compiler issues warning W:": AT-construction in instance DB not yet supported"; upgrade to firmware V3.3 or move the data to a global DB before applying this technique on a 31x CPU.
6. Workaround 2 — STL ANY-Pointer Assembly with Symbolic DB
When the goal is to call SFC20 BLKMOV with the DB name symbolic but the offset computed at runtime (e.g. from a configurable alarm-base tag), build the ANY in two TAR/LAR steps inside an FC. The same Siemens FAQ 21946854 contains the STL example reproduced below.
FUNCTION FC 100 : VOID
VAR_TEMP
sAnySrc : ANY;
sAnyDst : ANY;
wRet : WORD;
diBase : DINT;
END_VAR
BEGIN
// --- build source ANY for 8 bits (1 byte) starting at runtime offset ---
LAR1 ; // AR1 holds instance-DB base (set by caller)
L DBB 0 ; // offset-low from a symbolic byte tag
T LW 20 ;
L B#16#10 ; // S7-300 ANY ID
T LB 20 ;
L B#16#04 ; // 4 = BOOL, length unit = bit
T LB 21 ;
L 8 ; // 8 bits = 8 bools
T LW 22 ;
L W#16#0000 ; // DB number placeholder
T LW 24 ;
// Load DB number symbolically from a WORD tag in the same DB
L "DB_AlarmShadow".wDBno ;
T LW 24 ;
L B#16#84 ; // area code DB
T LB 26 ;
L W#16#0000 ;
T LW 27 ;
// destination ANY built identically from the target DB
CALL SFC 20 (
SRCBLK := sAnySrc,
RET_VAL:= wRet,
DSTBLK := sAnyDst);
END_FUNCTION
This pattern keeps the DB number and the symbolic structure under engineering control. The only "absolute" element is the byte/bit area code, which is required by the SFC itself and never changes. Offset and length can be moved to instance data so the function is reusable across projects.
7. Workaround 3 — Wrapper FC/FB with IN_OUT Byte Slice
For a clean ladder/FBD representation in the calling network, wrap the copy in a small FC whose input and output are IN_OUT ARRAY[*] OF BYTE variables typed over the same underlying memory. Inside the wrapper a single SCL MOVE_BLK call references the symbolic parameter and a constant length.
FUNCTION FC 101 : VOID
VAR_IN_OUT
abSrc : ARRAY[0..3] OF BYTE; // 32-bool area overlaid by AT in caller
abDst : ARRAY[0..0] OF BYTE; // 8-bool target area, pre-sized
END_VAR
BEGIN
// Slice abSrc[0] into abDst. Compiler resolves abSrc[0] symbolically.
abDst[0] := abSrc[0];
END_FUNCTION
The wrapper is fully symbolic, the call site becomes CALL FC 101 (abSrc := "DB_AlarmShadow".abBytes, abDst := "DB_AlarmTarget".abFirst). PLC code review, diffing and watch tables all read on the symbol rather than the absolute address.
8. Workaround 4 — SFC20 with AR1/AR2 Pointer Math
For high-performance applications where the call must remain in STL with multi-instance offsetting, pass the source pointer through AR1 and the destination pointer through AR2 using the "pointer to area-internal data" convention (area code 0x84 in the high byte of the low word). The Siemens AT-view contribution describes the same encoding for the ANY parameter of SFC20 and the BLKMOV legacy instruction.
LAR1 P#DBX 0.0 ; // AR1 = pointer to bit 0 of instance-DB root
+AR1 P#4.0 ; // offset to the alarm array base
LAR2 P#DBX 100.0 ; // AR2 = target area base
CALL SFC 20(
SRCBLK := P#M 0.0 BYTE 8, // length 8 bits must be 1 byte here
RET_VAL:= MW 200,
DSTBLK := P#M 10.0 BYTE 1);
Note: SFC20 does not accept a bit-length; convert the "8 BOOLs" to "1 byte" and ensure the 8 bits are byte-aligned in the source DB. This is the byte-length restriction noted on the S7-1500 BLKMOV page.
9. Workaround 5 — Bit-Shift into a WORD/DWORD Staging Buffer
If the engineer cannot change the source DB layout and is forbidden from using AT overlays (for example, on a legacy S7-300 with V5.3 SP1 or earlier where the compiler issues an error rather than a warning), serialize the eight bits into a temporary WORD by reading each bit with a U/L pattern, shifting and OR-ing into the staging word.
FUNCTION FC 102 : VOID
VAR_TEMP
i : INT;
wStage : WORD;
END_VAR
BEGIN
wStage := 0;
FOR i := 0 TO 7 DO
IF "DB_Alarm".abAlarms[i] THEN
wStage := wStage OR SHL(WORD#1, i);
END_IF;
END_FOR;
"DB_AlarmTarget".wFirstEight := wStage;
END_FUNCTION
The staging WORD can then be moved with one MOVE_BLK or MOVE instruction into a WORD tag in the target DB, where the receiving ladder logic decodes the eight bits individually. This is the slowest method (eight bit reads plus a loop) but the only one that works on every CPU firmware without overlay support.
10. Workaround Comparison Matrix
| Method | CPU families | Required firmware | Fully symbolic | Reusable | Performance (cycle cost) | Maintenance risk |
|---|---|---|---|---|---|---|
SCL AT overlay |
S7-300 (315 V3.3+), S7-400, S7-1200, S7-1500 | V3.3 / V4.0 / V1.0 | Yes | High | 1 byte copy, ~5 µs | Low — compiler tracks offsets |
STL ANY assembly |
S7-300 / S7-400 / S7-1500 (STL) | Any | Yes (DB + offset tag) | High | ~20 µs + SFC20 | Medium — manual pointer math |
| Wrapper FC/FB | All | Any | Yes | High | ~5 µs | Low — single call site |
| AR1/AR2 + SFC20 | S7-300 / S7-400 STL | Any | No (P# literal) | Medium | ~15 µs | High — multi-instance fragile |
| Bit-shift staging | All | Any | Yes | Medium | ~50 µs (8 iterations) | Low — explicit code |
11. Verification and Commissioning
After applying any of the five workarounds, run the following verification sequence on the target CPU. The steps reference S7-300 firmware V3.3 / STEP 7 V5.6 and S7-1500 firmware V2.9 / TIA Portal V18; adapt the menu paths to the local engineering tool.
-
Compile check. Trigger a full rebuild of the program. The SCL compiler must report 0 errors / 0 warnings. A residual warning such as
"AT-view: identical offset not guaranteed"indicates the BOOL array is in a different DB than the overlay; resolve by moving theATdeclaration into the source DB or a dedicated shadow DB with the sameSTRUCTaddress. -
Symbol resolution. Open the compiled program in the online view, right-click the
SRCBLKoperand, and confirm the displayed symbolic name matches the project symbol table. If the view shows an absolute address, the offline project is out of sync — re-download the program. -
Length check. Place a watch table on the source byte
"DB_Alarm".abBytes[0]and on the destination byte"DB_AlarmTarget".abFirst. Force eight bits in the source and verify that the destination byte reflects them bit-for-bit. -
Bit-isolation regression. Force the remaining 24 bits of the source array (
abAlarms[8..31]) to1and re-check the destination: it must still hold only the first eight bits. A failure here means theAToverlay is pointing at the wrong byte offset and is leaking into the next area. -
Cycle-time impact. On a 315-2 PN/DP measure OB1 cycle time with and without the BLKMOV block. A properly implemented
AT-view copy should add < 0.1 ms; a misconfigured bit-shift loop can add 0.3–0.5 ms per call. -
Cross-DB consistency. Open the cross-reference (Ctrl+Shift+F in STEP 7) on the source symbol. Every usage must resolve to the same DB number/offset. If the cross-reference shows two different offsets, the source block was modified after the
ATview was generated — re-run the compile and re-download. -
Retain / restart test. Cycle power to the PLC and confirm the destination byte is identical to the source. The
ATview does not alter retain behavior; both sides must be in a retain-enabled DB if the data must survive a warm restart.
BLKMOV path. Use the F-library certified F_BLKMOV or F_I_DB move blocks from the Siemens Industry Online Support safety package and keep the F-runtime group time budget under the value listed in the F-CPU manual (typically 30 ms for S7-300F, 15 ms for S7-1500F).12. Frequently Asked Questions
Can I move 8 bits of a 32-bit BOOL array with a fully symbolic BLKMOV call on an S7-315?
No. STEP 7 forces the BOOL source of BLKMOV to be addressed absolutely with a length that is a multiple of 8 bits. Use an SCL AT overlay, a wrapper FC/FB, or a bit-shift staging word to keep the call site symbolic.
Does upgrading from an S7-300 to an S7-1500 lift the partial-BOOL-array restriction?
No. The S7-1500 MOVE_BLK / BLKMOV instruction carries the same byte-alignment rule — "the tag must be addressed absolutely and the specified length of the area must be divisible by 8". The compiler messages differ, but the underlying requirement is identical.
What is the minimum firmware for the SCL AT overlay on an S7-300?
Firmware V3.3 on the S7-31x CPUs and STEP 7 V5.4 SP5 (or later) is required. Earlier firmware issues warning W: AT-construction in instance DB not yet supported and refuses the AT view in an FB's static area. Move the data to a global DB or upgrade the CPU firmware.
Is SFC20 BLKMOV faster than SCL MOVE_BLK for an 8-bit copy?
On an S7-315 the two are equivalent (~5 µs) because the bulk of the time is the call overhead, not the data transfer. The performance gap only matters for arrays above ~32 bytes. Pick SCL MOVE_BLK with an AT view for readability and pick SFC20 with explicit ANY assembly only when you need to compute the offset at runtime.
Where is the official Siemens documentation for the BLKMOV byte-alignment rule?
The S7-1500 BLKMOV reference page and the SCL Knowledge Contribution 21946854 together state the rule and the AT overlay pattern. For S7-300 STL behavior, the SFC20 entry in the "System and Standard Functions for S7-300/400" manual is the primary reference.