madsci1016 / Arduino-EasyTransfer

An Easy way to Transfer data between Arduinos
http://www.billporter.info/easytransfer-arduino-library/
320 stars 114 forks source link

Struct Packing #12

Open wizard97 opened 8 years ago

wizard97 commented 8 years ago

It seems to me that this library is only portable if both the sender and receiver are on the same platform. To serialize a struct, the library is using memcpy(), which does not take into account how different platforms might pack the struct differently.

I'm not sure if this problem would exist between different Arduino boards, such as the Due (ARM) or the UNO (AVR), but perhaps you should at least warn people of this potential.

bbbowden commented 6 years ago

Thank you for the heads up! I'm trying to adapt this library for UDP between an Atmel ATMega and an ARM based processor. Did a quick check of the size of the structure when compiled for the ATMega and compiled for the ARM processor. Sure enough, ATMega size was 7 and ARM size was 8. Adding "attribute ((packed))" to the definition of the structure ensured that the structures were the same.

wizard97 commented 6 years ago

You also need to worry about endianess, if one end is big endian and the other is little endian, you will get garbage out.

The library needs to always serialize elements into the same byte ordering before sending over the wire. Memcpy is not the right thing to use.

bbbowden commented 6 years ago

I can see how that could cause problems but not sure if this method could be modified. In the end, this library has no idea what is in the data structure / where the element boundaries are, only the size of the entire structures in bytes.

If memcpy isn't the right thing to use, how would you handle it while maintaining the flexibility of not needing to know what is in the structure?

madsci1016 commented 6 years ago

how would you handle it while maintaining the flexibility of not needing to know what is in the structure?

Google Protobuff

wizard97 commented 6 years ago

Google Protobuff

Attempting to use C++ Protobuff's on low memory micro-controllers with no MMU, especially 8-bit AVRs, is a terrible idea.

madsci1016 commented 6 years ago

See https://github.com/nanopb/nanopb

I've used it on 32 bit fine but they claim it runs on 8 bit with only 2-10 kB ROM, <1 kB Ram required.