Beispiel: Memory-Ring-FiFo (FB_MemRingBuffer)

Die kompletten Sourcen finden Sie hier: MemRingBufferExample.zip

Folgendes Beispiel zeigt eine einfache Verwendung des Funktionsbausteins. Es sollen Datensätze mit der gleichen Länge gepuffert werden (dies ist aber nicht zwingend notwendig). Die Datensätze haben folgende Struktur:

TYPE ST_DataSetEntry :
STRUCT
    bFlag  : BOOL;
    nValue : BYTE;
    sMsg   : STRING(20) := 'Unknown';
END_STRUCT
END_TYPE

Die Schnittstelle des FB_DataSetFifo-Funktionsbausteins:

Der im Beispielprojekt verwendete applikationsspezifische Funktionsbaustein FB_DataSetFifo benutzt intern den FB_MemRingBuffer-Funktionsbaustein. Dieser Baustein vereinfacht das Hinzufügen/Entfernen der Datensätze. Außerdem liefert der neue Funktionsbaustein den aktuellen prozentualen Füllstatus des Puffers und eine Overwrite-Option. Wenn bOverwrite-Eingang gesetzt ist und der Puffer bereits voll ist, dann wird der älteste Eintrag aus dem Puffer entfernt und mit dem neuen überschrieben.

VAR_GLOBAL CONSTANT
    MAX_BUFFER_SIZE : UDINT := 1000;
END_VAR
FUNCTION_BLOCK FB_DataSetFifo
VAR_INPUT
    bOverwrite : BOOL;
    in         : ST_DataSetEntry;
END_VAR
VAR_OUTPUT
    bOk        : BOOL;
    nCount     : UDINT;
    nLoad      : UDINT;
    out        : ST_DataSetEntry;
END_VAR
VAR
    arrBuffer  : ARRAY[0..MAX_BUFFER_SIZE] OF BYTE; (* Buffer memory used by FB_MemRingBuffer function block *)
    fbBuffer   : FB_MemRingBuffer;
END_VAR

Das Hauptprogramm:

Die steigende Flanke am bReset löscht alle Puffer Einträge. Wenn Sie bAdd = TRUE setzen wird ein neuer Datensatz in den Ringpuffer geschrieben und beim bRemove=TRUE wird der älteste Datensatz entfernt. Bei einer steigenden Flanke am bGet wird der älteste Datensatz gelesen, aber nicht entfernt.

PROGRAM MAIN
VAR
    fbFifo      : FB_DataSetFifo := ( bOverwrite := TRUE );
    newEntry    : ST_DataSetEntry;
    oldEntry    : ST_DataSetEntry;
    bSuccess    : BOOL;
    nCount      : UDINT;
    nLoad       : UDINT;

    bReset      : BOOL := TRUE;
    bAdd        : BOOL := TRUE;
    bGet        : BOOL := TRUE;
    bRemove     : BOOL := TRUE;
END_VAR
IF bReset THEN
    bReset := FALSE;
    (* reset fifo (clear all entries) *)
    fbFifo.A_Reset( in := newEntry, bOk=>bSuccess, nCount=> nCount, nLoad => nLoad );
END_IF

IF bAdd THEN
    bAdd := FALSE;

    (* create new or modify data set entry *)
    newEntry.bFlag  := NOT newEntry.bFlag;
    newEntry.nValue := newEntry.nValue + 1;
    newEntry.sMsg   := BYTE_TO_STRING(newEntry.nValue);

    (* add new entry to the fifo *)
    fbFifo.A_Add( in := newEntry, bOk=>bSuccess, nCount=> nCount, nLoad => nLoad );
END_IF

IF bGet THEN
    bGet := FALSE;
    (* get (but not delete) oldest entry *)
    fbFifo.A_Get( out => oldEntry, bOk => bSuccess, nCount => nCount, nLoad => nLoad );
END_IF

IF bRemove THEN
    bRemove:= FALSE;
    (* remove oldest entry *)
    fbFifo.A_Remove( out => oldEntry, bOk => bSuccess, nCount => nCount, nLoad => nLoad );
END_IF

Voraussetzungen

Entwicklungsumgebung

Zielplattform

Einzubindende SPS-Bibliotheken (Kategoriegruppe)

TwinCAT v3.1.0

PC oder CX (x86, x64, Arm®)

Tc2_Utilities (System)