Parameter Handling

There are several ways for supplying values (from the caller) to a function, a function block or its methods (the callee). These values are necessary to influence the implemented processing. First of all, we can distinguish the methods used to transport the values.

Parameter transfer by value:

With this method, the values of the parameters are copied e.g. from the address space of the caller to the address space of the callee. It is noticeable that the time required for the copying process depends on the amount of data to be copied. The more memory space the parameter types occupy, the longer the time required to copy the data into the address space of the callee. However, this disadvantage also has the advantage that the callee receives a private copy of the data and its changes to it do not have an effect on the callers site.

A transmission by value takes place for the ranges VAR_INPUT, VAR_INPUT CONSTANT and VAR_OUTPUT. If the chosen data types are related to the keywords REFERENCE TO, POINTER TO or INTERFACE the address of the variable will be copied.

Parameter transfer by reference:

The other method determines the addresses of the values in the memory space of the caller and transmits only these addresses, the so called references to the parameter values, in to the address space of the callee. For each parameter, only the amount of memory corresponding to the size of an address on the related processor platform must be transferred. The time for parameter transport therefore depends only on the number of parameters, but not on the size of the data types used. With this advantage you may also buy yourself a disadvantage. You can now access the same data from more than one site. This can lead to unwanted side effects if you don’t take care of the mutual exclusion before accessing the shared data.

A transmission by reference takes place for the ranges VAR_INOUT, and VAR_INOUT CONSTANT, as well as for the data types related to the keywords REFERENCE TO, POINTER TO and INTERFACE.

Each program organizational unit (POU) of an application (PROGRAM, FUNCTION_BLOCK, FUNCTION, METHOD, PROPERTY) has its own memory area (context). Selecting a specific keyword for a certain variable range determines who (caller or callee) has read and/or write access to the range.

Access Rights

Area

Caller

Callee

Transfer

VAR_INPUT

read/write

read only

by value

VAR_INPUT CONSTANT

read/write once

read only

by value

VAR_OUTPUT

read only

write only

by value

VAR_IN_OUT

read/write

read/write

by reference

VAR_IN_OUT CONSTANT

read/write

read only

by reference

VAR_INPUT

The data in this area is provided by the caller (writer) and should by the called POU only be read. See rule SA0037 of the CODESYS Static Analysis “Write access to input variables”. The transfer method used is by value. The CODESYS compiler will initialize the input variables of a PROGRAM or FUNCTION_BLOCK with default values. So the initialisation of the input variables by the caller is optional and it is possible to use “unconnected” input variables in this context.

_images/static_analysis.png

VAR_INPUT CONSTANT

The variables in this area should only be initialized once after the caller has declared this variable. The data should then read only by the callee.

Note

Please take a look to the article Parameterization with parameter lists. The VAR_INPUT CONSTANT construct is part of a convention for declarative parameterization of function blocks.

The variables in this area are treated separately in the language CFC and are offered for editing in a specific parameter editor. The transfer method used is by value.

UserError1: CEH.ErrorBase := (
    udiID:= 1,
    xAutoReset:= FALSE,
    tOnDelay:= T#500MS,
    bseEffects:=            CEH.EFFECTS.LOCAL_EFFECT_1
                    OR      CEH.EFFECTS.LOCAL_EFFECT_3
);
FUNCTION_BLOCK ErrorBase EXTENDS Element IMPLEMENTS IErrorProvider
VAR_INPUT CONSTANT
    udiID : UDINT;
    xAutoReset : BOOL;
    tOnDelay : TIME;
    {attribute 'displaymode':='hex'}
    bseEffects : BITSET_ELEMENT;
END_VAR
VAR_INPUT
    itfErrorHandler : IErrorProviderProtocol := 0;
    xEnable : BOOL := TRUE;
    xCondition : BOOL;
END_VAR
VAR_OUTPUT
    xError : BOOL;
    tTimeToError : TIME;
    tTimeErrorActive : TIME;
END_VAR
_images/var_input_constant.png

VAR_OUTPUT

After the caller has executed the callee, the data in this area is provided by the callee (writer) to the caller (reader). The caller has read access. The callee should only write this data. See rule SA0038 of the CODESYS Static Analysis “Read access to output variables”. The transfer method used is by value. The CODESYS compiler will initialize the output variables of a PROGRAM or FUNCTION_BLOCK with default values. So the initialisation of the output variables by the callee is optional and it is possible to use “unconnected” output variables in this context.

VAR_IN_OUT

The original approach to this type of variable range was the need for two-way data exchange. In order for both sides to be able to exchange data, each participant must have access to the same memory area. Therefore, only a reference to the shared memory can be passed on to the called party and not a copy. The transfer method by reference will therefore have to be used. In this case, it is important to take into account that undesired side effects can occur if more than one party is working simultaneously with the shared memory. In order to avoid undesirable side effects, mutual exclusion must be guaranteed. Since the transfer of data can only work via references, it is not possible to work directly with constants or literals (e. g. numbers or strings). Constants and literals can only be accessed read-only, but the VAR_IN_OUT type of variable range explicitly requires both sides to have read and write access. The reference to the shared memory must be passed from the caller to the calleee. It must be ensured that the access to the referenced memory area is possible only after the caller has initialized the reference. In particular, you must not access variables of a function block of type VAR_IN_OUT in the context of its methods, because it cannot ensured, that the initialization was carried out by calling the function block beforehand.

VAR_IN_OUT CONSTANT

Everything that has been said about the variable range VAR_IN_OUT also applies to the variable range VAR_IN_OUT CONSTANT. In addition, this new range allows the use of literals and constants. Now the called party is no longer allowed to write to the variables of this area, so that references to constants or literals can also be used. Again the transfer method by reference will therefore have to be used.

Consistency

When one of the two sides accesses the variables of a block, it is generally expected that the value is either transferred completely or that this value is replaced by the value of a concurrent executed access. The data from the two accesses must never be mixed. The guarantee of consistent data transmission can be given for all data types whose size corresponds to the natural register size of the processor model used. For larger data areas, consistent data transport must be ensured by means of self-imposed measures (e. g. mutual exclusion).

Especially the data types from the list below require special attention while implementing the required behaviour to ensure a consistent data transport.

  • (W)STRING

  • (W)STRING(n)

  • ARRAY

  • STRUCT

CODESYS comes with several libraries that can be used to implement a consistent data transport. Please have a look at CAA_MemBlockMan. library, ElementsCollection. library, and some more.