0

I have a board with a 32-bit ARM CPU as the main processor and a 8-bit AVR microcontroller as a slave device connected to it.

I am copying a struct (the slave converts it into a byte stream and the master receives and stores it in the memory location of a struct with identical definition).

Both the master and the slave print the values of the struct members on their own consoles. However the values do not match.

I have identified that the problem is occurring because the actual memory allocation of the struct in the master is changed a little to align with 16-bit boundaries. i.e. data types smaller than 16 bits are upgraded to 16 bits.

There are some 8 bit integers (u8) in the struct which are actually being allocated 2 bytes in memory in the Master whereas in the slave they are allocated just 1 byte as expected.

Unsurprisingly, sizeof(STRUCT_NAME) yields different results in each system.

I have figured out a way around this by inserting filler bytes in the incoming data where necessary.

Is there any standard way to handle struct serialization in situations like this?

I'm using GCC for the ARM part.

Dojo
  • 5,374
  • 4
  • 49
  • 79
  • 1
    You might want to look at http://stackoverflow.com/questions/3318410/pragma-pack-effect – silent Dec 06 '16 at 22:29
  • 2
    Three of the biggest problems transferring binary data between different architectures are a) word size, b) byte order, c) alignment. You can mitigate a) by using definitions like `u8`, You can mitigate b) with functions like `ntohs`. And most compilers give you a way to deal with c) with directives like `#pragma pack`: http://www.cplusplus.com/forum/general/14659/ – paulsm4 Dec 06 '16 at 22:36
  • This have been asked many times before. Structs are not portable, simple as that. There are many work-arounds, search for duplicate questions here on SO. – Lundin Dec 07 '16 at 07:38

2 Answers2

2
struct _str
{
    ...
} __attribute__((packed, aligned(1))) struct_name;

Alignment to 1 byte.

i486
  • 6,491
  • 4
  • 24
  • 41
0

Explicitly define how the data are represented during the transmission, then program the conversion to and from the byte stream explicitly.

You can do this by using shift and mask operations. With a few helper functions for common number types this is quite manageable.

This way you avoid all portability issues from different endianness and packing of structures.

starblue
  • 55,348
  • 14
  • 97
  • 151