Example: Memory ring FiFo (FB_MemRingBuffer)
The complete source can be found here: MemRingBufferExample.zip
The following example illustrates a simple application of the function block. Data records with the same length should be buffered ( but not not mandatory). The data records have the following structure:
TYPE ST_DataSetEntry :
STRUCT
bFlag : BOOL;
nValue : BYTE;
sMsg : STRING(20) := 'Unknown';
END_STRUCT
END_TYPE
Interface of function block FB_DataSetFifo:
The application specific function block used in the sample: FB_DataSetFifo uses internally the function block FB_MemRingBuffer. This function block simplifies the inserting/removing of data records. Furthermore the new function block supplies the current percental fill status of the buffer and an overwrite option.
If the intput bOverwrite is set and the buffer is full, the oldest entry will be removed from the buffer and overwritten by the newest one.
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
The main program::
A rising edge at bReset deletes all buffer entries. If you set bAdd = TRUE a new data record will be written into the ring buffer file, and when bRemove =TRUE the oldest data record is removed. With a rising edge at bGet the oldest data record is read but not removed.
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