FB_MemStackBuffer

FB_MemStackBuffer 1:

The FB_MemStackBuffer function block allows data records of varying lengths to be written into a buffer, or for data records that have previously been written there to be removed from the buffer. The buffer operates as a LIFO (Last In - First Out). Data records are read from it in the reverse sequence in which they were first written into the buffer.  This means that the newest entries are the first ones that are read. The buffer storage is provided to the function block via the input variables pBuffer and cbBuffer. Writing and reading the data records is controlled by action calls. The function block features the following tasks:

VAR_INPUT

VAR_INPUT
    pWrite   : DWORD; 
    cbWrite  : UDINT; 
    pRead    : DWORD; 
    cbRead   : UDINT; 
    pBuffer  : DWORD;
    cbBuffer : UDINT; 
END_VAR

pWrite: The address of the PLC variable or of a buffer variable that contains the value data that is to be written. The address can be determined with the ADR operator. The programmer is himself responsible for dimensioning the buffer variable in such a way that cbWrite data bytes can be taken from it.

cbWrite: The number of value data bytes that are to be written. (In the case of string variables this includes the final null).

pRead: The address of the PLC variables or of a buffer variable into which the value data that has been read is to be copied. The address can be determined with the ADR operator. The programmer is himself responsible for dimensioning the buffer variable in such a way that it can accept cbRead data bytes. The size of the buffer variables in bytes must be greater than or equal to the size of the data record that is to be read.

cbRead: The number of value data bytes to be read. If the buffer size is too small, data is not copied. The function block reports a buffer underflow error (bOk = FALSE ), and the buffer size required for the next data record that is to be read is returned at the cbReturn output.

pBuffer: Address of PLC variable (e.g. ARRAY[...] OF BYTES ) that is to be used by the function block as buffer storage. The address can be determined with the ADR operator.

cbBuffer: The maximum size, in bytes, of the PLC variables that is to be used as buffer storage. The size can be determined by the SIZEOF operator.

 

VAR_OUTPUT

VAR_OUTPUT
    bOk     :BOOL;
    nCount  :UDINT;
    cbSize  :UDINT;
    cbReturn    :UDINT;
END_VAR

bOk: Supplies TRUE if a new data record was inserted/deleted successfully. Supplies FALSE if a buffer overflow occurs or if no more entries do exist in the buffer.

nCount: Supplies the current number of buffered data records.

cbSize: Supplies the current number of stored data bytes in the buffer. The number of  occupied data bytes is always bigger than the actual number of written value data.Each data record is complemented by addtional information to be localised later.

cbReturn: The number of value data bytes successfully read. If a read buffer underflow error has occurred, this output supplies the necessary read buffer size in bytes. In this case the cbRead length is too small.

 

Example:

The following example illustrates a simple application of the function block. Strings with different length should be buffered. A rising edge at bReset deletes all buffer entries. If you set bAdd = TRUE a ten new string values will be written into the buffer. With a rising edge at bRemove the newest/latest string is removed. With a rising edge at bGet the newest/latest string is read but not removed.

 

Declaration:

PROGRAM MAIN
VAR
    buffer  : ARRAY[0..1000] OF BYTE;
    fbStack : FB_MemStackBuffer;

    bReset  : BOOL := TRUE;
    bAdd    : BOOL := TRUE;
    bGet    : BOOL := TRUE;
    bRemove : BOOL := TRUE;

    putEntry    : ARRAY[0..9] OF STRING(20) := 'Str_1', 'Str_2', 'Str_3', 'Str_4', 'Str_5', 'Str_6', 'Str_7', 'Str_8', 'Str_9', 'Str_10';
    getEntry    : STRING;
    i       : UDINT;
END_VAR


Program:

IF bReset THEN(* Clear buffer *)
    bReset := FALSE;
    fbStack.A_Reset( pBuffer := ADR( buffer ), cbBuffer := SIZEOF( buffer ) );
END_IF

IF bAdd THEN(* Add entries *)
    bAdd := FALSE;
    FOR i:= 0 TO 9 BY 1 DO
        fbStack.A_Push( pBuffer := ADR(buffer), cbBuffer := SIZEOF(buffer), pWrite := ADR(putEntry[i]), cbWrite := LEN(putEntry[i]) + 1 );
        IF fbStack.bOk THEN(* Success *)
            ;
        ELSE(* Buffer overflow *)
            ;
        END_IF
    END_FOR
END_IF

IF bGet THEN(* Peek newest entry *)
    bGet := FALSE;
    fbStack.A_Top( pBuffer := ADR(buffer), cbBuffer := SIZEOF(buffer), pRead := ADR(getEntry), cbRead := SIZEOF(getEntry) );
    IF fbStack.bOk THEN(* Success *)
        ;
    ELSE(* Buffer is empty *)
        ;
    END_IF
END_IF

IF bRemove THEN(* Remove newest entry *)
    bRemove := FALSE;
    fbStack.A_Pop( pBuffer := ADR(buffer), cbBuffer := SIZEOF(buffer), pRead := ADR(getEntry), cbRead := SIZEOF(getEntry) );
    IF fbStack.bOk THEN(* Success *)
        ;
    ELSE(* Buffer is empty *)
        ;
    END_IF
END_IF

Requirements

Development environment

Target system type

PLC libraries to be linked

TwinCAT v2.11.0 Build > 2211

PC or CX (x86, ARM)

TcUtilities.Lib