FB_IEC870_5_101TBufferCtrl
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:
- RxRemoveObj (entfernt den ältesten Fifoeintrag aus dem RX-Fifo);
- RxReset (löscht alle RX-Fifoeinträge, setzt den RX-Fifo zurück);
- TxAddObj (fügt einen neuen Fifoeintrag in den TX-Fifo);
- TxReset (löscht alle TX-Fifoeinträge, setzt den TX-Fifo zurück)
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):
- IEC 60870-5-101 Zentralstation (master, unbalanced mode);
- IEC 60870-5-101 Unterstation (slave, unbalanced mode);
- IEC 60870-5-101 Zentralstation (master, balanced mode);
- IEC 60870-5-101 Unterstation (slave, balanced mode);
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) |