[MAT logo][Prev][Up][Next]

IEC ST/IL compiler


One of the tools provided with the MatPLC is a compiler for the IEC 61131-3 IL and ST textual languages. Basically, this tool transforms a program written in ST and/or IL into C++ code that, when further compiled and linked to the MatPLC libraries, becomes a MatPLC module.

To write an ST or IL program, use a text editor and save the file with whatever name you wish. We sugest you use <prog_name>.st or <prog_name>.il as this is the convention that has been followed in the MatPLC demo directories. The IEC 61131-3 standard simply uses files names <prog_name>.txt in their examples, so you may want to use that instead.

Turning the ST/IL file into a module

The compiler accepts as its only parameter the name of the file to be compiled, using stdin if no filename is given. The resulting C++ code is sent to stdout.
$iec2cc oven.st > oven.cc
$cat oven.st | iec2cc > oven.cc

The resulting C++ code will need to be further compiled by a C++ compiler. Note that it needs to include the standard $MATPLC/lib/plc.h header file, as well as $MATPLC/logic/iec/stage4/generate_cc/plciec.h

Once compiled, the resulting object code will have to be linked with the standard matplc library $MATPLC/lib/matplc.[so|a]. We sugest that you use the working demo programs and makefiles in the $MATPLC/demo/basic_iec directory as a starting point.

The resulting executable code may be run as any other MatPLC module, including all the standard --PLC<plc_option> command line switches.

The ST and IL languages

Currently this manual does not include any description of the ST and IL languages. Users not familiar with the IL and ST programming languages are invited to read a book on these languages.

A useful on-line reference is IEC 61131-3: Programming Industrial Automation Systems.

Note, however, that most books currently available on programming with the IL and ST languages refer to the first version of these languages, whereas the iec2cc compiler was built based on the 2nd verion of the standard. More precisely, the publicly available draft version of the standard, dated 10th december 2001, was used.

Current State of the IEC Compiler

The iec2cc compiler as it stands is still very incomplete. It currently parses the complete syntax of the IL and ST languages, so any syntax errors in the program being compiled are caught early on. Nevertheless, error messages have not yet been written, so if the iec2cc compiler stops or simply runs into an infinite loop, this is because you have a syntax error somewhere in your IL/ST code.

Note however that not all syntax is yet suported when generating the equivalent C++ code. Aditionally, semantic checking is not yet performed, so most semantic errors (e.g. storing a TRUE value in a variable of type INT) in your programs will not be caught by the iec2cc compiler. Many semantic errors will nevertheless result in semantic errors in the resulting C++ code, so they will probably be caught later on by gcc, but this is not guaranteed.

Writing an IL/ST Program

Writing a MatPLC module in IL and/or ST for the iec2cc compiler is a question of merely writing all the program organization units (i.e functions, function blocks, programs and configurations) you require.

However, only the first configuration will be used by the iec2cc compiler. Remaining configurations will simply be ignored. Currently, this configuration may only contain a single program attributed to a single task.

For e.g.

varint : INT := 99;
varreal : REAL := 99.9;

TASK t1(INTERVAL := t#20ms, PRIORITY := 2);
PROGRAM foo WITH t1: PROG1(param1 := varint, param2 := varreal);

This implies that at the moment you will be writing a single program type, since a single instance of a single program type is currently supported.

The remaining functions and function blocks may be written in either ST or IL, as long as each function or function block uses a single language. The iec2cc compiler automatically distinguishes which language is being used.

Before calling a function, and before a function block or program instance is defined, the referenced function/function block/program must be defined. This means that when you can call a function, or create a function block instance, that function or function block instance must appear earlier in the file being compiled.

Note that your program may be divided into several files. A file may include another anywhere in the code using the syntax: (*#include "<filename>"*)

Note the lack of spaces between '(*' and '#include', as well as between the last '"' and '*)'. This syntax will be interpreted as a comment by other IL/ST compilers, but will probably nevertheless be changed to conform to the 'pragma' directive as defined in the IEC 61131-3 standard.

Accessing MatPLC Points

Accessing the MatPLC points from within IEC IL and ST programs is achieved using located variables. However, unlike the IEC standard that restricts the location of variables to names such as '%I.0.2', '%Q.9.34', etc., we allow the location to be any identifier that may also be used as a IL/ST variable name. For example,

leds AT %Lights : INT := 1;
left_bt AT %left_bt : BOOL;
right_bt AT %right_bt : BOOL;

From this declaration onwards, accessing the 'leds' variable from within the IL/ST program will directly access the 'lights' MatPLC point.

If the MatPLC point is wider (has more bits) than the data type of the corresponding ST/IL variable, writing to this variable will set the unused bits to zero, while reading the variable will ignore the extra bits.

Likewise, if the MatPLC point has less bits than the data type of the corresponding ST/IL variable, then writing to the variable will essentially discard the higher valued bits, while reading from the variable will set the higher valued bits to zero.

Note however that MatPLC points may have names such as 'temp__alarm', that are not valid ST/IL identifiers. In this case it is not yet possible to map them to ST/IL variables (this issue will be resolved at a later date), so we sugest that an alternative name is given to these MatPLC points, or an alias be established (see the 'alias' table in the [PLC] section of the matplc.conf file).

Limitations and extensions

The IEC standard allows compilers to accept extensions as long as they are within pragmas, which for the IEC 61131-3 is any text delimited by '{' and '}'. We have therefore extended the accepted syntax to allow inclusion of files from within other files, by using the following syntax:
{#include "<filename>"}
where <filename> should be replaced by the name of the file to be included. File inclusion is only allowed outside the definition of IEC 61131-3 Program Organization Units (i.e. outside Funtions, Funtion Blocks, Programs, Configurations).

Our compiler also allows that C or C++ code be inserted inlined with ST or IL code. This is done by simply inserting any C or C++ code, within the two '{' and '}' delimiters, in ST or IL code. Note that this support is prelimenary and its syntax may change without notice (as everything else in this project, really...;-] )

As stated previously, the IEC compiler is still at an embrionic stage, and does not yet support the full syntax and semantics of the IEC IL/ST languages.

Namely, the following elementary data types are not yet supported: TIME, DATE, TIME_OF_DAY, DATE_AND_TIME, STRING, WSTRING

In addition, the following derived data types are also not yet supported: SUBRANGE. ENUMERATION and ARRAY. Note that STRUCTREs are supported.

Standard functions and function blocks have not yet been written, except for tentative test functions/function blocks such as: BCD_TO_INT, INT_TO_BDC, SR, RS, CU, CD, CUD, R_TRIG, F_TRIG.

Due to the way located variables are implemented, we do not yet support the passing of EXTERNAL variables, declared in programs or functions blocks, as OUT or IN_OUT parameters to functions.

Another restriction is in the calling of function blocks using the formal syntax from within IL code. In this case, a parameter may not be given the value obtained from an embedded list of IL instructions. For example, consider the following function block call:

CAL fb_instance (
param1 = var1,
param2 = 45,
param3 = (
LD var2
ADD var3
param4 = var4
In the above code sample, the embeded IL for 'param3' is not yet supported.


$Date: 2005/12/08 09:13:44 $