Reputation: 10294
I am working on firmware for a 16-bit PIC and writing in C (Microchip C30 compiler). My device receives a long list of bytes from an external device, and then I am trying to copy those bytes into a structure. The structure is defined as follows:
typedef struct __attribute__((__packed__)) {
char F1Nickname[17];
char F2Nickname[17];
DWORD F1CurrentPos;
DWORD F2CurrentPos;
WORD F1CurrentTemp;
WORD F2CurrentTemp;
DWORD F1MaxPos;
DWORD F2MaxPos;
BYTE F1TempCompOn;
BYTE F2TempCompOn;
BYTE CheckSum;
} deviceStatus;
I was having a strange problem that whenever the total number of bytes in the structure was an odd number my program would freeze and get caught in AddressError service routine. I can fix the problem by simple adding an extra byte to the struct but that seems like a band-aid fix.
I put the packed attribute on the structure because I wanted to make sure the compiler didn't insert any filler bytes in between my variables. If that were to happen, the values in my structure would be incorrect when copied over from the received character array.
I know there is also an attribute called aligned. Does aligned just align the start of the structure to an even byte or does it align every item in the structure to an even byte? Do you think the aligned attribute is required here? If I add the aligned attribute to this structure, I should also add it to the structure on the device that is sending the data, right? As of now they are both defined the exact same way as shown above.
If I add the aligned attribute should I remove the packed attribute? Don't they basically do the opposite?
Upvotes: 3
Views: 4955
Reputation: 28932
Certain microprocessor architecture can only do a data fetch on an address that is aligned to word boundaries and will throw an exception if they are not word aligned. Often the compiler will help out and generate code that performs the necessary acrobatics to ensure the fetches are word aligned but this does not seem to be the case with your compiler and that is why you are seeing the exceptions.
In your case, you are using a struct
to serialize data and therefore it must be packed. In this case you must either rearrange your struct
to ensure that there are no reads across word boundaries or you will need to use and unpacked struct and hand serialize the data.
Upvotes: 2
Reputation: 71120
The __attribute__
and __packed__
are not part of the C standard and are extensions that your compiler is providing. The only way to know for sure what they mean is to look it up in the compiler documentation.
Upvotes: 2