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.

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
VAR CONSTANT
    MAX_BUFFER_SIZE : UDINT := 1000;
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