How to Create a Custom SCL Wrapper for the BRCV Block with Dynamic ANY Pointers
To create a reusable S7-SCL wrapper block around system function block SFB13 (BRCV - Block Receive) that receives variable-length data blocks dynamically, construct a 10-byte ANY pointer structure in temporary memory and map it to the RD_1 parameter. In SIMATIC S7-400 and PCS 7, standard system communication blocks require ANY pointers to define the target data buffer. Because S7-SCL does not permit variable arrays directly on standard formal block interfaces, engineers must assemble the ANY pointer components manually—specifying the syntax ID (16#10), data type, byte length, and destination Data Block (DB) number—and manage the asynchronous communication handshake states (EN_R, NDR, ERROR, STATUS).
Table of Contents
- Mechanics of SFB13 (BRCV) in S7-400 Inter-Station Communications
- Anatomy of the 10-Byte S7 ANY Pointer Structure
- Constructing Dynamic ANY Pointers in S7-SCL
- Method: Step-by-Step Implementation of the SCL Wrapper Block
- Verification
- Limitations and Operational Precautions
- Engineer FAQ
- Technical References
- Related Articles
- Related Tags
Mechanics of SFB13 (BRCV) in S7-400 Inter-Station Communications
In large SIMATIC S7 and PCS 7 architectures, large blocks of data (up to 64 KB) are exchanged between controllers or between an AS and external systems using the configured S7 communication block pair:
- BSEND (SFB12): Transmits segmented data blocks asynchronously over an S7 connection.
- BRCV (SFB13): Receives the data stream, reassembles segments, and transfers the payload directly into a destination Data Block (DB).
- The Coordination Handshake:
- ID: Configured S7 Connection ID from NetPro.
- R_ID: A unique 32-bit identifier pairing a specific BSEND with its matching BRCV.
- EN_R: Continuous enable input authorizing data reception.
- NDR (New Data Received): Pulses TRUE for one CPU scan upon successful transfer.
- ERROR and STATUS: Output diagnostic condition codes.
Anatomy of the 10-Byte S7 ANY Pointer Structure
To tell BRCV where to deposit incoming data, the receiver parameter RD_1 requires an ANY pointer. In memory, an ANY pointer consists of exactly 10 bytes structured into six fields:
Syntax_IDBYTE16#10 for standard SIMATIC S7 pointers.Data_TypeBYTE16#02 = BYTE, 16#04 = WORD, 16#06 = DWORD.Repetition_FactorWORDDB_NumberWORD16#0032); 0 for non-DB memory.Memory_AreaBYTE16#84 for Data Blocks (DB), 16#83 for Bit Memory (M).Byte_Bit_Pointer3 BytesConstructing Dynamic ANY Pointers in S7-SCL
In S7-SCL, declaring an internal structure in VAR_TEMP allows direct assembly of these binary bytes:
VAR_TEMP
Target_Any : ANY;
Any_Overlay AT Target_Any : STRUCT
Syntax_ID : BYTE;
DataType : BYTE;
Count : WORD;
DB_Num : WORD;
AreaCode : BYTE;
ByteOffset : DWORD; // 3 bytes used for bit address
END_STRUCT;
END_VAR
By utilizing the SCL AT overlay filter, writing values into the individual elements of Any_Overlay simultaneously populates the formal Target_Any variable, which is then passed directly to SFB13.
Method: Step-by-Step Implementation of the SCL Wrapper Block
Follow this complete S7-SCL implementation to construct a dynamic, parameterized receiver function block:
Complete SCL Source Code:
FUNCTION_BLOCK FB2604
TITLE = 'Dynamic_BRCV_Receiver'
VERSION : '1.0'
AUTHOR : 'AutomationNet'
VAR_INPUT
ID : WORD; // Connection ID from NetPro
R_ID : DWORD; // Unique Pair Identifier
EN_R : BOOL; // Enable Receive
DB_NUM_I : INT; // Target DB Number
DB_LEN_I : INT; // Number of Bytes to Receive
END_VAR
VAR_OUTPUT
NDR : BOOL; // New Data Received (Pulse)
ERROR : BOOL; // Communication Error Flag
STATUS : WORD; // Error Status Code
END_VAR
VAR
inst_BRCV : BRCV; // Static Multi-Instance of SFB13
END_VAR
VAR_TEMP
Target_Any : ANY;
Any_Struct AT Target_Any : STRUCT
Syntax_ID : BYTE;
DataType : BYTE;
Count : INT;
DB_Number : INT;
BytePointer : DWORD;
END_STRUCT;
END_VAR
BEGIN
// 1. Construct the ANY Pointer dynamically in temp memory
Any_Struct.Syntax_ID := 16#10; // S7 Standard Syntax ID
Any_Struct.DataType := 16#02; // Type: BYTE
Any_Struct.Count := DB_LEN_I; // Length in bytes
Any_Struct.DB_Number := DB_NUM_I; // Target DB Number
// Memory Area 16#84 (DB) + Start Offset at Byte 0 (0 * 8 = 0)
// 16#84000000 points to DBX 0.0
Any_Struct.BytePointer := 16#84000000;
// 2. Call the internal SFB13 (BRCV) instance
inst_BRCV(
EN_R := EN_R,
ID := ID,
R_ID := R_ID,
RD_1 := Target_Any
);
// 3. Map status outputs to block interface
NDR := inst_BRCV.NDR;
ERROR := inst_BRCV.ERROR;
STATUS := inst_BRCV.STATUS;
END_FUNCTION_BLOCK
Verification
To verify that the custom SCL wrapper receives data correctly:
- In SIMATIC Manager, compile the .SCL source file into FB2604.
- Insert FB2604 into a cyclic CFC chart (e.g., OB35).
- Parameterize the block:
- ID: Enter the exact hex connection ID from NetPro (e.g., 16#0001).
- R_ID: Enter matching 32-bit ID (e.g., DW#16#00000001).
- EN_R: Set to TRUE.
- DB_NUM_I: Enter destination DB number (e.g., 50).
- DB_LEN_I: Enter expected payload length (e.g., 128).
- Trigger BSEND on the partner controller:
- Confirm NDR pulses TRUE in online Test Mode.
- Verify ERROR = FALSE and STATUS = 16#0000.
- Open target DB50 online: confirm that data bytes from the sender populate the data block accurately.
Limitations and Operational Precautions
- Target Data Block Sizing: The destination Data Block in controller memory must be equal to or larger than the configured
DB_LEN_I. IfBRCVattempts to write beyond the end of the declared DB, the CPU triggers an area length error (OB121) or enters STOP mode. - Asynchronous Execution Rules:
BRCVdoes not execute in zero time. The handshake is multi-cyclic. Do not read or process the destination DB data untilNDRassertsTRUE. - R_ID Uniqueness: Every
BSEND/BRCVpair on the same S7 connection must use a globally uniqueR_ID. CollidingR_IDvalues cause telegram cross-talk and data corruption.
Engineer FAQ
Why did the original ticket code fail when compiling in SCL?
The original post attempted to use unaligned bit shifts and undeclared temporary structures without the AT overlay filter, causing S7-SCL syntax errors on the RD_1 parameter.
Can this wrapper receive data into a Merker (M) memory area instead of a DB?
Yes. Change Any_Struct.BytePointer from 16#84000000 (DB) to 16#83000000 (Bit Memory Area) and set Any_Struct.DB_Number := 0.
What does STATUS = 16#7000 or 16#7001 mean on BRCV?
16#7000 indicates block idle / uncalled. 16#7001 indicates the block has been enabled (EN_R = 1), is waiting for incoming data, and communication is actively armed.
How many BRCV blocks can run simultaneously in an S7-400 CPU?
The limit is determined by the CPU's available communication instances and connection resources. High-performance CPUs like the CPU 410-5H support dozens of concurrent BSEND/BRCV communication instances.
Technical References
- Siemens Industry Online Support: System Software for S7-300/400 System and Standard Functions Manual (SFB12/SFB13).
- Siemens Industry Online Support: S7-SCL for S7-300/400 Programming Manual.
- SIOS Entry 109742323: PCS 7 Compendium Part A - Industrial Communication Guidelines.
- Siemens Support FAQ: Structure of the ANY Pointer in STEP 7.
Related Articles
- How to Configure and Simulate AS-to-AS Communication in S7-PLCSIM
- How to Pack and Unpack Double Words (DWORD) in SIMATIC PCS 7 CFC
- How to Resolve SCL Syntax Errors When Compiling CFC Charts as Block Types in PCS 7
Related Tags
- BRCV
- BSEND
- S7-SCL
- ANY Pointer
- SFB13
- S7 Communication
- Industrial Automation