1

I have been tinkering with rs485 serial bus.

My message is 7 byte array with layout

uint8 address
uint8 command
int32 data
uint8 checksum

I now serialize and deserialize the int32 with bitshifting.

Would it be computationally more efficient to use a union of struct and array than to do the bitwise operations?

2
  • What's the nature of the data in your int32? Is it inherently bit-oriented? Why does it need to be bit-serialized instead of treated as 4 bytes? Commented Dec 3 at 16:25
  • 1
    what bitwise operations are you talking about? Commented Dec 3 at 18:52

1 Answer 1

1

It probably wouldn't make such a big difference, as bit-shiting by multiples of 8 bits is likely very efficient. The union trick may, however, make your code easier to read and write:

union Packet {
    struct {
        uint8_t address;
        uint8_t command;
        int32_t data;
        uint8_t checksum;
    };
    uint8_t bytes[7];
};

void send_a_packet() {
    Packet packet;
    packet.address  = 0x10;
    packet.command  = 0x32;
    packet.data     = 0xba987654;
    packet.checksum = 0xdc;
    // now send packet.bytes through the link.
}

Warnings:

  1. This works on AVR-based arduinos, because they are 8-bit micros that have no alignment constrains. On other architectures you may need to add __attribute__((packed)) to the struct.

  2. This assumes that both endpoints of the communication are little-endian, and agree that the data is to be transmitted in little-endian order. If you work with mixed endianness, you may want to stick with bit-shifting, or use something like htonl().

3
  • Actually the size of bytes does not matter, I saw many sources using simply "1". If the size is bigger than the size of the struct, the union wastes memory. The most correct way could be to name/typedef the struct and then put its size between the brackets, it would transport the intention. Commented Dec 4 at 6:48
  • @thebusybee: I would avoid uint8_t bytes[1];: when printing out the bytes, the compiler complains “iteration 1 invokes undefined behavior”. uint8_t bytes[sizeof(TheStruct)]; is really nicer, but it forces you to name the struct member and write things like packet.fields.address = 0x10;. Not a big deal though. Commented Dec 4 at 7:24
  • 1
    Yeah. I'm working in safety-related software, and therefore we need to avoid potential subtly bugs like this (an erroneous array size) by all means. It shows sometimes. ;-) And we love automatism. Commented Dec 4 at 10:45

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.