FB_IEC870_5_101TBufferCtrl

FB_IEC870_5_101TBufferCtrl 1:

Mit diesem Funktionsbaustein kann der Inhalt des TX/RX-Datenpuffers manipuliert werden, der bei der Kommunikation über das IEC 60870-5-101/104 Low-Level Interface benutzt wird.

Der Funktionsbaustein besitzt folgende Aktionen:

Durch den Aufruf der oben aufgelisteten Aktionen kann der Inhalt des TX/RX-Datenpuffers verändert werden.

VAR_IN_OUT

VAR_IN_OUT
    buffer  : ST_IEC870_5_101TBuffer;
END_VAR

buffer: TX/RX-Datenpuffer. Die TX/RX-Pufferparameter (wie z.B. asduSize ) müssen vor der Benutzung konfiguriert werden.

VAR_INPUT

VAR_INPUT
    putObj  : ST_IEC870_5_101AOGen;
END_VAR

putObj: Dateneinheit (ASDU), die gesendet werden soll.

VAR_OUTPUT

VAR_OUTPUT
    getObj  : ST_IEC870_5_101AOGen;
    bOk     : BOOL;
END_VAR

getObj: Empfangene Dateneinheit (ASDU).

bOk: Diese Variable wird TRUE, wenn ein neuer Eintrag erfolgreich hinzugefügt oder aus dem Fifo entfernt wurde. Diese Variable wird FALSE beim Pufferüberlauf und wenn kein Eintrag entfernt werden konnte weil der Fifo bereits leer ist.

Beispiele (Low-Level Interface):

Weitere Beispiele:

Folgendes Beispielcode (Ausschnitt) demonstriert die Benutzung der Baustein-Aktionen. Alle ~100ms (tCycle) wird eine neue ASDU (M_BO_TB_1) mit der Übertragungsursache: Spontan und Zeitstempel generiert und in den TX-Fifo abgelegt.
Die empfangenen Testkommandos (C_TS_TA_1) und Uhrzeitsynchronisationskommandos (C_CS_NA_1) werden aus dem RX-Fifo entfernt und mit gespiegelten ASDUs beantwortet.

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

Voraussetzungen

Entwicklungsumgebung

Zielplattform

Einzubindende SPS Bibliotheken (Kategoriegruppe)

TwinCAT v3.1.4012.0

PC oder CX (x86, x64, ARM)

Tc2_IEC60870_5_10x (Communication->IEC60870)
Tc2_SerialCom (Communication->Serial)
Tc2_TcpIp (Communication->TcpIp)
Tc2_Utilities (System)