The data structure alignment not correct

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The data structure alignment not correct

462 Views
jasonedn
Contributor II

I tried to align the structure members, but it seems the MCUXpresso compiler doesn't. 
I created two data types  based on the original spdif_config_t as below:

typedef struct _spdif_config_t
{
bool isTxAutoSync; /*!< If auto sync mechanism open */
bool isRxAutoSync; /*!< If auto sync mechanism open */
uint8_t DPLLClkSource; /*!< SPDIF DPLL clock source, range from 0~15, meaning is chip-specific */
uint8_t txClkSource; /*!< SPDIF tx clock source, range from 0~7, meaning is chip-specific */
spdif_rxfull_select_t rxFullSelect; /*!< SPDIF rx buffer full select */
spdif_txempty_select_t txFullSelect; /*!< SPDIF tx buffer empty select */
spdif_uchannel_source_t uChannelSrc; /*!< U channel source */
spdif_tx_source_t txSource; /*!< SPDIF tx data source */
spdif_validity_config_t validityConfig; /*!< Validity flag config */
spdif_gain_select_t gain; /*!< Rx receive clock measure gain parameter. */
} spdif_config_t;

typedef struct _spdif_config_t1
{
bool isTxAutoSync; /*!< If auto sync mechanism open */
bool isRxAutoSync; /*!< If auto sync mechanism open */
uint8_t DPLLClkSource; /*!< SPDIF DPLL clock source, range from 0~15, meaning is chip-specific */
uint8_t txClkSource; /*!< SPDIF tx clock source, range from 0~7, meaning is chip-specific */
spdif_rxfull_select_t rxFullSelect; /*!< SPDIF rx buffer full select */
spdif_txempty_select_t txFullSelect; /*!< SPDIF tx buffer empty select */
spdif_uchannel_source_t uChannelSrc; /*!< U channel source */
spdif_tx_source_t txSource; /*!< SPDIF tx data source */
spdif_validity_config_t validityConfig; /*!< Validity flag config */
spdif_gain_select_t gain; /*!< Rx receive clock measure gain parameter. */
} spdif_config_t1_t __attribute__(aligned(4));


#pragma pack(push, 4)
typedef struct _spdif_config_t2
{
bool isTxAutoSync; /*!< If auto sync mechanism open */
bool isRxAutoSync; /*!< If auto sync mechanism open */
uint8_t DPLLClkSource; /*!< SPDIF DPLL clock source, range from 0~15, meaning is chip-specific */
uint8_t txClkSource; /*!< SPDIF tx clock source, range from 0~7, meaning is chip-specific */
spdif_rxfull_select_t rxFullSelect; /*!< SPDIF rx buffer full select */
spdif_txempty_select_t txFullSelect; /*!< SPDIF tx buffer empty select */
spdif_uchannel_source_t uChannelSrc; /*!< U channel source */
spdif_tx_source_t txSource; /*!< SPDIF tx data source */
spdif_validity_config_t validityConfig; /*!< Validity flag config */
spdif_gain_select_t gain; /*!< Rx receive clock measure gain parameter. */
} spdif_config_t2_t;
#pragma pack(pop)

I printed the size using sizeof(spdif_config_t/spdif_config_t1_t/spdif_config_t2_t), all of the sizes 10.

However sizeof(spdif_config_t) should be different from sizeof(spdif_config_t1_t/spdif_config_t2_t) if the alignment works.

Can anybody help with this issue? 

0 Kudos
4 Replies

386 Views
rudi_cyber
Contributor III

Could you please try  aligned(1) or pack(push, 1). 

Because 32bit compiler  self-alignment is 4 bytes. 

Pack will lower the performance. 

0 Kudos

377 Views
jasonedn
Contributor II

Hi rudi_cyber,

The MCUXPresso default alignment is 1-byte and I want 4-byte alignment. The release build at -O3 craches if it's 1-byte alignment.

0 Kudos

352 Views
rudi_cyber
Contributor III

You can use objdump to check the size of bool in the toolchain.

And readelf to double confirm the alignment. 

Usually, bool is 1 byte in toolchain. So the first 4 members seem in one 32bit, it doesn't matter pack 1 or pack 4.

objdump

<2><ee>: Abbrev Number: 0
<1><ef>: Abbrev Number: 2 (DW_TAG_base_type)
<f0> DW_AT_byte_size : 1
<f1> DW_AT_encoding : 2 (boolean)
<f2> DW_AT_name : (indirect string, offset: 0xe4): _Bool
<1><f6>: Abbrev Number: 4 (DW_TAG_volatile_type)
<f7> DW_AT_type : <0xef>
<1><fb>: Abbrev Number: 0



<21> DW_AT_stmt_list : 0x0
<1><25>: Abbrev Number: 2 (DW_TAG_base_type)
<26> DW_AT_byte_size : 4
<27> DW_AT_encoding : 7 (unsigned)
<28> DW_AT_name : (indirect string, offset: 0x129): unsigned int
<1><2c>: Abbrev Number: 3 (DW_TAG_base_type)
<2d> DW_AT_byte_size : 4
<2e> DW_AT_encoding : 5 (signed)
<2f> DW_AT_name : int
<1><33>: Abbrev Number: 2 (DW_TAG_base_type)
<34> DW_AT_byte_size : 8
<35> DW_AT_encoding : 5 (signed)
<36> DW_AT_name : (indirect string, offset: 0x0): long long int
<1><3a>: Abbrev Number: 2 (DW_TAG_base_type)
<3b> DW_AT_byte_size : 8
<3c> DW_AT_encoding : 4 (float)
<3d> DW_AT_name : (indirect string, offset: 0x113): long double
<1><41>: Abbrev Number: 2 (DW_TAG_base_type)

readelf

Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small

 

0 Kudos

392 Views
Harvey021
NXP TechSupport
NXP TechSupport

Hi @jasonedn 

I think that the compiler will put these variables 

< bool isTxAutoSync; /*!< If auto sync mechanism open */

bool isRxAutoSync; /*!< If auto sync mechanism open */

uint8_t DPLLClkSource; /*!< SPDIF DPLL clock source, range from 0~15, meaning is chip-specific */

uint8_t txClkSource; /*!< SPDIF tx clock source, range from 0~7, meaning is chip-specific */ > 

in a uint32.

 

Best regards

Harvey

0 Kudos