Memory allocation for STRUCT variables!

occam
2011-01-11
2013-07-12
  • occam - 2011-01-11

    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:

    TYPE Tact :
    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] OF DWORD;
       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_STRUCT
    END_TYPE
    

    In order to process th data, I declared a variable

       TxAct AT %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

     
  • Rolf-Geisler - 2011-01-12

    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

     
  • occam - 2011-01-14

    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!

     
  • jachstet - 2013-07-12

    It's possible (at least in CoDeSys V3.5) using the "pack_mode" pragma:

    {attribute 'pack_mode' := '0'}
    TYPE StructDemo :
    STRUCT
    END_STRUCT
    END_TYPE
    
     

Log in to post a comment.