Search code examples
plctwincatstructured-textiec61131-3

Is it possible to add static parameters to function blocks?


Is it possible to write function blocks with some static parameterization? Specifically, can I make a buffer with a static capacity, but such that different instances can have different capacities?

Ideally, I'd imagine some constant parameters, like so:

FUNCTION_BLOCK FB_Buffer
VAR_INPUT CONSTANT
    StorageSize : DINT;
END_VAR
VAR
    Storage : ARRAY [1..StorageSize] OF REAL;
END_VAR

Instancing would then be something like this:

FUNCTION_BLOCK FB_Usage
VAR
    SmallBuffer : FB_Buffer := (StorageSize := 10);
    LargeBuffer : FB_Buffer := (StorageSize := 1000);
END_VAR

Assuming this isn't possible, what is the best approach to manage different storage sizes for different function block instances?

I'll post my least-bad workaround as an aswer.


Solution

  • I was thrown a little by your referencing of 'Static' variables, as VAR STAT is a separate thing to what you want, and used to make all instances of an FB share a common element.

    What you really are looking for are the wonders of FB_INIT and __NEW


    Example

    You have to manage your own data access, making sure you don't overflow and all the other dangerous things, but otherwise this should work as per your posted answer. Then initializing this code with a couple of different lengths is as simple as:

    FUNCTION_BLOCK FB_Usage
    VAR
      SmallBuffer : fb_DataArray( 100 );
      LargeBuffer : fb_DataArray( 10000 );
    END_VAR
    
    // Function block for handling a data array that is generated at boot time
    FUNCTION_BLOCK fb_DataArray
    VAR
      pZeroElem  : POINTER TO REAL;  // Pointer to the head of the array
      ArrayLength : UDINT;  // Length of the array in elements 
    END_VAR
    
    // Do something by indexing through ring
    
    METHOD FB_init : BOOL
    // Initialisation method for fb_DataArray, allocates memory space to array
    VAR
        bInitRetains    :   BOOL;   // required
        bInCopyCode     :   BOOL;   // required 
        Length          :   UDINT;  //  Number of element in the array
    END_VAR
    
    pZeroElem := __NEW( REAL, Length ); 
    // Generate a pointer to the first element of a dataspace that is precisely big enough for <Length> Real elements. 
    
    Method FB_exit
    // Needs to be called to de-allocate the memory space allocated in fb_init. 
    VAR
     bInCopyCode : BOOL; // Required
    END_VAR
    
    IF pZeroElem <> 0 THEN
      // Checks if the pointer is valid, then deletes the allocation
      __DELETE( pZeroElem ); 
    END_IF