How to Create a Custom SCL Wrapper for the BRCV Block with Dynamic ANY Pointers

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

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:

Byte OffsetField NameData TypeValue / PurposeByte 0Syntax_IDBYTEAlways 16#10 for standard SIMATIC S7 pointers.Byte 1Data_TypeBYTEData type of target: 16#02 = BYTE, 16#04 = WORD, 16#06 = DWORD.Bytes 2–3Repetition_FactorWORDNumber of elements (e.g., number of bytes to receive).Bytes 4–5DB_NumberWORDTarget Data Block number (e.g., DB 50 = 16#0032); 0 for non-DB memory.Byte 6Memory_AreaBYTEArea code: 16#84 for Data Blocks (DB), 16#83 for Bit Memory (M).Bytes 7–9Byte_Bit_Pointer3 BytesBit address pointer: Start byte offset multiplied by 8 ($\text{ByteOffset} \ll 3$).

Constructing 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. If BRCV attempts to write beyond the end of the declared DB, the CPU triggers an area length error (OB121) or enters STOP mode.
  • Asynchronous Execution Rules: BRCV does not execute in zero time. The handshake is multi-cyclic. Do not read or process the destination DB data until NDR asserts TRUE.
  • R_ID Uniqueness: Every BSEND/BRCV pair on the same S7 connection must use a globally unique R_ID. Colliding R_ID values 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

Related Tags

  • BRCV
  • BSEND
  • S7-SCL
  • ANY Pointer
  • SFB13
  • S7 Communication
  • Industrial Automation
20 respuestas