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

Unaligned access problems

Note: This was originally posted on 1st June 2009 at http://forums.arm.com

We had written some code for an ARM Cortex M3 platform. But now, we have to port it to an ARM7TDMI based controller in very little time. The problem is the former supports unaligned access, but the latter doesnt. Now, we have lots of code of the form:

unsigned int a;
char b[100];
a =  *( ( unsigned int *) &b[5] );


As you can see, we were using typecasts to copy 4-byte entities and also 2 byte entities in many places. We are using IAR compiler. The code works fine when run on Cortex M3 but when ARM7TDMI encounters this kind of instructions, it goes into abort. Is there any way we can cause the compiler to generate appropriate instructions so that aborts do not occur, other than replacing all of this kind of instructions with byte-wise memcopys ?
  • Note: This was originally posted on 25th June 2009 at http://forums.arm.com

    A C compiler will always generally assume that integers are aligned - so there is normally no "quick" solution to this problem. Casting an integer to an unaligned memory address is not strictly valid C, so you are really in to implementation defined behavior of the compiler.

    With the RealView tools you can make a pointer point to a packed object - which will generate either unaligned accesses or byte accesses depending on the CPU you have chosen and the presence of the --[no-]unaligned flag:

    __packed int *pMyInt;

    There might be an equivalent for the IAR tools - but it varies from tool to tool ...


    You see, the problem with this solution is that we were not using any pointers.. we were using '&'s and typecasts.. In the end, we had to go about it the hard way.. replacing everything with memcopy's  :)
  • Note: This was originally posted on 1st June 2009 at http://forums.arm.com

    A C compiler will always generally assume that integers are aligned - so there is normally no "quick" solution to this problem. Casting an integer to an unaligned memory address is not strictly valid C, so you are really in to implementation defined behavior of the compiler.

    With the RealView tools you can make a pointer point to a packed object - which will generate either unaligned accesses or byte accesses depending on the CPU you have chosen and the presence of the --[no-]unaligned flag:

    __packed int *pMyInt;

    There might be an equivalent for the IAR tools - but it varies from tool to tool ...
  • Note: This was originally posted on 25th June 2009 at http://forums.arm.com

    we were not using any pointers.. we were using '&'s and typecasts.


    Well, &myVar generates a pointer - your code just immediately consumes it. So make it explicit via a temporary variable and you have pointers you can do fun things with. It is worth noting that the hardware needs this temporary register, so number of instructions won't typically go up.

    Using your first example,

    __packed unsigned int* pA;
    unsigned int a
    char b[100];

    /* generate explicit unaligned pointer */
    pA = (__packed unsigned int *) &b[5];

    /* load from it. */
    a = *pA

    /* This may also work - but binanry will be same size anyway =) */
    a = *( ( __packed unsigned int *) &b[5] );