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.

Compiler/TMS570LS2124: unaligned data access

Part Number: TMS570LS2124

Tool/software: TI C/C++ Compiler

Team,

One of my customers sometimes gets data abort errors. It's due to an unaligned access via the STM instruction, even if compiler option unaligned_access=on is set. They debugged their code and created the following code snipped to reproduce the issue:

uint8_t array[42];
uint64_t dummyValue = 0x11111111FFFFFFFFu;
*(uint64_t*)&array[1]= dummyValue;

The compiler creates a STM instruction for the last line. If uint32_t instead of uint64_t is used, then no error occurs. 

How is the behavior of unaligned_access=on? Shouldn't all data accesses use unaligned instructions?

Compiler version used:  TI Compiler 5.2.9

Compiler flags:
--compile_only -mv7R4 --code_state=32 --float_support=VFPv3D16 --abi=eabi -O4 --fp_mode=strict --opt_for_speed=5 -g --symdebug:dwarf_version=3 --c99 --c++03 --diag_warning=225 --emit_warnings_as_errors --diag_wrap=off --display_error_number --sat_reassoc=off --unaligned_access=on --enum_type=packed --common=off --fp_reassoc=off --plain_char=unsigned --embedded_constants=on --wchar_t=16

Linker flags:
--opt_level=4 --opt_for_speed=5 --emit_warnings_as_errors --run_linker --reread_libs --diag_wrap=off --display_error_number --warn_sections --rom_model --be32

Thanks,
  Robert

  • Hello Robert,

    Please refer to the Cortex-R4#66 and Device#64 (rev C silicon only) in device errata:

    http://www.ti.com/lit/er/spnz222b/spnz222b.pdf

    The compiler version 5.2.9 supports a "--no_stm" option that prevents of STMxx instructions for any writes to memory. You need to be careful and enable this option only for source files that have writes to external memory.

    Please refer to the following post too:

    https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/306285/1312686?tisearch=e2e-sitesearch&keymatch=STM#1312686

  • Anonymous
    0 Anonymous in reply to QJ Wang

    Hello Robert, hello QJ Wang,

    thank you for posting the question and the reference to the old thread.

    The original post is more about how the compiler-flag unaligned_access=on works. We are using integrated RAM and silicon revision D, that's why the referred post does not really match.

    For sure, the provided code snippet might be flawed, because it casts an (uint8_t*) to (uint64_t*) which produces an unaligned acces for uint64_t. But why does this not work for uint64_t but does work for uint32_t, uint16_t and uint8_t? Is this always the case?

    For us it would be especially interesting, how this behaves for packed structs. We want to use this for de-/serializing the packed structs from/into uint8_t-buffers.

    Thanks,
    Franz

  • Hello Franz,

    Setting the compiler switch "--unaligned_access" to "ON" only informs the compiler that the target device supports unaligned memory accesses. If this switch is set to "OFF" the compiler ensures that data is aligned to its size boundary. If this switch is set to "ON", it allows generation of load and store instructions for data that falls on an unaligned boundary.

    Cortex R4/5 use ARM v7R architecture. A 64-bit (doubleword) write must be aligned to a word (32-bit) boundary as per the requirements of this architecture. A 32-bit unaligned access is allowed by default, and can also be configured to generate an exception (abort).

    See the ARM v7R Architecture Reference Manual (ARM ARM) for more details. I am also pasting the relevant information here:

    The default value of SCTLR.A is 0, hence a 32-bit unaligned write (STR) causes an "unaligned access" to go through without generating an alignment fault exception.

    A 64-bit write using an STRD instruction, or a Store Multiple (STM) instruction always must be word-aligned.

    Regards, Sunil

  • Anonymous
    0 Anonymous in reply to Sunil Oak

    Hi Sunil,

    thank you for your reply. I think I understood the basics now. For us it is important to understand how to write C/C++ code in order to avoid any alignment problems. There are 3 use cases I see:

    1) Basic Casts
    Is a pointer-cast to a data type smaller or equal the size of a word always safe, because the compiler uses assembler instructions that support unaligned access per default? (Scenario originally posted by Robert.)

    2) Packed Structs
    Is the usage of packed structs always safe because the compiler knows that access might be unaligned?

    struct __attribute__((__packed__)) MyStruct_t
    {
      uint8_t  dummy1;
      uint32_t dummy2;
    };
    
    uint8_t array[42];
    MyStruct_t* pMyStruct = reinterpret_cast<MyStruct_t*>(&array[1]);
    MyStruct_t aMyStructCopy = *pMyStruct; // Works here, but fails with un-packed struct

    3) Memcpy
    In addition, I need to understand whether the usage of memcpy is always safe regarding unaligned access. I think I have seen that memcpy uses the addresses to decide if aligned or unaligned access is required. Is this correct?

    x) Packed Pointers
    And just out of curiosity: Does the TI Compiler (5.2.9) support packed pointers like the Keil ARM Compiler does http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230476.htm?

    Regards,
    Franz

  • Franz,

    I will have to seek comments from the compiler support team for these questions. Stay tuned.

    Regards, Sunil

  • For some general background, please see this forum thread, and this article from ARM.  

    Franz Schauer said:
    Is a pointer-cast to a data type smaller or equal the size of a word always safe, because the compiler uses assembler instructions that support unaligned access per default? (Scenario originally posted by Robert.)

    Per a strict interpretation of the standard, no.  The standard says (loosely speaking) that all casts of pointers are bad, except a cast to a char pointer.  As a practical matter ... I cannot think of a situation where a cast like this would cause problems.

    Franz Schauer said:
    Is the usage of packed structs always safe because the compiler knows that access might be unaligned?

    Yes

    Franz Schauer said:
    In addition, I need to understand whether the usage of memcpy is always safe regarding unaligned access. I think I have seen that memcpy uses the addresses to decide if aligned or unaligned access is required. Is this correct?

    The interface to memcpy says nothing about the alignment of the input pointers.  The implementation of memcpy takes this constraint into account.

    Franz Schauer said:
    Does the TI Compiler (5.2.9) support packed pointers like the Keil ARM Compiler does

    No

    Thanks and regards,

    -George 

  • Anonymous
    0 Anonymous in reply to George Mock

    Hi Sunil, George,

    thank you for the clear answers!

    Regards,
    Franz