cancel
Showing results for 
Search instead for 
Did you mean: 

Miscellaneous bit field arrangement in STM32G4

newbie_stm32
Associate III

Hi Community,

I have a bitfield arrangement for one of the driver files which is a 32-bit value. While debugging I was not able to figure out how it is being stored in the register. The bit order and endianness are not always guaranteed in structs and bit fields but I want to have a fair knowledge on how it is being stored.

Bit field arrangement

 

typedef union
{
    uint32_t value;
    
    struct
    {
        uint8_t data_1       : 4;
        uint8_t data_2       : 3;
        uint8_t data_3       : 4;
        uint8_t data_4       : 2;
        uint8_t data_5       : 1;
        uint8_t data_6       : 1;
        uint8_t data_7       : 2;
        const uint8_t data_8 : 3;
    } field;
} reg_t;

 

If I assign a value to fields of data like below the expected 32-bit value data.field.value is 0x88372.

 

reg_t data = {.field.data_8 = 4};
data.field.data_1 = 2;
data.field.data_2 = 7;
data.field.data_3 = 6;
data.field.data_7 = 1;

 

But I am getting 0x110672 why?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

I suspect it doesn't want to split data_3 across different uint8_t values in memory.

Making all the fields uint32_t instead of uint8_t will give you what you want.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

9 REPLIES 9
TDK
Guru

I suspect it doesn't want to split data_3 across different uint8_t values in memory.

Making all the fields uint32_t instead of uint8_t will give you what you want.

If you feel a post has answered your question, please click "Accept as Solution".
LCE
Principal

Interesting.

How does the ARM / compiler handle byte variables within the memory when the linker file declares it as ALIGN(4) ?

Bitfield arrangement is compiler-specific.

In gcc, use __attribute__((packed)) struct, to enforce bitfields layout.

JW

Pavel A.
Evangelist III

Now change the type of fields to int16_t and you'll get yet another value.

Linker? The compiler cannot know how the linker aligns sections, this occurs later at link time.

> In gcc, use __attribute__((packed)) struct, to enforce bitfields layout.

I tried this, it had no effect on the layout. Compiler still forced data_3 to be on a new byte.

If you feel a post has answered your question, please click "Accept as Solution".

This is an intricate issue and many things can go wrong - there are global settings influencing bitfield packing, maybe alignment of the struct's allocation influences that too, gcc version is a factor, and there may even be switches/configuration upon gcc compilation influencing that. For example, https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute says:

Note: The 4.1, 4.2 and 4.3 series of GCC ignore the packed attribute on bit-fields of type char. This has been fixed in GCC 4.4 but the change can lead to differences in the structure layout. See the documentation of -Wpacked-bitfield-compat for more information.

There are also "funny" options which influence bitfield packing ordering in a very subtle (but of course important when it comes to interoperability) ways, for example this x86-specific option: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mms-bitfields (guess why do I know about it).

My gcc setup (5.4.1 20160609 from launchpad - and again I don't know what are all the factors impacting this) results in 0x110672 without packed attribute, and 0x88372 with it.

JW

PS. The "legal" framework for gcc is https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html (Whether a bit-field can straddle a storage-unit boundary ) and in relevant portion of ARM ABI (AAPCS32)  the note at the end of chapter 8.1.7.1 Bit-fields no larger than their container

 

@TDK that was a good observation that helped me a lot. Thank you. 

@waclawek.jan thanks for pointing out resources to have a look at. It was a great learning for me.

@Pavel A. Yes, it does.