ARM Data Alignment (Compact 2013)

3/26/2014

This topic provides information to assist you if you encounter data alignment errors when you port your ARM code to run on Windows Embedded Compact 2013.

Hardware can handle unaligned access of cached memory. However, by default, the Visual Studio compiler assumes that unaligned access will be resolved by hardware, so the compiler may generate code that uses inappropriate alignment to access uncached data.

You generally will not encounter this problem because the /QRunaligned- flag is set when you compile your OS. This flag causes the compiler to generate code to handle unaligned memory access. The implementation of memcpy and memmove has also been modified to handle unaligned access.

Even with these precautions, you may still encounter a data alignment error. Consider the situation where you accept an unaligned pointer to uncached memory. The following example shows an instance of a structure that contains an unaligned member and is allocated in uncached memory. The structure is passed to a function that dereferences an unaligned field.

Important

For readability, the code examples in this topic do not contain security checking or error handling. Do not use the following code in a production environment.

struct aStruct {
    char c; // c is aligned
    __packed int i; // i is unaligned
};

void MyFunction(aStruct *p) {
    int x = p->i; // generates an alignment fault because i is unaligned
}

In this example, the CPU generates an alignment fault if one of the following situations has occurred, even if the CPU is configured to enable unaligned access:

  • p is uncached and i is not aligned on a four-byte boundary.
  • The memory management unit (MMU) is not activated. When the MMU is disabled, all memory access is treated as uncached.

Boot loader startup code, which runs before kernel startup code has enabled the MMU, is a special case where you must be very careful with alignment. This is because the new compiler emits code that assumes the hardware is set to handle unaligned access. Because some drivers that you utilize during the boot loader phase can also access unaligned data, such as a packed data structure, boot loader initialization code should enable unaligned support. Enable unaligned support by clearing the A bit, bit 1, of CP15 register 1, and setting the U bit, bit 22, of CP15 register 1.

Uncached memory normally falls within the address range 0xA0000000 - 0xBFFFFFFF. Memory address ranges declared in other tables, such as OEMDeviceTable, are uncached. Cached memory normally falls within the address range 0x80000000 - 0x9FFFFFFF. All address ranges declared in OEMAddressTable are cached.

Tip

Cached memory within the kernel area normally falls within the virtual address range 0x80000000-0xA0000000. Uncached memory normally falls within the virtual address range 0xA0000000-0xC0000000. All virtual address ranges declared in OEMAddressTable are cached.

For more information about accessing unaligned data on ARM, see either of the following articles on the ARM Information Center website:

Unaligned data access in C and C++ code

How does the ARM Compiler support unaligned accesses?

See Also

Concepts

Port an ARM BSP to Compact 2013