### REXLANG – User programmable block

Block SymbolLicensing group: REXLANG

Function Description
The standard function blocks of the REXYGEN system cover the most typical needs in control applications. But there still exist situations where it is necessary (or more convenient) to implement an user-defined function. The REXLANG block covers this case. It implements an user-defined algorithm written in a scripting language very similar to the C language (or Java).

Scripting language
As mentioned, the scripting language is similar to the C language. Nevertheless, there are some differences and limitations:

• Double, long and string data types are supported (it is possible to use int, short, bool as well, but these are internally converted to long. The float type can be used but it is converted internally to double. The typedef type is not defined.
• Pointers and structures are not implemented. However, it is possible to define arrays and use the indexes (the [ ] operator). Block inputs, outputs and parameters can not be arrays.
• The ’,’ operator is not implemented.
• The preprocessor supports the following commands: #include, #define, #ifdef .. [#else .. ] #endif, #ifndef .. [#else .. ] #endif (i.e. #pragma and #if .. [#else .. ] #endif are not supported).
• The standard ANSI C libraries are not implemented, however the majority of mathematic functions from math.h and some other functions are implemented (see the text below).
• The input, output and parameter keywords are defined for referencing the REXLANG block inputs, outputs and parameters. System functions for controlling the execution and diagnostics are implemented (see the text below).
• The main() function is executed periodically during runtime. Alongside the main() function the init() (executed once at startup), exit() (executed once when the control algorithm is stopped) and the parchange() (executed on parameters change in REXYGEN.
• The functions and procedures without parameters must be explicitly declared void.
• The identifiers cannot be overloaded, i.e. the keywords and built-in functions cannot share the name with an identifier. The local and global variables cannot share the same name.
• Array initializers are not supported. Neither in local arrays nor the global ones.
• User defined return values of main(), init() and exit() functions are written to iE output. Values < -99 will stop algorithm execution (reinicialization by RESET input needed for further algorithm run). Return values:

iE >= 0 …No error occurred

0 > iE >= -99 …Warning, no changes to function block algorithm execution

iE < -99 …Error occured, function block algorithm execution stopped

Scripting language syntax
The scripting language syntax is based on the C language, but pointers are not supported and the data types are limited to long and double. Moreover the input, output and parameter keywords are defined for referencing the REXLANG block inputs, outputs and parameters. The syntax is as follows:

• <type> input(<input number>) <variable name>;
• <type> output(<outpt number>) <variable name>;
• <type> parameter(<parameter number>) <variable name>;

The input and parameter variables are read-only while the output variables are write-only. For example:

double input(1) input_signal; /* declaration of a variable of type
double, which corresponds with the
u1 input of the block */
long output(2) output_signal; /* declaration of a variable of type
long, which corresponds with the y2
output of the block */

input_signal = 3;               //not allowed, inputs are read-only
sum = output_signal + 1;        //not allowed, outputs are write-only
if (input_signal>1) output_signal = 3 + input_signal;  //correct

Available functions
The following functions are available in the scripting language:

• Mathematic functions (see ANSI C, math.h):
atan, sin, cos, exp, log, sqrt, tan, asin, acos, fabs, fmod, sinh, cosh, tanh, pow, atan2, ceil, floor and abs Please note that the abs function works with integer numbers. All the other functions work with variables of type double.
• Vector functions (not part of ANSI C)
double max([n,]val1,…,valn)

Returns the maximum value. The first parameter defining the number of items is optional.

double max(n,vec)

Returns the value of maximal item in the vec vector.

double min([n,]val1,…,valn)

Returns the minimum value. The first parameter defining the number of items is optional.

double min(n,vec)

Returns the value of minimal item in the vec vector.

double poly([n,]x,an,…,a1,a0)

Evaluates the polynomial $\mathtt{\text{y}}=\mathtt{\text{an}}\ast {\mathtt{\text{x}}}^{\mathtt{\text{n}}}+\dots +\mathtt{\text{a1}}\ast \mathtt{\text{x}}+\mathtt{\text{a0}}$. The first parameter defining the number of items is optional.

double poly(n,x,vec)

Evaluates the polynomial $\mathtt{\text{y}}=\mathtt{\text{vec[n]}}\ast {\mathtt{\text{x}}}^{\mathtt{\text{n}}}+\dots +\mathtt{\text{vec[1]}}\ast \mathtt{\text{x}}+\mathtt{\text{vec[0]}}$.

double scal(n,vec1,vec2)

Evaluates the scalar product $\mathtt{\text{y}}=\mathtt{\text{vec1[0]}}\ast \mathtt{\text{vec2[0]}}+\dots +\mathtt{\text{vec1[n-1]}}\ast \mathtt{\text{vec2[n-1]}}$.

double scal(n,vec1,vec2,skip1,skip2)

Evaluates the scalar product $\mathtt{\text{y}}=\mathtt{\text{vec1[0]}}\ast \mathtt{\text{vec2[0]}}+\mathtt{\text{vec1[skip1]}}\ast \mathtt{\text{vec2[skip2]}}+\dots +\mathtt{\text{vec1[(n-1)*skip1]}}\ast \mathtt{\text{vec2[(n-1)*skip2]}}$. This is well suited for multiplication of matrices, which are stored as vectors (line by line or column by column).

double conv(n,vec1,vec2)

Evaluates the convolutory product $\mathtt{\text{y}}=\mathtt{\text{vec1[0]}}\ast \mathtt{\text{vec2[n-1]}}+\mathtt{\text{vec1[1]}}\ast \mathtt{\text{vec2[n-1]}}+\dots +\mathtt{\text{vec1[n-1]}}\ast \mathtt{\text{vec2[0]}}$.

double sum(n,vec)

Sums the items in a vector, i.e. $\mathtt{\text{y}}=\mathtt{\text{vec[0]}}+\mathtt{\text{vec[1]}}+\dots +\mathtt{\text{vec[n-1]}}$.

double sum([n,]val1,…,valn)

Sums the items, i.e. $\mathtt{\text{y}}=\mathtt{\text{val1}}+\mathtt{\text{val2}}+\dots +\mathtt{\text{valn}}$. The first parameter defining the number of items is optional.

[]array([n,]an-1,…,a1,a0)

Returns an array/vector with the given values. The first parameter defining the number of items is optional. The type of the returned value is chosen automatically to fit the type of parameters (all must be of the same type).

[]subarray(idx,vec)

Returns a subarray/subvector of the vec array, starting at the idx index. The type of the returned value is chosen automatically according to the vec array.

copyarray(count,vecSource,idxSource,vecTarget,idxTarget)

Copies count items of the vecSource array, starting at idxSource index, to the vecTarget array, starting at idxTarget index. Both arrays must be of the same type.

void fillarray(vector, value, count)

Copies value to count items of the vector array (always starting from index 0).

• String functions (ANSI C contains analogous functions in the string.h file)
string strsub(str,idx,len)

Returns a substring of length len starting at index idx.

long strlen(str)

Returns string length (number of characters).

long strfind(str,substr)

Returns the position of first occurrence of substr in str.

long strrfind(str,substr)

Returns the position of last occurrence of substr in str.

strreplace(str,pattern,substr)

Find all occurrences of pattern in str and replace it with substr (in-place replacement, so new string is stored into str).

strupr(str)

Converts a string to uppercase.

strlwr(str)

Converts a string to lowercase.

long str2long(str [, default])

Converts string to integer number. The first non-numerical character is considered the end of the input string and the remaining characters are ignored. If conversion failed, 2nd parameter is returned (or 0 if parameter is not set).

double str2double(str [, default])

Converts string to a decimal number. The first non-numerical character is considered the end of the input string and the remaining characters are ignored. If conversion failed, 2nd parameter is returned (or 0 if parameter is not set).

Converts an integer number num to text. The optional parameter radix specifies the numerical system in which the conversion is to be performed (typically 10 or 16). If radix is not specified, default value is $\mathtt{\text{radix}}=10$. The output string does not contain any identification of the numerical system used (e.g. the 0x prefix for the hexadecimal system).

string double2str(num)

Converts a decimal number num to text.

strcpy(dest,src)

Function copies the src string to the dest string. Implemented for compatibility with ANSI C. The construction dest=src yields the same result.

strcat(dest,src)

Function appends a copy of the src string to the dest string. Implemented for compatibility with ANSI C. The construction dest=dest+src yields the same result.

strcmp(str1,str2)

Function compares strings str1 and str2. Implemented for compatibility with ANSI C. The construction str1==str2 yields the same result.

float2buf(buf,x[,endian])

Function for converting real number x into 4 elements of array buf. Each element represents an octet (byte) of number in single precision representation according to IEEE 754 (known as float). The function is useful for filling communication buffers. Optional 3rd parameter has the following meaning: 0 (default) = processor native endian, 1 = little endian, 2 = big endian.

double2buf(buf,x[,endian])

Similar function to float2buf, but stores 8 elements in double precision format.

double buf2float(buf[,endian])

Inverse function to float2buf

double buf2double(buf[,endian])

Inverse function to double2buf

long RegExp(str,regexp,capture[])

Compares the str string with regular expression regexp. When the string matches the pattern, the capture array contains individual sections of the regular expression. capture[0] is always the complete regular expression. The function return the number of captured strings or a negative value in case of an error. The regular expression may contain the following:

(?i) …Must be at the beginning of the regular expression. Makes the matching case-insensitive.

̂ …Match beginning of a string

$…Match end of a string () …Grouping and substring capturing \s …Match whitespace \S …Match non-whitespace \d …Match decimal digit \n …Match new line character \r …Match line feed character \f …Match vertical tab character \v …Match horizontal tab character \t …Match horizontal tab character \b …Match backspace character + …Match one or more times (greedy) +? …Match one or more times (non-greedy) * …Match zero or more times (greedy) *? …Match zero or more times (non-greedy) ? …Match zero or once (non-greedy) x|y …Match x or y (alternation operator) \meta …Match one of the meta characters: ^$().[]*+?|\

\xHH …Match byte with hex value 0xHH, e.g. \x4a.

[...] …] Match any character from the set. Ranges like [a-z are supported.

[^...] …Match any character but the ones from the set.

long ParseJson(json,cnt,names[],values[])

The json string is supposed to contain text in JSON format. The names array contain property names of the requested objects (subitems are accessed via ., index of the array via [] - e.g. "cars[1].model" ). The values array then contains values of the requested objects. The cnt parameter defines the number of requested objects (length of both the names and values arrays). The function returns the number of values, negative numbers indicate errors.

Note: String variable is declared just like in ANSI C, i.e. char <variable name>[<maximum number of characters>];. For passing the strings to functions use char <variable name>[] or string <variable name>.

• System functions (not part of ANSI C)

Archive(arc, type, id, lvl_cnt, value)

Stores a value into the archive subsystem. arc is a bit mask of archives to write the events to (e.g. for writing to archives 3,5 set arc=20 -> (BIN)10100 = (DEC)20). The archives are numbered from 1 and the maximum number of archives is limited to 15 (archive no. 0 is an internal system log). type

1 …Bool

2 …Byte (U8)

3 …Short (I16)

4 …Long (I32)

5 …Word (U16)

6 …DWord (U32)

7 …Float (F32)

8 …Double (F64)

9 …Time

10 …Large (I64)

11 …Error

12 …String

17 …Bool Group

18 …Byte Group (U8)

19 …Short Group (I16)

20 …Long Group (I32)

21 …Word Group (U16)

22 …DWord Group (U32)

23 …Float Group (F32)

24 …Double Group (F64)

25 …Time Group

26 …Large Group (I64)

27 …Error Group

id is a unique archive item ID. lvl_cnt is Alarm level in case of alarms or number of elements in case of Group type. value is a value to be written or an array reference in case of Group type.

Trace(id, val)

Displays the id value and the val value. The function is intended for debugging. The id is a user-defined constant (from 0 to 9999) for easy identification of the displayed message. The val can be of any data type including text string. The output can be found in the system log of REXYGEN.

In order to view these debugging messages in System log it is necessary to enable them. Go to the menu
Target$\to$Diagnostic messages and tick the Information checkbox in the Function block messages box. Logging has to be also enabled for the particular block by ticking the Enable logging checkbox in the Runtime tab of the block parameters dialog. By default, this is enabled after placing a new block from library. Only then are the messages displayed in the System log.

TraceError(id, val) TraceWarning(id, val) TraceVerbose(id, val)

These commands are similar to the Trace command, only the output is routed to the corresponding logging group (Error, Warning, Verbose). Messages with the Error level are always written to the log. To view the Warning and Verbose messages, enable the corresponding message group. Go to the menu
Target$\to$Diagnostic messages and tick the corresponding checkbox in the Function block messages box.

Suspend(sec)

The script is suspended if its execution within the given sampling period takes more seconds than specified by the sec parameter. At the next start of the block the script continues from the point where it was suspended. Use Suspend(0) to suspend the code immediately.

double GetPeriod()

Returns the sampling period of the block in seconds.

double CurrentTime()

Returns the current time (in internal format). Intended for use with the ElapsedTime() function.

double ElapsedTime(new_time, old_time)

Returns the elapsed time in seconds (decimal number), i.e. the difference between the two time values new_time and old_time. The CurrentTime() function is typically used in place of the new_time parameter.

double Random()

Returns a pseudo-random number from the $⟨0,1\right)$ interval. The pseudo-random number generator is initialized prior to calling the init() function so the sequence is always the same.

long QGet(var)

Returns the quality of the var variable (see the QFC, QFD, VIN, VOUT blocks). The function is intended for use with the inputs, outputs and parameters. It always returns 0 for internal variables.

void QSet(var, value)

Sets the quality of the var variable (see the QFC, QFD, VIN, VOUT blocks). The function is intended for use with the inputs, outputs and parameters. It has no meaning for internal variables.

long QPropag($\mathtt{\text{[}}$n,$\mathtt{\text{]}}$val1,…,valn)

Returns the quality resulting from merging of qualities of val1,…,valn. The basic rule for merging is that the resulting quality correspond with the worst quality of val1,…,valn. To obtain the same behavior as in other blocks of the REXYGEN system, use this function to set the quality of output, use all the signals influencing the output as parameters.

Reads a value from a file. A binary file with double values or a text file with values on individual lines is supposed. The idx index (binary file) or line number (text file) starts at 0. The file is identified by fileid. At present the following values are supported:

0 …file on a disk identified by the p0 parameter

1 …file on disk identified by name of the REXLANG block and extension .dat

2…file on a disk identified by the srcname parameter, but the extension is changed to .dat

3 rexlang.dat file in the current directory

4-7 …same like 0-3, but format is text file. Each line contains one number. The index idx is the line number and starts at zero. Value idx=-1 means next line (e.g. sequential writing).

void SaveValue(fileid, idx, value)

Stores the value to a file. The meaning of parameters is the same as in the LoadValue function.

void GetSystemTime(time)

Returns the system time. The time is usually returned as UTC but this can be altered by the operating system settings. The time parameter must be an array of at least 8 items of type long. The function fills the array with the following values in the given order: year, month, day (in the month), day of week, hours, minutes, seconds, milliseconds. On some platforms the milliseconds value has a limited precision or is not available at all (the function returns 0 ms).

void Sleep(seconds)

Stop execution of the block’s algorithm (and whole task) for defined time. Use this block with extreme caution and only if there is no other possibility to achieve the desired behaviour of your algorithm. The sleep interval should not exceed 900 milliseconds. The shortest interval is about 0.01s, the precise value depends on the target platform.

long GetExtInt(ItemID)

Returns the value of input/output/parameter of arbitrary block in REXYGEN algorithm. Such an external data item is referenced by the ItemID parameter. The structure of the string parameter ItemID is the same as in e.g. the sc parameter of the GETPI function block. If the value cannot be obtained (e.g. invalid or non-existing ItemID, data type conflict, etc.), the REXLANG block issues an error and must be reset.

long GetExtLong(ItemID)

See GetExtInt(ItemID).

double GetExtReal(ItemID)

Similar to GetExtInt(ItemID) but for decimal numbers.

double GetExtDouble(ItemID)

See GetExtReal(ItemID).

string GetExtString(ItemID)

Similar to GetExtInt(ItemID) but for strings.

void SetExt(ItemID, value)

Sets the input/output/parameter of arbitrary block in REXYGEN algorithm to value. Such an external data item is referenced by the ItemID parameter. The structure of the string parameter ItemID is the same as in e.g. the sc parameter of the SETPI function block. The type of the external data item (long/double/string) must correspond with the type of the value parameter. If the value cannot be set (e.g. invalid or non-existing ItemID, data type conflict, etc.), the REXLANG block issues an error and must be reset.

int BrowseExt(ItemID, first_subitem_index, max_count, subitems, kinds)

Function browses task adress space. If ItemID is a block identifier (block_path), subitems string array will contain names of all inputs, outputs, parameters and internal states. Function returns number of subitems or negative error code. kinds values: executive = 0, module = 1, driver = 2, archive = 3, level = 4, task = 5, quicktask = 6, subsystem = 7, block = 8, input = 9, output = 10, internal state = 11, parameter or state array = 12, special = 13.

long CallExt(ItemID)

Run (one step) arbitrary block in REXYGEN algorithm. Such an external block is referenced by the ItemID parameter. The structure of the string parameter ItemID is the same as in e.g. the sc parameter of the GETPI function block. The function returns result code of the calling block (see REXYGEN error codes). It is strongly recommended to call halted blocks only (set checkbox Halt on the property page Runtime in the parameters dialog of the block) and the block (or subsystem) should be in same task as the REXLANG block.

long GetInArrRows(input)

Returns the number of rows of the array that is attached to the input with index input of the REXLANG block.

long GetInArrCols(input)

Returns the number of columns of the array that is attached to the input with index input of the REXLANG block.

double GetInArrDouble(input, row, col)

Returns the member of the array that is attached to the input with index input of the REXLANG block.

Void SetInArrValue(input, row, col, value)

Sets the member of the array that is attached to the input with index input of the REXLANG block.

Void SetInArrDim(input, row, col)

Sets the dimension of the array that is attached to the input with index input of the REXLANG block.

long memrd32(hMem, offset)

long memwr32(hMem, offset, value)

Writing to physical memory. Get the handle by OpenMemory("/dev/mem",<physical address>,<area size>).

• Communication functions (not part of ANSI C)

This set of functions is intended for communication over TCP/IP, UDP/IP, serial line (RS-232 or RS-485), SPI bus and I2C bus. Only a brief list of available functions is given below, see the example projects of the REXYGEN system for more details.

long OpenFile(string filename)

Function for opening a file. Identification number (the so-called handle) of the file is returned. If a negative value is returned, the opening was not successful.

long OpenCom(string comname, long baudrate, long parity)

Function for opening a serial line. Identification number (the so-called handle) of serial port is returned. If a negative value is returned, the opening was not successful. Parity setting: 0=none, 1=odd, 2=even.

long OpenUDP(string localname, long lclPort, string remotename, long remPort)

Function for opening a UDP socket. Identification number (the so-called handle) of the socket is returned. If a negative value is returned, the opening was not successful.

long OpenTCPsvr(string localname, long lclPort)

Function for opening a TCP socket (server, listening). Identification number (the so-called handle) of the socket is returned. If a negative value is returned, the opening was not successful.

long OpenTCPcli(string remotename, long remPort)

Function for opening a TCP socket (client). Identification number (the so-called handle) of the socket is returned. If a negative value is returned, the opening was not successful.

long OpenI2C(string devicename)

Function for opening the I2C bus. Identification number (the so-called handle) of the bus is returned. If a negative value is returned, the opening was not successful.

long OpenSPI(string devicename)

Function for opening the SPI bus. Identification number (the so-called handle) of the bus is returned. If a negative value is returned, the opening was not successful.

long OpenMemory(string devicename, long baseaddr, long size)

Function for mapping physical memory. Identification number (the so-called handle) of the memory address is returned. If a negative value is returned, the opening was not successful.

long OpenDevice(string filename)

Same as OpenFile(), but Write() or Read() are not-blocking (e.g. if data are not readable/writeable, function return immediately with return code -1).

long OpenSHM(string devicename, long deviceid, long size, long flags)

Function for mapping shared memory ( linux only, call shmget() ).

void Close(long handle)

Closes the socket, serial line, file or any device opened by the Open... functions.

void SetOptions(long handle, long params[])

Sets the parameters of a socket or serial line. The array size must be at least:

• 22 for serial line,
• 2 for file (1st item is mode: 1=seek begin, 2=seek current, 3=seek end, 4=set file end, 2nd item is offset for seek),
• 3 for SPI (1st item is SPI mode, 2nd item is bits per word, 3rd item is max speed in Hz),
• 5 for I2C (1st item is slave address, 2nd item is 10-bit address flag, 3rd item is Packet Error Checking flag, 4th item is nuber of retries, 5th item is timeout)
void GetOptions(long handle, long params[])

Reads parameters of a socket or serial line to the params array. The array size must be big enough, at least 2 for files, 2 for a socket and 22 for serial line (see SetOptions).

long Accept(long hListen)

Accepts the connection to listening socket hListen invoked by the client. A communication socket handle or an error is returned.

long Read(long handle, long buffer[], long count)

Receives data from a serial line or socket. The count parameter defines the maximum number of bytes to read. The count of bytes read or an error code is returned. Each byte of incoming data is put to the buffer array of type long in the corresponding order.

It is also possible to use the form
long Read(long handle, string data[], long count) (i.e. a string is used instead of a data array; one byte in the input file corresponds to one character; not applicable to binary files).
The error codes are:

 -1 it is necessary to wait for the operation to finish (the function is "non-blocking") -309 reading failed; the operating system error code appears in the log (when function block logging is enabled) -307 file/socket is not open
long Write(long handle, long buffer[], long count)

Sends the data to a serial line or socket. The count parameter defines the number of bytes to send. The count of bytes or en error code sent is returned. Each byte of outgoing data is read from the buffer array of type long in the corresponding order.

It is also possible to use the form
long Write(long handle, string data) (i.e. a string is used instead of a data array; one byte in the output file corresponds to one character; not applicable to binary files).
The error codes are:

 -1 it is necessary to wait for the operation to finish (the function is "non-blocking") -310 write failed; the operating system error code appears in the log (when function block logging is enabled) -307 file/socket is not open

Read one line from (text) file, serial line or socket; read characters are in the variable data up to allocated size of the string; the function return real size (number of bytes) of line or error code.

long DeleteFile(string filename)

Delete file. Return 0 if success; negative value is error code.

long RenameFile(string filename, string newfilename)

Rename file. Return 0 if success; negative value is error code.

bool ExistFile(string filename)

Return true if file or device exist (is it possible to open it for reading).

long I2C(long handle, long addr, long bufW[], long cntW, long bufR[], long cntR)

Communication over the I2C bus. Works only in Linux operating system on devices with the I2C bus (e.g. Raspberry Pi). Sends and receives data to/from the slave device with address addr. The parameter handle is returned by the OpenI2C function, whose parameter defines the device name (according to the operating system). The parameter bufW is a buffer (an array) for the data which is sent out, cntW is the number of bytes to send out, bufR is a buffer (an array) for the data which comes in and cntR is the number of bytes to receive. The function returns 0 or an error code.

long SPI(long handle, 0, long bufW[], long cntW, long bufR[], long cntR)

Execution of one transaction over the SPI bus. Works only in Linux operating system on devices with the SPI bus (e.g. Raspberry Pi). The parameter handle is returned by the OpenSPI function, whose parameter defines the device name (according to the operating system). The second parameter is always 0 (reserved for internal use). The parameter bufW is a buffer (an array) for the data which is sent out, cntW is the number of bytes to send out, bufR is a buffer (an array) for the data which comes in and cntR is the number of bytes to receive. Note that SPI communication is full-duplex, therefore the resulting length of the SPI transaction is given by maximum of the cntW and cntR parameters, not their sum. The function returns 0 or an error code.

long Seek(long handle, long mode[], long offset)

Set position for Read/Write command. Parameter mode means: 1=offset from begin of the file, 2= offset from current position, 3=offset from end of the file.

long Recv(long handle, long buffer[], long count)

long Send(long handle, long buffer[], long count)

long crc16(data,length,init,poly,flags,offset)

Compute 16-bit cyclic redundand code that is used as checksum/hash in many comunication protocols. data byte array (represented by long array) or string to compute hash length number of bytes in input array/text (could be -1 for whole string) init so called initial vector poly so called control polynom flags 1...revert bit order (in input bytes as so as in result crc), 2...result crc is xored with 0xFFFF, 4...if data is long array, all 4 bytes in long are procesed (LSB first), 8... same like 4, but MSB first offset index of the first processed byte in data array (usually 0) Notice: there is same function for 32-bit CRC long crc32(data,length,init,poly,flags,offset), and for 8-bit CRC long crc8(data,length,init,poly,flags,offset). Initial vector, control polynom, flags for many protocols could be found on https://crccalc.com/ Examples: MODBUS: crc16("123456789",-1,0xFFFF,0x8005,1,0)); DECT-X: crc16("123456789",-1,0,0x0589,0,0));

Remarks

• The data type of inputs u0..u15, outputs y0..y15 and parameters p0..p15 is determined during compilation of the source code according to the input, output and parameter definitions.
• All error codes < -99 require restarting of the REXLANG function block by input RESET. Of course it is necessary to remove the cause of the error first.
• WARNING! – The inputs and outputs of the block cannot be accessed within the init() function (the values of inputs are 0, outputs are not set).
• It is possible to include path in the srcname parameter. Otherwise the file is expected directly in the project directory or in the directories specified by the -I command line option of the REXYGEN Compiler compiler.
• All parameters of the vector functions are of type double (or array of type double). The only exception is the n parameter of type long. Note that the functions with one vector parameter exist in three variants:

double function(val1,…,valn)

Vector is defined as a sequence of values of type double.

double function(n,val1,…,valn)

Vector is defined as in the first case, only the first parameter defines the number of values – the size of the vector. This variant is compatible with the C compiler. The n parameter must be a number, not the so-called const variable and it must correspond with the number of the following elements defining the vector.

double function(n,vec)

The n parameter is an arbitrary expression of type long and defines the number of elements the function takes into account.

• The optional parameter n of the vector functions must be specified if the compatibility with C/C++ compiler is required. In such a case all the nonstandard functions must be implemented as well and the functions with variable number of parameters need to know the parameter count.
• In all case it is important to keep in mind that the vectors start at index 0 and that the array limits are not checked (just like in the C language). E.g. if double vec[10], x; is defined, the elements have indexes 0 to 9. The expression x=vec[10]; is neither a syntax nor runtime error, the value is not defined. More importantly, it is possible to write vec[11]=x;, which poses a threat, because some other variable might be overwritten and the program works unexpectedly or even crashes.
• Only the parser error and line number are reported during compilation. This means a syntax error. If everything seems fine, the problem can be caused by identifier/keyword/function name conflict.
• All jumps are translated as relative, i.e. the corresponding code is restricted to 32767 instructions (in portable format for various platforms).
• All valid variables and temporary results are stored in the stack, namely:
• Global variables and local static variables (permanently at the beginning of the stack)
• Parameters of functions
• Local function variables
• Return value of function
• Temporary results of operations (i.e. the expression a=b+c; is evaluated in the following manner: b is stored in the stack, c is stored in the stack (it follows after b), the sum is evaluated, both values are removed from the stack and the result is stored in the stack

Each simple variable (long or double) thus counts as one item in the stack. For arrays, only the size is important, not the type.

• The arrays are passed to the functions as a reference. This means that the parameter counts as one item in the stack and that the function works directly with the referenced array, not its local copy.
• If the stack size is not sufficient (less than space required for global variables plus 10), the stack size is automatically set to twice the size of the space required for the global variables plus 100 (for computations, function parameters and local variables in the case that only a few global variables are present).
• If basic debug level is selected, several checks are performed during the execution of the script, namely initialization of the values which are read and array index limits. Also a couple of uninitialized values are inserted in front of and at the back of each declared array. The NOP instructions with line number of the source file are added to the *.ill file.
• If full debug is selected, additional check is engaged – the attempts to access invalid data range are monitored (e.g. stack overflow).
• The term instruction in the context of this block refers to an instruction of a processor-independent mnemocode. The mnemocode is stored in the *.ill file.
• The Open() function set serial line always 19200Bd, no parity, 8 bit per character, 1 stopbit, binary mode, no timeout. Optional 2nd (bitrate) and 3th (parity) parametrs can be used in the Open() function.
• Accessing text file is significantly slower that binary file. A advantage of the text file is possibility view/edit data in file without special editor.
• This block does not call the parchange() function. It is necessary to call it in init() function (if it is required).
• The block’s inputs are available in the init() function, but all are equal to zero. It is possible (but not common) to set block’s outputs.
• The Open() function also allows opening of a regular file. Same codes like in the LoadValue() function are used.

Debugging the code
Use the Trace command mentioned above.

Inputs

 HLD Hold – the block code is not executed if the input is set to on Bool RESET Rising edge resets the block. The block gets initialized again (all global variables are cleared and the Init() function is called). Bool u0..u15 Input signals which are accessible from the script Unknown

Outputs

 iE Runtime error code. For error codes $\mathtt{\text{iE}}<-99$ the algorithm is stopped until it is reinitialized by the RESET input or by restarting the executive) Error 0 .... No error occurred, the whole main() function was executed (also the init() function). -1 ... The execution was suspended using the Suspend() command, i.e. the execution will resume as soon as the REXLANG block is executed again < -1 . Error code of the REXYGEN system, see Appendix C > 0 .. User-defined return values, algorithm execution without any change y0..y15 Output signals which can be set from within the script Unknown

Parameters

 srcname Source file name  $\odot$srcfile.c String srctype Coding of source file  $\odot$1 Long (I32) 1: C-like  Text file respecting the C-like syntax described above 2: STL  Text file respecting the IEC61131-3 standard. The standard is implemented with the same limitations as the C-like script (i.e. no structures, only INT, REAL and STRING data types, function blocks are global variables VAR_INPUT, outputs are global variables VAR_OUTPUT, parameters are global variables VAR_PARAMETER, standard functions according to specification, system and communication functions are the same as in C-like). 3: RLB  REXLANG binary file which results from compilation of C-like or STL scripts. Use this option if you do not wish to share the source code of your block. 4: ILL  Text file with mnemocodes, which can be compared to assembler. This choice is currently not supported. stack Stack size defined as number of variables. Default and recommended value is 0, which enables automatic estimation of the necessary stack size. Long (I32) debug Debug level – checking is safer but slows down the execution of the algorithm. Option No check can crash REXYGENapplication on target platform if code is incorect.  $\odot$3 Long (I32) 1 .... No check 2 .... Basic check 3 .... Full check strs Total size of buffer for strings. Enter the maximum number of characters to allocate memory for. The default value 0 means that the buffer size is determined automatically. Long (I32) p0..p15 Parameters which are accessible from the script Unknown

Example C-like
The following example shows a simple code to sum two input signals and also sum two user-defined parameters.

double input(0) input_u0;
double input(2) input_u2;

double parameter(0) param_p0;
double parameter(1) param_p1;

double output(0) output_y0;
double output(1) output_y1;

double my_value;

long init(void)
{
my_value = 3.14;
return 0;
}

long main(void)
{
output_y0 = input_u0 + input_u2;
output_y1 = param_p0 + param_p1 + my_value;
return 0;
}

long exit(void)
{
return 0;
}

Example STL
And here is the same example in Structured Text.

VAR_INPUT
input_u0:REAL;
input_u1:REAL;
input_u2:REAL;
END_VAR

VAR_OUTPUT
output_y0:REAL;
output_y1:REAL;
END_VAR

VAR_PARAMETER
param_p0:REAL;
param_p1:REAL;
END_VAR

VAR
my_value: REAL;
END_VAR

FUNCTION init : INT;
my_value := 3.14;
init := 0;
END_FUNCTION

FUNCTION main : INT;
output_y0 := input_u0 + input_u2;
output_y1 := param_p0 + param_p1 + my_value;
main := 0;
END_FUNCTION

FUNCTION exit : INT;
exit := 0;
END_FUNCTION

2022 © REX Controls s.r.o., www.rexygen.com