B&R PLC Tag Memory Usage

Hi Community,

I found this interesting thing when I was trying to find a way to generalize some of our program so I can convert some loose ACTIONS to a standard function block. After encountering the below question, my idea probably won’t work but my curiosity is burning.

Below is an example. Tag New_Variable1 is a UDT tag with a few basic data type items in it. Tag New_Variable is an array of 30 bytes.

I did a memory copy from the UDT tag to the byte array with the length of the UDT.

I noticed 3 interesting things here:

  1. The UDT’s byte size is bigger than each element’s size combined:
    |Data Type | Size in Byte|
    |— | —|
    |BYTE | 1|
    |BOOL | 1|
    |WORD | 2|
    |BOOL | 1 + 1 because LREAL needs to start at an even number offset|
    |LREAL | 8|
    |SINT | 1|
    The UDT’s size should be 15 bytes but from the copying result we can see that the last SINT sits on byte 16 so actually the UDT uses 17 bytes to store the data.

  2. the SIZEOF() command returns 20 bytes as the UDT’s size.
    So the UDT is actually using more bytes to store the values than 17 as reflected by the byte array.

  3. One obvious thing is a LREAL should take 8 bytes but after copying, bytes 6 - 15 are used by the LREAL copy.

I can see that based on observation 1 and 3, the 2 bytes difference is due to the LREAL’s mysterious 2 bytes.

I can’t find any explanation to 2.

I suppose we have some B&R experts who can help me out here😁

Hello,

If you are using Structures you might encounter a situation, in which, a “filling byte” is placed by the compiler. This will result in a huger memory demand than it might initialy look like.
Memory Alignment

If you are working with memory you should also get to known about the Dataformat. If you recieve data from an network this might also be an situation were you have to adapt data.
Dataformat

This Help Sections are for SG4 Targets. Old SG3 and new ARM might be different.

Greetings
Michael

3 Likes

Hi,

(SG4 only)

Your byte order is this:

 BYTE    | BOOL     | WORD    | WORD    |
 BOOL    | <EMPTY>  | <EMPTY> | <EMPTY> |
 LREAL   | LREAL    | LREAL   | LREAL   |
 LREAL   | LREAL    | LREAL   | LREAL   |
 SINT    | <EMPTY>  | <EMPTY> | <EMPTY> |

This explains the size of 20 (reply to 2). It also shows that the assumption that bytes 6-15 are the LREAL is wrong and it is actually placed at bytes 8-15 - as expected. Your bytes 6 and 7 are not part of the LREAL but are filler bytes and thus “0” as well :slight_smile:

This is due to memory alignment, as stated by the reply above.

What you can do to reduce the memory footprint is taking advantage of this knowlegde: Move the SINT after the second BOOL and see it magically shrink to 16 bytes:

 BYTE    | BOOL     | WORD    | WORD    |
 BOOL    | *SINT*   | <EMPTY> | <EMPTY> |
 LREAL   | LREAL    | LREAL   | LREAL   |
 LREAL   | LREAL    | LREAL   | LREAL   |

1 Like

Hi Michael,

Thank you for your reply. I though memory alignment was only applicable to odd and even number start address. It’s clear to me now.

Hi Michael,

Thank you for your reply.

I normally will do the manual optimization though the UDT was not made by me…

I wonder if B&R will provide some option like SIEMENS’s optimized DB access that should be a similar thing…