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.
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:
- RxRemoveObj (removes the oldest Fifo entry from the RX-Fifo);
- RxReset (deletes all RX-Fifo entries,resets the RX-Fifo);
- TxAddObj (inserts a new Fifo entry in the TX-Fifo);
- TxReset (deletes all TX-Fifo entries, resets the TX-Fifo)
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 |