This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Alignment of arrays

Hi guys,

I'm currently working with a Cortex-M0 which is incapable of unaligned reads.

I have a byte array which is storing a received packet in a certain protocol, the first lot of information to come in is 1 byte, followed by two 16-bit half-words.

This is leading to misalignment and preventing me from performing any direct casting/pointer access to these values; I can't space the data out as it's being placed in the array by DMA.

I know with a structure it can be packed, however I've had no such luck with pointers and access to my array.

Is it possible to ask the compiler to align the start of my byte array on the edge of a word (3 bytes), so that the rest of my data is aligned? And if so how?

Any other suggestions?

Many thanks for any help and advice.

  • char dummy[PKT_SIZE+3];
    char *buf = dummy+3;
    

    But you really should write manual code to pack/unpack data when transmitting binary information like that. Not only can you have alignment issues but also little/big endian issues. The transfer times are normally so slow in the CPU time frame that it doesn't matter if you have something like:

    p = pickup_u8(buf,&rec.my_byte);
    p = pickup_u16(p,&rec.my_ushort1);
    p = pickup_u16(p,&rec.my_ushort2);
    p = pickup_u8(data,&rec.another_byte);
    ...
    

    Then you would be in the driving seat and be in control.

  • Thanks,

    Was thinking I'd have to do this, a the incoming frame always starts in this format I'll be using pointers and then pack/unpack commands for data after this.

    Cheers

  • The first code I posted was just a concept description. If the raw buffer is a byte array, then the pointer can't be initialized with just +3 - it need to check the align of the byte buffer.

    If going for the buffer/pointer fake instead of doing it the "correct" way with pack/unpack commands, it is normally better to have the raw buffer be an array of 32-bit integers and then typecast when setting the pointer 3 bytes into that array.

    uint32_t dummy[(PKT_SIZE+3)/4+1];  // 32-bit array gets aligned, and one extra word for abuse.
    char *buf = ((uint8_t*)dummy)+3;   // 3 steps into that 32-bit array gives one byte and then aligned data.
    

    All this code will fail magnificently when when one side is big-endian and one is little-endian. And the compiler will not give any warnings.