This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Accessing unaligned memory

Other Parts Discussed in Thread: MSP430FR5739

Hi,

I’ve got a program running on MSP430FR5739 which is trying to read 32bit word from a buffer in the memory located in an unaligned address (e.g. 0x1FC3).
I’m seeing that the compiler is changing the read address to be 32bit aligned.
Why is that?
Is there a way to work around it? Like a compiler directive?
Is there a way to read 32bit (UINT32) from an unaligned memory address or I should make sure that all of my buffers are aligned?
Finally, should the buffer address be 16bit aligned or 32bit aligned?

Thanks,
Alon.S

  • Hi Alon,

    On the MSP430 word (16-bit) accesses must be aligned, and since the simplest way of decomposing a uint32_t is into two 16-bit words the compiler will automatically align it on word boundary.

    If you require byte-addressed access to a uint32_t, try using the #pragam data_alignment=1 directive, which should generate additional instructions to access a uin32_t as bytes.

    Tony

  • Forgot to add that the #pragma data_alignment directive is for the IAR toolchain.

    For CCS use #pragma data_align(1).

    For GCC use #pragma pack(1).

    Tony

  • All word instrucitons of the MSP43 CPU are ignoring the LSB of the address.
    To perform a 16 (or 32) bit read that is not word-aligned, two byte reads are required which are then assembled to a 16 bit value.

    Since this is way less efficient that a 16 bit read, the compiler by default assumes word alignment for word values. And the linekr only places word variables word-aligned too.
    If you are dealign with data streams where word datad si contained unaligned, you have two choices: either do the assembly manually by adding two byte reads to a word variable, or use a struct type instead of an integer, and give teh struct the attribute 'packed'. In this case, the compiler will do the assembling for you. independent of whether the struct * is word aligned or not.

    Alon Srednizki said:
    Finally, should the buffer address be 16bit aligned or 32bit aligned?

    Word aligned is sufficient. The MSp data bus is 16 bit wide, so 32 bit operations are 2*16 bit operations anyway (and not atomic!)

    Alon Srednizki said:
    should make sure that all of my buffers are aligned?

    That's the msot efficient way - but not always possible, e.g. if getting data in a stream buffer

  • Hi,

    I am trying to understand data alignement, but I never saw need to use it.

    So, how will show up problems, where data is not aligned ?

    In this post http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/127319/457093.aspx#457093 it change the values of data ? Thx

  • Mykro Std said:
    So, how will show up problems, where data is not aligned ?


    Assume you have a data stream that is located at 0x2000. At offset 0x0b is a word value. You can try to access it with a pointer:
    int * ptr = 0x200b;
    int a = *ptr;

    Neither compiler nor linker will complain. However, if the CPU sees the instruction to move a word from 0x200B to 'a', it will instead move a word from 0x200a to 'a', ignoring the LSB of the source address. The result is (obviously) not what you want. And you won't get any errors or warnings. The C code is fine, but the processor has a limitation here.

    Under certain circumstances, the compiler is smart enough to determine, that the pointer might be unaligned. In this case, the compiler might generate code that reads two byte values from memory in two registers, using byte access, then combining the two. Which is significantly longer and slower than a real word access.
    However, I wouldn't trust it and double-check with a test case.
    MSPGCC 3.23 before 12/2008 didn't take care of this and produced code that looked 100% correct at first but didn't work in case of unaligned data. (had this with packed data structs which were defined on an Atmel 8-bit system with byte-alignment and received serially, so the unaligned definitions had to match)

**Attention** This is a public forum