Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28379D: How does the C2000 bit/byte pad struct fields?

Part Number: TMS320F28379D

SPRU514T – Optimizing C Compiler reference sheet says the following:

7.1.7 Field/Structure Alignment

When the compiler determines the layout of a structure, it provides as many words as are needed to hold
all of the members, while complying with each member's alignment constraint. This means that padding
bytes may be placed between members and at the end of the structure. Each member is aligned as its
type requires.

Types with a size of 16 bits are aligned on 16-bit boundaries. Types with a size of 32 bits or larger are
aligned on 32-bit (2 word) boundaries. For details on EABI field alignment, refer to the C28x Embedded
Application Binary Interface (EABI) Reference Guide (SPRAC71).

However, bit-fields may not be aligned as strictly as the declared type of the bit-field would be if it were not
a bit-field. Bit-fields are packed in the order seen in the source code. The least significant bits of the
structure word are filled first. Bit-fields are allocated only as many bits as requested. Bit-fields are packed
into adjacent bits of a word.

For COFF, bit-fields do not overlap word boundaries. If a bit-field would overlap into the next word, the
entire bit-field is placed into the next word.

Can you please clarify explicitly and exactly under what conditions the C2000 pads struct members/bitfields (COFF)? This is very important for our CAN messaging architecture which relies heavily on bytes being ordered/packed correctly. From what I can gather from the field/structure alignment section there are 3 conditions that must be followed.

  1. 16-bit native data types (uint16_t, int16_t, etc.) must be 16-bit aligned.
    1. Does this mean that if I have a 1-bit field followed by a 16-bit field, 15 bits of padding will be added between the 1-bit field and the 16-bit field?
    2. Similarly, if I have an 8-bit field followed by a 16-bit field, 8 bits of padding will be added between the 8-bit field and the 16-bit field?
  2. 32-bit+ native data types (uint32_t, uint64_t, etc.) must be 32-bit aligned (2-words).
    1. Does this mean that if I have a 1-bit field followed by a 32-bit field, 31 bits of padding will be added between the 1-bit field and the 32-bit field?
    2. Does this mean if I have a 16-bit field followed by a 32-bit field, 16 bits of padding will be added between the 16-bit field and the 32-bit field?
  3. For COFF, bit fields don't overlap word (16-bit?) boundaries. If overlapping, entire bit-field is placed into next word.
    1. How would this work for bit fields that are greater than 16-bits in size? Those technically have to overlap word boundaries, no? For example, an 8-bit field followed by a 24-bit field (which is one case I've actually tested and it fits into 32 bits in memory...seemingly violating this rule)?
    2. What would happen if there was a 9-bit field followed by 24-bit field? Would there be 7 bits of padding (16-bit/word aligned) or 23 bits of padding (32-bit aligned)?

These are just a couple example questions, but overall, the datasheet doesn't seem to match what is being observed (or at the very least, I am misunderstanding what it's saying). I need clarification on exactly how bit/byte alignment works in the C2000 for structs/bitfields (COFF) and most importantly what constraints we need to follow so that intermediary bit/byte padding does not happen since our CAN architecture requires strict byte ordering.

Thanks!

  • The answer to all 4 of these questions ...

    • 16-bit native data types (uint16_t, int16_t, etc.) must be 16-bit aligned.
      1. Does this mean that if I have a 1-bit field followed by a 16-bit field, 15 bits of padding will be added between the 1-bit field and the 16-bit field?
      2. Similarly, if I have an 8-bit field followed by a 16-bit field, 8 bits of padding will be added between the 8-bit field and the 16-bit field?
    • 32-bit+ native data types (uint32_t, uint64_t, etc.) must be 32-bit aligned (2-words).
      1. Does this mean that if I have a 1-bit field followed by a 32-bit field, 31 bits of padding will be added between the 1-bit field and the 32-bit field?
      2. Does this mean if I have a 16-bit field followed by a 32-bit field, 16 bits of padding will be added between the 16-bit field and the 32-bit field?

    ... is yes.

    Regarding ...

    For COFF, bit fields don't overlap word (16-bit?) boundaries. If overlapping, entire bit-field is placed into next word.
    1. How would this work for bit fields that are greater than 16-bits in size? Those technically have to overlap word boundaries, no? For example, an 8-bit field followed by a 24-bit field (which is one case I've actually tested and it fits into 32 bits in memory...seemingly violating this rule)?
    2. What would happen if there was a 9-bit field followed by 24-bit field? Would there be 7 bits of padding (16-bit/word aligned) or 23 bits of padding (32-bit aligned)?

    I agree the manual does not address the case of bit fields that are larger than 16-bits.  I filed EXT_EP-10406 to have this addressed.  You are welcome to follow it at that link.

    In the mean time, you are welcome to send me the C code for a bit field structure, and I'll tell you how the compiler lays it out.

    Thanks and regards,

    -George

  • Thank you for investigating. The main examples I was curious about were the two referenced above:

    For COFF, bit fields don't overlap word (16-bit?) boundaries. If overlapping, entire bit-field is placed into next word.
    1. How would this work for bit fields that are greater than 16-bits in size? Those technically have to overlap word boundaries, no? For example, an 8-bit field followed by a 24-bit field (which is one case I've actually tested and it fits into 32 bits in memory...seemingly violating this rule)?
    2. What would happen if there was a 9-bit field followed by 24-bit field? Would there be 7 bits of padding (16-bit/word aligned) or 23 bits of padding (32-bit aligned)?

    So the structs would look something like:

    // example 1
    typedef struct A_tag
    {
        uint16_t field1 : 8;
        uint32_t field2 : 24;
    } A;
    
    // example 2
    typedef struct B_tag
    {
        uint16_t field1 : 9;
        uint32_t field2 : 24;
    } B;

    These examples would be good to confirm some expected behavior, but also, rather than working backwards with some examples and trying to figure out the bit/byte padding rules the compiler uses. I would rather know what rules the compiler uses for bit/byte padding so we can cover all bitfield use cases. No matter the configuration, order, or data types, we should know the deterministic/expected behavior for all struct/bitfield cases.

    Thank you.

  • In the structure layouts which follow:

    • 16-bit words are in shown little endian order
    • Within a word, most significant bits start on the left

    Legend:

    • A: bit for field A
    • B: bit for field B
    • x: bit not used

    For example 1 ...

    struct bf_tag {
       uint16_t A :  8;
       uint32_t B : 24;
    } bf;
    
           +----+----+----+----+
    bf   : |BBBB|BBBB|AAAA|AAAA|
           +----+----+----+----+
    bf+1 : |BBBB|BBBB|BBBB|BBBB|
           +----+----+----+----+

    For example 2 ...

    struct bf_tag {
       uint16_t A :  9;
       uint32_t B : 24;
    } bf;
    
           +----+----+----+----+
    bf   : |xxxx|xxxA|AAAA|AAAA|
           +----+----+----+----+
    bf+1 : |xxxx|xxxx|xxxx|xxxx|
           +----+----+----+----+
    bf+2 : |BBBB|BBBB|BBBB|BBBB|
           +----+----+----+----+
    bf+3 : |xxxx|xxxx|BBBB|BBBB|
           +----+----+----+----+

    I would rather know what rules the compiler uses for bit/byte padding so we can cover all bitfield use cases.

    I understand.  That is why I filed EXT_EP-10406.  That entry requests that these details be added to the documentation by the compiler development team.

    Thanks and regards,

    -George