FB_IEC870_5_101TBufferCtrl

From product version:  TwinCAT PLC Library IEC60870-5-104 substation v2.0.6 / IEC60870-5-101 substation v2.0.2 and higher.

FB_IEC870_5_101TBufferCtrl 1:

This function block changes the content of the TX/RX data buffer. This data buffer ist used by the communication via the IEC60870-5-104/101 Transport Interface.

The function block has the following actions:

The content of the TX/RX data buffer can be changed by the call of one of the listed actions above.

VAR_IN_OUT

VAR_IN_OUT
    buffer  : ST_IEC870_5_101TBuffer; (* TX/RX data buffer *)
END_VAR

buffer: TX/RX data buffer. The TX/RX buffer parameters (like e.g. asduSize ) have to be configured before using.

VAR_INPUT

VAR_INPUT
    putObj  : ST_IEC870_5_101AOGen; (* ASDU to send *)
END_VAR

putObj: Data unit (ASDU) to be sent.

VAR_OUTPUT

VAR_OUTPUT
    getObj  : ST_IEC870_5_101AOGen; (* received ASDU *)
    bOk     : BOOL; (* TRUE = action succesfully, FALSE=Fifo overflow or fifo empty *)
END_VAR

getObj: Received data unit (ASDU).

bOk: This variable becomes TRUE, if a new entry was inserted or removed successfully from the Fifo. This variable becomes FALSE at a buffer overflow and if no entry could be removed, because the Fifo was already emty.

 

Example in ST:

The following example code shows the using of theactions.  Each ~100ms (tCycle) a new ASDU (M_BO_TB_1) with the transmission cause spontaneous and time stamp will be created and  stored in the TX-Fifo.
The received test commands (C_TS_TA_1)  and time synchronisation commands (C_CS_NA_1) are removed from the RX-Fifo and answered with mirrored ASDUs

 

PROGRAM P_SAMPLE_1ms
VAR
    (* TX/RX data buffer *)
 fbBuffer    : FB_IEC870_5_101TBufferCtrl;
    buffer      : ST_IEC870_5_101TBuffer := ( asduSize := 253 );

    tCycle  : TIME := T#100ms;
    timer   : TON;
    dtStart     : DT := DT#2006-07-05-12:34:56;

    txAsdu  : ST_IEC870_5_101AOGen;
    rxAsdu  : ST_IEC870_5_101AOGen;

    txBSI   : DWORD := 1;
    txQDS   : BYTE;
    txTT    : T_CP56Time2a;
    rxTT    : T_CP56Time2a;
END_VAR

 

timer( IN := TRUE, PT := tCycle );
IF timer.Q THEN
    timer( IN := FALSE );

    txAsdu.ident.eType := M_BO_TB_1; (* Bit string with time tag *)
    txAsdu.ident.bSQ := FALSE;
    txAsdu.ident.nObj := 1;
    txAsdu.ident.eCOT := eIEC870_COT_SPONTAN;
    txAsdu.ident.nORG := 1;
    txAsdu.ident.bPN := FALSE;
    txAsdu.ident.bT := FALSE;
    txAsdu.ident.eClass := eIEC870_Class_1;
    txAsdu.ident.asduAddr := 7;
    txAsdu.info.objAddr := 100;


    txBSI := ROL( txBSI, 1); (* Modify bit string value *)
    txQDS.7 := NOT txQDS.7; (* Toggle IV quality flag *)(* create dummy time tag *)
    dtStart := dtStart + tCycle;
    txTT := SYSTEMTIME_TO_CP56Time2a( DT_TO_SYSTEMTIME( dtStart ), TRUE );

    F_iecResetStream( 0, txAsdu.info.stream ); (* clear previous data (this sets the stream length = 0 *)
 F_iecCopyBufferToStream( ADR( txBSI ), SIZEOF( txBSI ), txAsdu.info.stream ); (* put BSI to stream *)
 F_iecCopyBufferToStream( ADR( txQDS ), SIZEOF( txQDS ), txAsdu.info.stream ); (* put QDS to stream *)
 F_iecCopyBufferToStream( ADR( txTT ), SIZEOF( txTT ), txAsdu.info.stream ); (* put time tag to stream *)

    fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
 IF NOT fbBuffer.bOk THEN
        ;(* Report send buffer overflow error *)
 END_IF
END_IF



REPEAT
fbBuffer.RxRemoveObj( getObj=>rxAsdu, buffer := buffer ); (* Try to remove asdu from RX fifo *)
IF fbBuffer.bOk THEN (* success *)

    CASE rxAsdu.ident.eType OF
    C_TS_TA_1: (* Test command *)

        txAsdu := rxAsdu;
        txAsdu.ident.eCOT := eIEC870_COT_ACT_CON; (* send activation confirmation *)

        fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
     IF NOT fbBuffer.bOk THEN
            ;(* Report send buffer overflow error *)
     END_IF


    C_CS_NA_1: (* clock synchronisation *)

        F_iecCopyStreamToBuffer( ADR( rxTT ), SIZEOF( rxTT ), rxAsdu.info.stream );

        (*... *)

        txAsdu := rxAsdu; (* dummy old time value *)
     txAsdu.ident.eCOT := eIEC870_COT_ACT_CON; (* send activation confirmation *)

        fbBuffer.TxAddObj( putObj := txAsdu, buffer := buffer ); (* put asdu to the TX fifo *)
     IF NOT fbBuffer.bOk THEN
            ;(* Report send buffer overflow error *)
     END_IF

    END_CASE

END_IF
UNTIL NOT fbBuffer.bOk (* RX fifo is empty *)
END_REPEAT

 

 

Requirements

Development Environment

Target System

PLC libraries to include

TwinCAT v2.10.0 Build >= 1301

PC or CX (x86, ARM)

TcIEC870_5_101.Lib
( Standard.Lib; TcBase.Lib; TcSystem.Lib; TcUtilities.Lib; are included automatically  )