• No results found

DataTypes

In document OpenSCADA Documentation (Page 18-23)

3.5 Instruction List Programming

3.5.1 DataTypes

}

Arguments to each invocation of the POU can be passed through initialization_maps (a subfield of the ProgramSpeci-fication message). Initialization maps can be used to initialize the POUs input/inout variables as well as specify where output variables could be stored after the invocation. In this example, the program “PID_CONTROL“‘s input variable

“dummy_in” at the start of every invocation is assigned the value of the global variable “start_int” (which was specified in the System specification i.e, in the previous section). At the end of the invocation, the value of the output variable of the PROGRAM called “dummy_out” is copied to “global_int_var” (which was created in the previous section as a PLC level global variable). It must be noted that the mapped_variable_field_name for an VAR_INPUT variable could also be an immediate value. For instance in the above example, if “dummy_in” needs to be initialized with 10 for every invocation, the initialization map could be modified to:

initialization_maps {

pou_variable_field_name: "dummy_in"

mapped_variable_field_name: "10"

}

3.5 Instruction List Programming

This section of the guide describes how Instruction List (IL) programs can be written in OpenSCADA. It assumes that the reader has some familiarity with IL programs and is not designed to be a tutorial for IL programming. It must be noted that the IL backend in OpenSCADA is designed to be simple and it does not exhaustively include all features specified in IEC-61131-3. A Few of them have been omitted in the implementation for convenience and they are documented here.

We first describe the fundamental building blocks of IL programs in OpenSCADA: DataTypes, Program Organization Units (POUs) and Tasks. Then, the capabilities of the current implementation are described including the set of supported IL instructions, System Functions and System Function Blocks. Finally, some of the missing IL specific features are documented for future work.

3.5.1 DataTypes

DataTypes are a fundamental part of any IL program. Each datatype in OpenSCADA is associated with a datatype category, datatype name and optional dimension attributes. If a dimension attribute is specified with the datatype definition, then it is interpreted as an array.

DataTypes are primarily two categories: Elementary and Non-Elementary. Each category has many subcategories.

Elementary data types have been implicitly defined and they do not need to be declared during system specification.

The table given below lists all the elementary data type names, their categories and size in bits. It also includes an example string representation of a value of the data type. (Note that strings in OpenSCADA are character arrays with fixed length of 1000)

OpenSCADA Documentation, Release 1.0

DataType Name Category Size in Bits Example

BOOL BOOL 1 “TRUE”

BYTE BYTE 8 “16#A1”

WORD WORD 16 “16#A102”

DWORD DWORD 32 “16#A1010101”

LWORD LWORD 64 “16#B101010101010101”

CHAR CHAR 8 ‘a’

USINT USINT 8 “123”

SINT SINT 8 “-123”

UINT UINT 16 “123”

INT INT 16 “123”

UDINT UDINT 32 “123”

DINT DINT 32 “123”

ULINT ULINT 64 “123”

LINT LINT 64 “123”

REAL REAL 32 “0.2”

LREAL LREAL 64 “0.234”

TIME TIME 64 “t#1.2s”

DATE DATE 96 “d#02-01-2010”

TOD TIME_OF_DAY 96 “tod#23:59:59”

DT DATE_AND_TIME 192 “dt#02-01-2010 23:59:59”

STRING CHAR 8000 “Hello how are you!”

Declaring a data type: Custom data types can be declared in the system specification protoxt file using a datatype_declaration field of type DataType message defined inconfiguration.proto. Its fields are explained below:

• name: Name of the datatype

• datatype_category: Category of the datatype. If a custom datatype is to be defined, the category needs to be specified as DERIVED. A DERIVED datatype cannot have datatype field of POU category. By default, it is set to POU.

• pou_type: If the datatype_category is POU, this field denotes the type of POU: i.e Function (FN), Function Block (FB) or Program (PROGRAM)

• datatype_field: Must be specified only if datatype_category is POU or DERIVED. This describes an individual field of the complex datatype.

– field_name: Name of the field

– field_datatype_name: Name of the datatype of the field. It cannot be a POU category datatype if the parent datatype_category is not POU

– initial_value: (string) May only be specified if the category of this field’s datatype belongs to one of the categories in the table listed above

– dimension_1: must only be specified if this field is supposed to be an array – dimension_2: must only be specified if this field is supposed to be a 2d-array

– intf_type: Refers to interface type of the field. It may only be specified if the parent datatype_category is POU. The interface type of a field changes the way it is interpreted upon POU’s invocation. Since POUs contain the execution logic and need to be invoked, its fields are treated as arguments and return values. Field interface types decide which fields are input arguments, return values, both or neither. There are several supported field interface types which are described here:

* VAR_INPUT: The field is treated as an input variable. Its value can only be read within the called POU and can only be set from the calling POU

* VAR_OUTPUT: The field is treated as an output variable. Its value can only be set within the called POU and it can only be read from the calling POU

3.5. Instruction List Programming 15

* VAR_IN_OUT: The field is treated as both input/output variable. During the time of POU invocation, another variable from calling POU’s scope is assigned to this field. It could be modified within the called POU and these modifications reflect changes in the calling POU as well.

