3
votes

I'm trying to find a good way to align variables on a bondary of 32 bits or 16 bits with GCC.

I'm working on a Cortex-M0 that doesn't support the missaligned data acess. I have this problem when I use -Os. I use arm-none-eabi version 4.6.2. I have this small test case:

#include "stdint.h"

typedef struct Struct_HdrPrefix{
    uint8_t Prefix;
    uint16_t Type;
}__attribute((packed))Struct_HdrPrefix;

volatile Struct_HdrPrefix test;
volatile Struct_HdrPrefix test1;

int main(void)
{
    test.Type = 0;
    while(1)
        __asm("nop");
}

void HardFault_Handler(void)
{
    while(1)
        __asm("nop");
}

When I compile this I get a non aligned variable test.

Here is the result in the map file:

COMMON         0x20000000        0x6 ./SRC/main.o
               0x20000000                test1
               0x20000003                test

So now I got to hardfault. If I add this to the vars:

volatile Struct_HdrPrefix test __attribute((aligned (4)));
volatile Struct_HdrPrefix test1 __attribute((aligned (4)));

This is working as expected since test is now aligned.

I can't use the align attribute on the struct since this struct could be part of another one packed too.

Is there a way to tell GCC or LD to align packed variables on a 32 bits boundary?

Regards

1
If you tell the compiler to pack a structure, you're telling it to ignore alignment concerns. You can't really have it both ways.Carl Norum

1 Answers

5
votes

If you don't mind:

typedef struct Struct_HdrPrefix{
    uint8_t Prefix;
    uint8_t dummy; // for alignment
    uint16_t Type;
}__attribute((packed))Struct_HdrPrefix;

IF you want both packed structure and aligned fields, there is no other way. You have to align data manually. The only choice you have is where to insert dummy into (and how many to have).