You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds initialization logic for user-defined `FB_INIT` methods and updates the user-documentation.
Struct-types now get an additional init-function for user-initialization, which will call the `FB_INIT` if present and then initialize each member, similar to the already present `__init_<type>` functions. The user_init functions (`__user_init_<type>`) are guaranteed to be called after the implicit init is finished to allow pointers to be initialized beforehand.
A `FUNCTION` defines a return value in the signature, while a `FUNCTION_BLOCK` relies on `VAR_OUTPUT` definitions.
@@ -334,6 +332,67 @@ pub struct myStruct {
334
332
```
335
333
336
334
### 2.5 `FUNCTION_BLOCK` initialization
337
-
Not yet implemented.
335
+
336
+
When creating a library with `FUNCTION_BLOCK`s, you can implement initialization logic that runs when an instance is created.
337
+
338
+
For more details on `FB_INIT` in IEC61131-3, refer to the [Program Organization Units (POUs)](../pous.md#function_block-initialization) documentation.
339
+
340
+
#### Interoperability with libraries written in other languages
341
+
342
+
When implementing a `FUNCTION_BLOCK` with initialization in C or other languages, you need to follow a specific naming convention for the initialization function.
343
+
344
+
For a C implementation:
345
+
346
+
1. Define a struct that matches your `FUNCTION_BLOCK` variables:
347
+
348
+
```c
349
+
typedefstruct {
350
+
int a;
351
+
int b;
352
+
// Other members as needed
353
+
} myFunctionBlock;
354
+
```
355
+
356
+
2. ruSTy expects a default-initializer to be present to initialize instances on the stack
357
+
(`VAR_TEMP` blocks or `VAR` blocks in functions or methods)
358
+
359
+
This global instance follows the naming scheme of `__<FunctionBlockName>__init`, below is an example of a zero-initializer:
360
+
361
+
```c
362
+
myFunctionBlock __myFunctionBlock__init = { 0 };
363
+
```
364
+
365
+
3. Optionally create an initialization function following the naming pattern `<FunctionBlockName>_FB_INIT`:
4. In your IEC61131-3 declaration (e.g., in a header file [`*.pli`]), ensure your `FUNCTION_BLOCK` includes the `FB_INIT` method (if present):
378
+
379
+
```
380
+
{external}
381
+
FUNCTION_BLOCK myFunctionBlock
382
+
VAR
383
+
a : DINT;
384
+
b : DINT;
385
+
END_VAR
386
+
METHOD FB_INIT
387
+
END_METHOD
388
+
END_FUNCTION_BLOCK
389
+
```
390
+
391
+
Note that the `FB_INIT` method doesn't need implementation details in the IEC61131-3 declaration when using an external implementation - the declaration just signals that initialization is available.
392
+
393
+
#### Project-wide initialization
394
+
395
+
See [Project-wide initialization](../using_rusty.md#project-wide-initialization)
Copy file name to clipboardExpand all lines: book/src/pous.md
+22
Original file line number
Diff line number
Diff line change
@@ -147,6 +147,28 @@ END_VAR
147
147
END_FUNCTION_BLOCK
148
148
```
149
149
150
+
#### `FUNCTION_BLOCK` initialization
151
+
Function blocks can define a special method called `FB_INIT` that is automatically called when an instance is created. This is analogous to a constructor in object-oriented programming.
152
+
153
+
The `FB_INIT` method allows you to initialize the function block's variables to specific values. It is called during program initialization before any other code runs.
154
+
155
+
`FB_INIT` methods can neither have parameters nor a return type in their current implementation - violating this contract will lead to undefined behaviour at runtime.
156
+
157
+
```iecst
158
+
FUNCTION_BLOCK MyFB
159
+
VAR
160
+
x : INT;
161
+
y : INT;
162
+
END_VAR
163
+
METHOD FB_INIT
164
+
x := 1;
165
+
y := 2;
166
+
END_METHOD
167
+
168
+
// Other methods and code...
169
+
END_FUNCTION_BLOCK
170
+
```
171
+
150
172
### Action
151
173
152
174
An action is represented by a parent struct, and does not define its own interface (VAR blocks).
Copy file name to clipboardExpand all lines: book/src/using_rusty.md
+26
Original file line number
Diff line number
Diff line change
@@ -136,3 +136,29 @@ Outputs the json schema used for the validation of the `plc.json` file
136
136
Ouputs a json file with the default error severity configuration for the project.
137
137
See [Error Configuration](./error_configuration.md) for more information.
138
138
139
+
## Project-wide initialization
140
+
141
+
When your code is compiled, the compiler creates a special initialization function with the naming pattern `__init___<projectname>`. This function is responsible for calling all implicit and user-defined initialization code, including all [`FB_INIT`](../pous.md#function_block-initialization) methods.
142
+
143
+
`<projectname>` is either taken directly from the `plc.json`'s `name` field or derived from the first input file (replacing `.`/`-` with `_`) when compiling without a `plc.json` (e.g. `plc prog.st ...` would yield `__init___prog_st`).
144
+
145
+
This function is added to the global constructor list, therefore loading the binary will automatically call the `__init___<projectname>` function (and therefore your `<FunctionBlockName>_FB_INIT` function) when an instance of your function block is created, before any other methods are called. This allows you to set default values or perform required setup for your function block.
146
+
147
+
> **IMPORTANT:** The global constructor initialization is currently only supported for `x86` ISAs. To make sure initialization code runs reliably regardless of target-architecture, ensure your runtime calls this function before starting main task execution.
148
+
If you're using the executable without a runtime, you **must** ensure that `__init___<projectname>` is called before any other code runs. Failure to do so will result in uninitialized function blocks and pointers, which can lead to undefined behavior and/or crashes.
149
+
150
+
Example of ensuring initialization when using C (crt0):
Copy file name to clipboardExpand all lines: compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_in_different_locations_with_debug_info.snap
Copy file name to clipboardExpand all lines: compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_files_with_debug_info.snap
Copy file name to clipboardExpand all lines: compiler/plc_driver/src/tests/snapshots/plc_driver__tests__multi_files__multiple_source_files_generated.snap
0 commit comments