* VAR: The field is internal to the POU and equivalent to a local variable. But unlike local variable in the traditional sense, its value is retained across invocations if the PoUType is a PROGRAM or FB. It cannot be used in a FN.

* VAR_TEMP: The field is internal to the POU and equivalent to a local variable.

* VAR_EXTERNAL: The field is equivalent to an extern variable. It cannot be accessed/assigned during POU invocation. It points to global variables declared at the resource/PLC level. The field name and field datatype names must match these previously declared global variables.

The field can be accessed for read/write operations within the called POU.

* VAR_EXPLICIT_STORAGE: The field is backed by an address in memory (RAM or IO). It is equivalent to a directly represented variable in IL terminology. These variables cannot be accessed/assigned during POU invocation but any changes to the associated memory location is reflected in the affected logic.

* VAR_ACCESS: Discussed in Advanced Topics

– field_storage_spec: If the intf_type is VAR_EXPLICIT_STORAGE, then details on the backing mem-ory address is specified here. It includes memmem-ory type, byte offset and bit offset. The bit offset is ignored unless the field’s datatype category is BOOL. The field_storage_spec may also be specified as a string in short form: e.g “%M4.1” to denote byte 4, bit 1 in RAM or “%I2.0” to denote byte 2, bit 0 in Input memory or “%Q3.0” to denote byte 3, bit 0 in Output memory.

– field_qualifier: Field qualifiers are additional optional attributes which could assigned to (1) VAR_INPUT or VAR_EXPLICIT_STORAGE boolean fields (2) VAR_ACCESS fields. For VAR_INPUT/VAR_EXPLICIT_STORAGE boolean fields, two qualifiers are allowed R_EDGE and F_EDGE which denote rising edge and falling edge respectively. When a boolean field with a R_EDGE qualifier is read inside the called POU, the read operation returns TRUE iff the field ex-perienced a rising edge transition. Similarly, when a boolean field with a F_EDGE qualifier is read inside the called POU, the read operation returns TRUE iff the field experienced a falling edge transi-tion. Field qualifiers for VAR_ACCESS fields are discussed later in Advanced Topics.

• datatype_spec: A datatype declaration may also optionally have a datatype_spec field. datatype_spec may only be specified for DataTypes where datatype_category is not in {POU, DERIVED}. It could be used to assign initial_values and convert this datatype into an array:

– initial_value: Specified as a string only if the datatype_category is present in the table listed above – dimension_1: Must only be specified if this datatype is supposed to be a typedef of an ARRAY of

[datatype_category] i.e if datatype_category is INT and if datatype_spec with dimension_1 = 10 is specified, then this datatype is a typedef of an integer array of size 10 (ARRAY[10] of INT)

– dimension_2: Must only be specified if this datatype is typedeffing a 2d-array

• code_body: It contains the set of instructions to execute upon a POU’s invocation. Thus it may only be specified if the dataype_category is POU

3.5.1.1 Illustrations

Declaring a new datatype called “TIME_TYPE_DEF” which is a typedef of the elementary TIME datatype. The initial value of any field of this datatype would be “t#1s”:

OpenSCADA Documentation, Release 1.0

Declaring a new datatype called “INT_1DARR” which is a 1-D INT array of size 10 with initial values: {-1,0,1,2,3,4,5,6,7,8}:

Declaring a new datatype called “INT_2DARR” which is a 2-D INT array of size 2 x 2 with initial values:

{{0,1},{2,3}}:

Declaring a structure called “COMPLEX_STRUCT_1” with multiple fields:

datatype_declaration { name: "COMPLEX_STRUCT_1"

datatype_category: DERIVED datatype_field {

# This field is a character array of length 1000 field_name: "string_field"

field_datatype_name: "STRING"

}

datatype_field {

# This field is an integer field_name: "int_field"

field_datatype_name: "INT"

}

datatype_field {

# This field is a REAL number and its initial value is 0.1 field_name: "real_field"

field_datatype_name: "REAL"

initial_value: "0.1"

}

datatype_field {

# This field is a 1D integer array of size 10 with initial values {-1,0,1,2,3,

˓→4,5,6,7,8}

(continues on next page)

3.5. Instruction List Programming 17

(continued from previous page) field_name: "oned_arr_field"

field_datatype_name: "INT_1DARR"

}

datatype_field {

# This field is a 2D integer array of size 2 x 2 with initial values {{0,1},

˓→{2,3}}

field_name: "twod_arr_field"

field_datatype_name: "INT_2DARR"

} }

Declaring a nested structure with mixed type of fields i.e both elementary and non-elementary:

datatype_declaration { name: "COMPLEX_STRUCT_2"

datatype_category: DERIVED datatype_field {

# Note: this is a field of the previously declared COMPLEX_STRUCT_1 datatype field_name: "complex_field"

Declaring a nested structure with fields which are arrays of derived datatypes:

datatype_declaration { name: "COMPLEX_STRUCT_3"

datatype_category: DERIVED datatype_field {

# Note that this field is a 1-D ARRAY of [COMPLEX_STRUCT_2] with two elements field_name: "complex_vector"

field_datatype_name: "COMPLEX_STRUCT_2"

(continues on next page)

OpenSCADA Documentation, Release 1.0

(continued from previous page) dimension_1: 2

} }

In document OpenSCADA Documentation (Page 18-23)

Related documents