The build fails when a C/C++ Function Block POU uses local state variables.
In my case, the can_rx function block needs a local variable called PrevSeq. This variable stores the previous CAN sequence number, so the block can detect if a received CAN frame is new or duplicated.
Simplified context from the function block:
void can_rx_setup(CAN_RX_VARS* data) {
PrevSeq = 0;
}
void can_rx_loop(CAN_RX_VARS* data) {
if (!data->Enable) {
PrevSeq = 0;
return;
}
uint8_t seq1 = /* sequence number extracted from CAN frame */;
if (seq1 != PrevSeq) {
PrevSeq = seq1;
// process the new CAN frame
data->NewData = true;
} else {
// duplicate or stale frame
data->NewData = false;
}
}
PrevSeq must be local to the FB_CAN_RX instance. It cannot be global, because the project may use more than one CAN receiver block. If PrevSeq is global, all instances would share the same previous sequence number. One CAN receiver could then change the state used by another receiver, causing wrong duplicate/new-frame detection.
So PrevSeq has to be stored inside the function block instance state, for example inside CAN_RX_VARS or an equivalent generated structure.
At the moment, the generated C++ code uses PrevSeq directly, but the variable is not declared, so Arduino compilation fails.
Error:
c_blocks_code.cpp:548:5: error: 'PrevSeq' was not declared in this scope
548 | PrevSeq = 0;
| ^~~~~~~
c_blocks_code.cpp:580:9: error: 'PrevSeq' was not declared in this scope
580 | PrevSeq = 0;
| ^~~~~~~
c_blocks_code.cpp:615:17: error: 'PrevSeq' was not declared in this scope
615 | if (seq1 != PrevSeq) {
| ^~~~~~~
The same kind of issue also happens with other local state variables, such as Prev_Send and LAST_FIRE_MS.
Expected behavior:
Local variables used by C/C++ Function Block POUs should be generated as per-instance variables, not as missing symbols and not as globals.
Environment:
OpenPLC Editor 4.2.8
macOS arm64
Target: Raspberry Pico 2
Arduino CLI 1.4.1
STruC++ 0.5.13
The build fails when a C/C++ Function Block POU uses local state variables.
In my case, the can_rx function block needs a local variable called PrevSeq. This variable stores the previous CAN sequence number, so the block can detect if a received CAN frame is new or duplicated.
Simplified context from the function block:
PrevSeq must be local to the FB_CAN_RX instance. It cannot be global, because the project may use more than one CAN receiver block. If PrevSeq is global, all instances would share the same previous sequence number. One CAN receiver could then change the state used by another receiver, causing wrong duplicate/new-frame detection.
So PrevSeq has to be stored inside the function block instance state, for example inside CAN_RX_VARS or an equivalent generated structure.
At the moment, the generated C++ code uses PrevSeq directly, but the variable is not declared, so Arduino compilation fails.
Error:
The same kind of issue also happens with other local state variables, such as Prev_Send and LAST_FIRE_MS.
Expected behavior:
Local variables used by C/C++ Function Block POUs should be generated as per-instance variables, not as missing symbols and not as globals.
Environment:
OpenPLC Editor 4.2.8
macOS arm64
Target: Raspberry Pico 2
Arduino CLI 1.4.1
STruC++ 0.5.13