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.
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
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