Hi everybody,
Please give me hint how to deal with the following problem:
I'm using CoDeSys V.2.3.9.22 to program an ABB PM554 PLC.
Using one of its COM ports as a MODBUS master, I'm gathering chunks of data from several slave controllers and am trying to put the data together into a STRUCT as follows:
TYPETact:STRUCTÂ Â MsrSt:WORD;Â Â CrtWeight:REAL;Â Â Â Â Â Â Â Â TxState:BYTE;Â Â ChngID:WORD;Â Â SoChng:DT;Â Â EoChng:DT;Â Â TxWeight:REAL;Â Â TaraWeight:REAL;Â Â BrtWeight:REAL;Â Â TxSt:WORD;Â Â TxNr:ARRAY[1..2]OFDWORD;Â Â IntTxNr:WORD;Â Â TxDir:WORD;Â Â SoTx:DT;Â Â EoTx:DT;Â Â ProdCode:STRING(16);Â Â TtlIn:LREAL;Â Â TtlOut:LREAL;Â Â TtlCodeIn:LREAL;Â Â TtlCodeOut:LREAL;Â Â TrsprtType:WORD;Â Â TrsprtNr:STRING(32);Â Â PADNr:STRING(32);END_STRUCTEND_TYPE
In order to process th data, I declared a variable
  TxActAT%MW0.200:Tact;
The problem I face is that memory for the structure gets allocated at DWORD boundaries for the STRUCT members - i.e. TxAct.MsrSt as well as all WORD and BYTE members occupy 2 registers instead of 1. But this is not the case in the controllers I read from! Is it possible to "enforce" strict size alignment for the allocation of the structure?
Thnx in advance
Best regards
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi occam,
I guess it's an issue of CPU architecture. On 32 bit CPUs any variable resp. STRUCT member occupies 32 bit. That's the only way to have a quick access to it - the address conversions to break down to 16 bit or less take a lot of time and would bring up PLC CPU load without any benefit. The controllers you read from probably have a 16 bit embedded controller, don't they?
Since you have declared a fixed address for the received data, the 4 byte boundaries are visible. Let the compiler decide where to store it (by using a simple variable declaration without the AT assignment)
```
VAR
 TxAct : Tact;
END_VAR
```This could solve the problem.
To process the data, you do not need to know their address. You can access to it directly via TxAct.
Have success. Regards,
Rolf
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Rolf,
Thanks for your reply!
I'm afraid, your advice won't help - unless I "reassemble" anew in order to fill the STRUCT with alignment bytes. In this case I'll have to disassemble the STRUCT back in order to return it to the controllers after processing or will have to increase the number of messages in order to skip non significant bytes added by the compiler.
I was hoping for a miracle solution - a pragma in the compiler to allow for "tight" allocation, sacrificing speed over memory!
So I'll skip the STRUCT variable alltogether and go with plain variable declarations.
Best regards and thanks for your effort!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi everybody,
Please give me hint how to deal with the following problem:
I'm using CoDeSys V.2.3.9.22 to program an ABB PM554 PLC.
Using one of its COM ports as a MODBUS master, I'm gathering chunks of data from several slave controllers and am trying to put the data together into a STRUCT as follows:
In order to process th data, I declared a variable
The problem I face is that memory for the structure gets allocated at DWORD boundaries for the STRUCT members - i.e. TxAct.MsrSt as well as all WORD and BYTE members occupy 2 registers instead of 1. But this is not the case in the controllers I read from! Is it possible to "enforce" strict size alignment for the allocation of the structure?
Thnx in advance
Best regards
Hi occam,
I guess it's an issue of CPU architecture. On 32 bit CPUs any variable resp. STRUCT member occupies 32 bit. That's the only way to have a quick access to it - the address conversions to break down to 16 bit or less take a lot of time and would bring up PLC CPU load without any benefit. The controllers you read from probably have a 16 bit embedded controller, don't they?
Since you have declared a fixed address for the received data, the 4 byte boundaries are visible. Let the compiler decide where to store it (by using a simple variable declaration without the AT assignment)
```
VAR
 TxAct : Tact;
END_VAR
```This could solve the problem.
To process the data, you do not need to know their address. You can access to it directly via TxAct.
Have success. Regards,
Rolf
Hi Rolf,
Thanks for your reply!
I'm afraid, your advice won't help - unless I "reassemble" anew in order to fill the STRUCT with alignment bytes. In this case I'll have to disassemble the STRUCT back in order to return it to the controllers after processing or will have to increase the number of messages in order to skip non significant bytes added by the compiler.
I was hoping for a miracle solution - a pragma in the compiler to allow for "tight" allocation, sacrificing speed over memory!
So I'll skip the STRUCT variable alltogether and go with plain variable declarations.
Best regards and thanks for your effort!
It's possible (at least in CoDeSys V3.5) using the "pack_mode" pragma: