Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22077

How to Set Structure Padding and Alignment when Targeting ARM with Clang/GCC Compilation?

$
0
0

I am developing a bare-metal application in Rust using bindings generated from C code. My microcontroller is based on the Cortex-M0 core.

I compile the C source code using Clang/GCC to generate a .a static library, then use bindgen to generate bindings and develop the application in Rust, linking it with this static library.

However, when dealing with some structures, there is an issue where the structs compiled with Clang/GCC are not aligned, and the member offsets do not increment regularly. The bindings are 4-byte aligned, leading to memory access issues.

This problem occurs with both GCC and Clang, though the structures that exhibit severe issues may differ in the two compilers.

Here is one of the structs with incorrect offsets:

typedef struct __DMA_HandleTypeDef{  DMA_Channel_TypeDef   *Instance;                                                    /*!< Register base address                  */  DMA_InitTypeDef       Init;                                                         /*!< DMA communication parameters           */  HAL_LockTypeDef       Lock;                                                         /*!< DMA locking object                     */  __IO HAL_DMA_StateTypeDef  State;                                                   /*!< DMA transfer state                     */  void                  *Parent;                                                      /*!< Parent object state                    */  void                  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA transfer complete callback         */  void                  (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback    */  void                  (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer error callback            */  void                  (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer abort callback            */  __IO uint32_t         ErrorCode;                                                    /*!< DMA Error code                         */  DMA_TypeDef          *DmaBaseAddress;                                               /*!< DMA Channel Base Address                */  uint32_t              ChannelIndex;                                                 /*!< DMA Channel Index                       */} DMA_HandleTypeDef;

This structure (including DMA_InitTypeDef Init) has 18 members in total, and the size after alignment should be 72 btyes. However, the actual size is 68 btyes, and the offsets of the internal members do not increase evenly.

In bindings, the structure size is exactly 72 btyes.

  int len = sizeof(DmaHandle);  int offset1 = offsetof(struct __DMA_HandleTypeDef2, Lock);  int offset2 = offsetof(struct __DMA_HandleTypeDef2, State);
bt full...len = 68offset1 = 0offset2 = 33

One of the members, Lock, is an enum that occupies only one byte within the structure after compilation.

typedef enum{  HAL_UNLOCKED = 0x00U,  HAL_LOCKED   = 0x01U} HAL_LockTypeDef;

I have tried the following options with both compilers:

-fno-pack-struct-fpack-struct=4#pragma pack(push, 4)#pragma pack(4)__attribute__((aligned(4)))

But none seem to enforce padding and alignment for the structures.


Viewing all articles
Browse latest Browse all 22077

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>