POU Declarations¶
This public entry covers FUNCTION, FUNCTION_BLOCK, PROGRAM, class,
interface, method, property, and action declarations.
Use the full spec below when you need exact declaration syntax, inheritance rules, or execution-control parameter details.
Related: Variables, Statements
Program Organization Unit Declarations¶
IEC 61131-3 Edition 3.0 (2013) - Section 6.6
This specification defines POU declarations for trust-hir.
1. Overview¶
Program Organization Units (POUs) are the building blocks of IEC 61131-3 programs:
| POU Type | Keyword | Instances | State | Return Value |
|---|---|---|---|---|
| Function | FUNCTION |
N/A (call) | No | Optional |
| Function Block | FUNCTION_BLOCK |
Yes | Yes | Via outputs |
| Program | PROGRAM |
Yes | Yes | Via outputs |
| Class | CLASS |
Yes | Yes | N/A |
| Interface | INTERFACE |
N/A | N/A | N/A |
| Method | METHOD |
N/A | No | Optional |
Implementation Extension: Test POUs (DEV-033)¶
truST accepts TEST_PROGRAM and TEST_FUNCTION_BLOCK as test-oriented,
non-IEC declaration forms; see docs/IEC_DEVIATIONS.md (DEV-033).
TEST_PROGRAM name
...
END_TEST_PROGRAM
TEST_FUNCTION_BLOCK name
...
END_TEST_FUNCTION_BLOCK
Current parser/HIR behavior:
- TEST_PROGRAM is parsed with PROGRAM structure and collected as SymbolKind::Program.
- TEST_FUNCTION_BLOCK is parsed with FUNCTION_BLOCK structure and collected as SymbolKind::FunctionBlock.
- Mismatched end markers produce actionable diagnostics (expected END_TEST_PROGRAM / expected END_TEST_FUNCTION_BLOCK).
2. FUNCTION Declaration (Table 19, Section 6.6.2)¶
Syntax¶
FUNCTION function_name : return_type
// Variable declarations
VAR_INPUT ... END_VAR
VAR_OUTPUT ... END_VAR
VAR_IN_OUT ... END_VAR
VAR_EXTERNAL ... END_VAR
VAR_EXTERNAL CONSTANT ... END_VAR
VAR ... END_VAR
VAR_TEMP ... END_VAR
// Statements
END_FUNCTION
Examples¶
// Function with return value
FUNCTION Square : INT
VAR_INPUT
X: INT;
END_VAR
Square := X * X;
END_FUNCTION
// Function without return value (procedure-like)
FUNCTION LogMessage
VAR_INPUT
Message: STRING;
END_VAR
// Implementation
END_FUNCTION
Rules (Section 6.6.1.2)¶
- No state retention: Variables in VAR/VAR_TEMP are re-initialized each call (VAR and VAR_TEMP are equivalent in functions/methods)
- Return value: Assigned via function name or RETURN statement
- VAR_IN_OUT and VAR_EXTERNAL: May be modified inside the function; VAR_EXTERNAL CONSTANT shall not be modified
- CONSTANT restriction: Function block instances shall not be declared in variable sections with CONSTANT qualifier
Function Call (Section 6.6.1.7)¶
| No. | Call Type | Example |
|---|---|---|
| 1 | Formal call | Y := Square(X := 5); |
| 2 | Non-formal call | Y := Square(5); |
| 3 | Procedure call | LogMessage('Hello'); |
Mixed calls are allowed when positional arguments precede formal arguments. (IEC 61131-3 Ed.3 §6.6.1.4.2; Table 50)
EN/ENO Mechanism (Section 6.6.1.6)¶
EN and ENO are optional parameters on FUNCTION/FUNCTION_BLOCK declarations and calls:
EN: BOOL input, defaultTRUEwhen declaredENO: BOOL output
| EN | Execution | ENO |
|---|---|---|
| FALSE | POU body is not executed | FALSE |
| TRUE | POU body executes normally | TRUE unless the POU sets it FALSE |
| TRUE | POU body encounters an execution error | FALSE |
FUNCTION SafeDiv : REAL
VAR_INPUT
EN: BOOL := TRUE;
Num, Den: REAL;
END_VAR
VAR_OUTPUT
ENO: BOOL;
END_VAR
IF Den = 0.0 THEN
ENO := FALSE;
SafeDiv := 0.0;
ELSE
SafeDiv := Num / Den;
END_IF;
END_FUNCTION
Result := SafeDiv(EN := Cond, Num := A, Den := B, ENO => Valid);
Return Value (Table 20)¶
FUNCTION Max : INT
VAR_INPUT
A, B: INT;
END_VAR
IF A > B THEN
Max := A; // Assign to function name
ELSE
Max := B;
END_IF;
END_FUNCTION
Or using RETURN:
FUNCTION Max : INT
VAR_INPUT
A, B: INT;
END_VAR
IF A > B THEN
RETURN A;
ELSE
RETURN B;
END_IF;
END_FUNCTION
3. FUNCTION_BLOCK Declaration (Table 40, Section 6.6.3)¶
Syntax¶
FUNCTION_BLOCK fb_name
// Variable declarations
VAR_INPUT ... END_VAR
VAR_OUTPUT ... END_VAR
VAR_IN_OUT ... END_VAR
VAR ... END_VAR
VAR_TEMP ... END_VAR
VAR_EXTERNAL ... END_VAR
// Methods (optional)
METHOD ... END_METHOD
// Statements
END_FUNCTION_BLOCK
Example¶
FUNCTION_BLOCK Counter
VAR_INPUT
Reset: BOOL;
CountUp: BOOL R_EDGE;
END_VAR
VAR_OUTPUT
Count: INT;
Overflow: BOOL;
END_VAR
VAR
InternalCount: INT := 0;
END_VAR
IF Reset THEN
InternalCount := 0;
ELSIF CountUp THEN
IF InternalCount < 32767 THEN
InternalCount := InternalCount + 1;
ELSE
Overflow := TRUE;
END_IF;
END_IF;
Count := InternalCount;
END_FUNCTION_BLOCK
Rules¶
- State retention: Internal variables persist across calls
- Instantiation required: Must be declared as instance to use
- Instance isolation: Each instance has independent state
- Can contain methods: OOP-style methods allowed
- Can inherit: Using EXTENDS (if supported)
- EXTENDS targets: Function blocks may EXTENDS a FUNCTION_BLOCK or CLASS; extending an INTERFACE is invalid (Table 40, IEC 61131-3 Ed.3 §6.6.3.4)
Function Block Instance Declaration (Table 41)¶
VAR
MyCounter: Counter; // Simple instance
Timers: ARRAY[1..10] OF TON; // Array of instances
HeaterPID: PID := (Kp := 2.5, Ti := T#10s); // With initialization
END_VAR
Function Block Call (Table 42)¶
| No. | Call Type | Example |
|---|---|---|
| 1 | Complete formal | MyCounter(Reset := FALSE, CountUp := TRUE); |
| 2 | Incomplete formal | MyCounter(CountUp := Trigger); |
| 3 | Output access | Value := MyCounter.Count; |
| 4 | With EN/ENO | MyFB(EN := Cond, ENO => Success); |
4. PROGRAM Declaration (Table 47, Section 6.6.4)¶
Syntax¶
PROGRAM program_name
// Variable declarations
VAR_INPUT ... END_VAR
VAR_OUTPUT ... END_VAR
VAR ... END_VAR
VAR_EXTERNAL ... END_VAR
VAR_TEMP ... END_VAR
VAR_ACCESS ... END_VAR
// Statements
END_PROGRAM
Example¶
PROGRAM MainControl
VAR_INPUT
EmergencyStop: BOOL;
END_VAR
VAR_OUTPUT
SystemRunning: BOOL;
END_VAR
VAR
StartupSequence: INT := 0;
ProcessTimer: TON;
END_VAR
VAR_EXTERNAL
GlobalConfig: Configuration;
END_VAR
IF EmergencyStop THEN
SystemRunning := FALSE;
StartupSequence := 0;
ELSE
// Main control logic
END_IF;
END_PROGRAM
Rules¶
- Similar to FUNCTION_BLOCK but with additional capabilities
- Can be associated with TASKs
- Can have VAR_ACCESS declarations
- Typically represents a complete control application
- Instantiated in CONFIGURATION/RESOURCE
5. CLASS Declaration (Table 48, Section 6.6.5)¶
Syntax¶
CLASS class_name
// Variable declarations
VAR ... END_VAR
// Methods
METHOD ... END_METHOD
END_CLASS
With Inheritance and Interface¶
CLASS class_name EXTENDS base_class IMPLEMENTS interface1, interface2
// ...
END_CLASS
Example¶
CLASS Motor
VAR PUBLIC
Speed: INT;
Running: BOOL;
END_VAR
VAR PRIVATE
InternalState: INT;
END_VAR
METHOD PUBLIC Start
Running := TRUE;
InternalState := 1;
END_METHOD
METHOD PUBLIC Stop
Running := FALSE;
Speed := 0;
InternalState := 0;
END_METHOD
METHOD PUBLIC SetSpeed
VAR_INPUT
NewSpeed: INT;
END_VAR
IF Running THEN
Speed := NewSpeed;
END_IF;
END_METHOD
END_CLASS
Class Modifiers¶
| Modifier | Description |
|---|---|
FINAL |
Cannot be extended |
ABSTRACT |
Cannot be instantiated, must be extended |
CLASS ABSTRACT BaseController
METHOD PUBLIC ABSTRACT Execute;
END_CLASS
CLASS FINAL SpecificController EXTENDS BaseController
METHOD PUBLIC OVERRIDE Execute
// Implementation
END_METHOD
END_CLASS
Rules¶
- Classes cannot have VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT
- All member access is through methods or PUBLIC variables
- Instantiation:
VAR MyMotor: Motor; END_VAR - Cannot be associated with TASKs directly
- EXTENDS must reference a CLASS type; FINAL classes cannot be extended (Table 48, IEC 61131-3 Ed.3 §6.6.5.5.4)
6. INTERFACE Declaration (Table 51, Section 6.6.6)¶
Syntax¶
INTERFACE interface_name
METHOD method_name
// Parameter declarations only, no body
END_METHOD
END_INTERFACE
Example¶
INTERFACE IControllable
METHOD Start
END_METHOD
METHOD Stop
END_METHOD
METHOD GetStatus : INT
END_METHOD
END_INTERFACE
CLASS Pump IMPLEMENTS IControllable
VAR PRIVATE
IsRunning: BOOL;
END_VAR
METHOD PUBLIC Start
IsRunning := TRUE;
END_METHOD
METHOD PUBLIC Stop
IsRunning := FALSE;
END_METHOD
METHOD PUBLIC GetStatus : INT
IF IsRunning THEN
GetStatus := 1;
ELSE
GetStatus := 0;
END_IF;
END_METHOD
END_CLASS
Interface Inheritance¶
INTERFACE IAdvancedControl EXTENDS IControllable
METHOD Pause
END_METHOD
METHOD Resume
END_METHOD
END_INTERFACE
Interface as Variable Type¶
VAR
MyPump: Pump;
Controller: IControllable; // Reference to any implementing class
END_VAR
Controller := MyPump; // Assign implementing instance
Controller.Start(); // Call through interface
Rules¶
- Interfaces contain only method prototypes (no implementation) per IEC 61131-3 Ed.3 §6.6.6.1. Property signatures are accepted as an extension (see
docs/IEC_DEVIATIONS.md). - All methods are implicitly PUBLIC
- Classes implementing interface MUST implement all methods
- Interfaces can extend other interfaces
- A class can implement multiple interfaces
- Interface variables are references and shall be assigned before use; they shall not be VAR_IN_OUT
- Interface variables can be assigned NULL (default) and compared for equality
- EXTENDS must reference INTERFACE types; cyclic interface inheritance is invalid (Table 51, IEC 61131-3 Ed.3 §6.6.6.3)
7. METHOD Declaration (Section 6.6.1.5)¶
Syntax¶
METHOD access_specifier method_name : return_type
VAR_INPUT ... END_VAR
VAR_OUTPUT ... END_VAR
VAR_IN_OUT ... END_VAR
VAR ... END_VAR
VAR_TEMP ... END_VAR
// Statements
END_METHOD
Example¶
METHOD PUBLIC Calculate : REAL
VAR_INPUT
A, B: REAL;
END_VAR
VAR_TEMP
Temp: REAL;
END_VAR
Temp := A * A + B * B;
Calculate := SQRT(Temp);
END_METHOD
Method Modifiers¶
| Modifier | Description |
|---|---|
OVERRIDE |
Overrides base class method |
FINAL |
Cannot be overridden in derived classes |
ABSTRACT |
No implementation, must be overridden |
CLASS Base
METHOD PUBLIC Process
// Default implementation
END_METHOD
END_CLASS
CLASS Derived EXTENDS Base
METHOD PUBLIC OVERRIDE Process
SUPER.Process(); // Call base implementation
// Additional processing
END_METHOD
END_CLASS
Access Specifiers for Methods¶
| Specifier | Description |
|---|---|
PUBLIC |
Accessible from anywhere |
PROTECTED |
Accessible from class and derived classes (default) |
PRIVATE |
Accessible only within declaring class |
INTERNAL |
Accessible within same NAMESPACE |
THIS and SUPER Keywords¶
METHOD PUBLIC Example
THIS.Speed := 100; // Access own member
SUPER.Initialize(); // Call base class method
END_METHOD
8. ACTION Declaration (Table 56, Table 72; Section 6.7.4)¶
Syntax¶
ACTION action_name
// Statements
END_ACTION
Rules¶
- Actions may be declared inside PROGRAM or FUNCTION_BLOCK bodies; they share the enclosing POU scope (IEC 61131-3 Ed.3 §6.7.4, Table 56).
- Action declarations are local to the enclosing POU.
- Action bodies are type-checked like statement lists in the enclosing POU, including access to THIS/SUPER in function blocks.
9. NAMESPACE Declaration (Tables 64-66, Section 6.9)¶
Syntax¶
NAMESPACE namespace_name
// Type declarations
// POU declarations
END_NAMESPACE
Nested Namespaces¶
NAMESPACE Company
NAMESPACE Project
NAMESPACE Module
FUNCTION_BLOCK MyFB
// ...
END_FUNCTION_BLOCK
END_NAMESPACE
END_NAMESPACE
END_NAMESPACE
USING Directive¶
USING Company.Project.Module;
USING Standard.Timers, Standard.Counters;
VAR
FB1: MyFB; // Can use without full qualification
END_VAR
Qualified Access¶
VAR
FB1: Company.Project.Module.MyFB; // Full qualification
END_VAR
Rules¶
- Namespaces can be nested
- USING may appear in the global namespace, inside a namespace, or immediately after a POU header (IEC 61131-3 Ed.3, Section 6.9.4, Table 66)
- USING brings names from the referenced namespace into scope (direct members only)
- Qualified names can always be used
- Name conflicts resolved by qualification
- INTERNAL access specifier limits scope to namespace
Implementation Notes for trust-hir¶
- USING directives are parsed and resolved for global, namespace, and POU scopes; only direct members of the imported namespace are made available. (IEC 61131-3 Ed.3, Section 6.9.4, Table 66)
- INTERNAL access specifier is enforced at namespace boundaries. (IEC 61131-3 Ed.3, Tables 64-66)
Implementation Notes for trust-hir¶
POU Symbol Requirements¶
- Name: Unique identifier
- Kind: Function, FB, Program, Class, Interface, Method
- Parameters: Input, output, in-out lists
- Return type: For functions and methods
- Body: Statement list
- Scope: Containing namespace/POU
- Modifiers: FINAL, ABSTRACT, access specifiers
Semantic Checks¶
- Duplicate definition: Same POU name in scope
- Missing implementation: ABSTRACT method not overridden
- Interface compliance: All methods implemented
- Override without base: OVERRIDE on non-virtual method
- FINAL violation: Extending FINAL class/overriding FINAL method
- Access violation: Calling PRIVATE/PROTECTED inappropriately
- Return value: Function/method must assign return value
- Parameter matching: Call arguments match declaration
Error Conditions¶
- Undefined POU reference
- Missing return value assignment
- Type mismatch in call
- Invalid inheritance (circular, FINAL violation)
- Interface method not implemented
- Abstract class instantiation
- Invalid use of THIS/SUPER
- OVERRIDE without matching base method