← Files RungstoneARCHIVED FILE
skills/rungstone-plc/references/iec61499.md
5.59 KB · Nov 3, 2026 · 06:12 UTC
# IEC 61499 / Eclipse 4diac (target `iec61499`)
Read when translating to IEC 61499 or reading 4diac `.fbt` files. Formats and grammar rules here
were checked against the 4diac IDE 3.x sources (its type library and ST grammar, October 2026); the
checker passes every type in 4diac's own 3.x library. The generated types have not been opened in
the 4diac IDE or run on FORTE here: say so.
## Contents
1. The model, and the translation pattern
2. What gets generated
3. Writing the scan body (timers, edges, counters)
4. ST rules in 4diac
5. Events and sampling (With)
6. I/O, HMI and retentive data
7. Deliverables and checks
---
## 1. The model, and the translation pattern
IEC 61131-3 runs everything every scan. IEC 61499 runs a function block only when an event
arrives; data travels with events. A faithful first translation keeps the scan: the whole program
becomes one **Basic FB** whose REQ event runs the old scan as one ST algorithm, and an `E_CYCLE`
(4diac standard library, `iec61499::events::E_CYCLE`) fires REQ every cycle. Behaviour stays the
same, so it can be verified against the source.
Tell the engineer this is a starting point: splitting it into event-driven FBs (one per machine
function, triggered by real events) is the IEC 61499 way and comes after the behaviour is proven.
## 2. What gets generated
`st_to_61499.py <file>.st -o out/` writes two 4diac 3.x types:
| File | What it is |
|---|---|
| `<Name>.fbt` | Basic FB. INIT (EInit) runs `initialize` (outputs to their start values) and answers INITO; REQ runs the scan body and answers CNF. Every data input travels with INIT and REQ, every output with INITO and CNF. Input `CYCLE : TIME` carries the scan period. |
| `<Name>_App.fbt` | Composite FB: `Logic` (the Basic FB) plus `Cycle` (E_CYCLE). INIT initializes the logic, INITO starts the cycle, Cycle.EO drives REQ, STOP stops it; CYCLE feeds both E_CYCLE.DT and the logic. |
Variables: VAR_INPUT and `AT %I..` become data inputs, VAR_OUTPUT and `AT %Q..` data outputs,
everything else internal variables. The engineer adds both files to a 4diac project's type
library, places `<Name>_App` in the application, connects INIT to an `E_RESTART` (COLD/WARM), and
wires the data inputs and outputs to the device's I/O FBs.
## 3. Writing the scan body
Write the translation as one PROGRAM or FUNCTION_BLOCK in plain ST that **calls no FB instances**
(a Basic FB algorithm here doesn't call timers, edges or counters). Use these patterns; they match
TON / R_TRIG / CTU scan for scan in the simulator (fixture `fixtures/plc/iec61499_fill`):
```
(* TON T: IN = cond, PT = T#3s ; internal T_ET : TIME, T_Run : BOOL, T_Q : BOOL *)
IF cond THEN
IF T_Run THEN
T_ET := T_ET + CYCLE;
IF T_ET > T#3s THEN T_ET := T#3s; END_IF;
END_IF;
T_Run := TRUE;
ELSE
T_ET := T#0s;
T_Run := FALSE;
END_IF;
T_Q := T_Run AND T_ET >= T#3s;
(* R_TRIG E: CLK = x ; internal E_Mem, E_Q : BOOL *)
E_Q := x AND NOT E_Mem;
E_Mem := x;
(* CTU C: CU = x, PV = 5 ; internal C_CV : INT, C_Mem, C_Q : BOOL *)
IF x AND NOT C_Mem AND C_CV < 32767 THEN C_CV := C_CV + 1; END_IF;
C_Mem := x;
C_Q := C_CV >= 5;
```
TOF, TP, F_TRIG, CTD follow the same idea. Timer accuracy is the cycle: a review item says so,
and CYCLE must equal the E_CYCLE period (both come from the one CYCLE input in the App FB).
Rockwell RTO: keep T_ET when cond goes false, reset it only on the RES condition.
## 4. ST rules in 4diac
- Every statement ends in `;`, including `END_IF;`, `END_CASE;`, `END_FOR;`.
- Comments: `(* *)`, `/* */` or `//`.
- Typed literals are fine (`BOOL#TRUE`, `T#500ms`, `16#FF`); bit access `x.3` is allowed.
- No located variables (`AT %IX0.0`), no CODESYS extensions (POINTER TO, ADR, `__NEW`,
`S=`/`R=`, THIS^/SUPER^), no `{}` pragmas.
- Algorithms are stored as `ALGORITHM <name> ... END_ALGORITHM` inside the `<ST>` element.
## 5. Events and sampling
A Basic FB only reads a data input when an event that lists it (`<With Var=...>`) arrives, and
connected FBs only see an output when an event that lists it fires. The generator associates
everything with INIT/REQ and INITO/CNF. If you edit the types, keep that: `iec61499_check.py`
warns `[sampling]` when an algorithm reads an input its trigger event doesn't carry, or writes an
output its output event doesn't carry. Generated output must have none.
## 6. I/O, HMI and retentive data
- I/O: inputs and outputs connect to the target device's I/O FBs in the application (4diac has
them per platform, e.g. for Raspberry Pi or Modbus). Which pin is which is a high review item.
- HMI/SCADA: data reaches an HMI through communication FBs (OPC UA, MQTT, PUBLISH/SUBSCRIBE,
CLIENT/SERVER in 4diac's library), not through addresses. Every HMI tag needs one: list them as
review items with the HMI rebind. Former `%M` HMI setpoints become data inputs fed that way.
- Retentive: IEC 61499 has no RETAIN. Internal values last while the resource runs; values that
must survive a restart need explicit storage. High review item for every retentive value
(Rockwell sources: all of them).
- Safety: not a safety platform. Safety logic stays excluded.
## 7. Deliverables and checks
1. `out/<project>_61499.st`: the scan body as one PROGRAM/FUNCTION_BLOCK following section 3.
2. `python3 <skill>/scripts/st_to_61499.py out/<project>_61499.st --cycle T#<ms>ms -o out/61499/`.
Its warnings (FB instances, `%M` variables, RETAIN) become review items or fixes.
3. `python3 <skill>/scripts/iec61499_check.py out/61499/*.fbt`: zero errors and no `[sampling]`
warnings before you present anything.
4. Verify with `simulate.py compare --target out/61499/<Name>.fbt --target-entry <Name>.REQ`
(results are simulated, not hardware-tested).
SHA-256: af448b5f92765fe94518479303623a65e024c12023108774318a439baa2ad798