The ARM Cortex-M33 is a little endian processor. This means that in memory, it stores the least significant byte of a multi-byte value in the lowest byte address and the most significant byte in the highest byte address. So for a 32-bit integer like 0x12345678, it would be stored in memory as 0x78563412.
Understanding Endianness
Endianness refers to how a processor orders the bytes that make up a multi-byte value like a 16-bit integer or 32-bit float in memory. There are two types:
- Little endian – The least significant byte is stored at the lowest address. For a 32-bit integer, the bytes would be ordered 4-3-2-1.
- Big endian – The most significant byte is stored at the lowest address. For a 32-bit integer, the bytes would be ordered 1-2-3-4.
For example, let’s say we have the 32-bit hexadecimal value 0x12345678. In little endian, this would be stored as: Address Contents 0x100 0x78 0x101 0x56 0x102 0x34 0x103 0x12
In big endian, it would be: Address Contents 0x100 0x12 0x101 0x34 0x102 0x56 0x103 0x78
When a value spans multiple bytes, endianness defines in which order those bytes are stored in memory. This affects how data is represented at the byte level and needs to be accounted for when transmitting data between systems with different endianness.
Endianness in ARM Cortex-M33
The ARM Cortex-M33 uses little endian byte ordering. This applies to all data types that span multiple bytes such as 16-bit halfwords, 32-bit words, and 64-bit doublewords.
For example, loading a 32-bit integer value like 0x12345678 from memory on a Cortex-M33 will result in the register containing 0x78563412. Storing that register value back to memory will store the bytes in little endian order.
When interfacing with big endian systems, the Cortex-M33 CPU will need to swap the byte order of values to convert between little and big endian. This is usually handled automatically by device drivers, but can require special handling in some cases.
Why ARM uses Little Endian
One reason ARM adopted little endian byte ordering is efficiency. In little endian, the least significant bytes that are most often accessed and manipulated tend to be stored in the lower byte addresses. Since most system architectures fetch data from lower addresses first, this improves performance for common operations.
Many 32-bit microcontrollers and embedded systems also use little endian because the x86 architecture that dominates PCs and servers uses little endian. Keeping the same byte ordering simplifies interfacing and data exchange between the two platforms.
However, there are also advantages to big endian byte ordering. It matches the logical ordering of data, from most significant to least significant. Big endian is common in networking protocols and file formats. Overall there are reasonable uses for both approaches.
Checking Endianness in Cortex-M33
There are a few ways to check the endianness of the Cortex-M33 in code:
- Look at the bytes of a 32-bit integer in memory – they will be ordered 4-3-2-1 in little endian.
- Use a union to overlay a 32-bit int over a byte array and inspect the ordering.
- Print the bytes of a known value and check if they match little endian order.
- Compare a known big endian value against its byte swapped little endian version.
Here is an example using a union in C to check endianness on the Cortex-M33: #include <stdint.h> typedef union { uint32_t i; uint8_t c[4]; } endian_t; int main(void) { endian_t x; x.i = 0x12345678; if (x.c[0] == 0x12 && x.c[1] == 0x34 && x.c[2] == 0x56 && x.c[3] == 0x78) { // Big endian } else if (x.c[0] == 0x78 && x.c[1] == 0x56 && x.c[2] == 0x34 && x.c[3] == 0x12) { // Little endian } return 0; }
This overlays a 32-bit integer over a byte array in a union, allowing inspection of the actual byte order. Since the Cortex-M33 is little endian, it will match the second case.
Using Endianness Correctly
Here are some guidelines for working with endianness on the Cortex-M33 and other little endian ARM processors:
- WhenExamining byte arrays manually, remember they will be ordered 4-3-2-1 for 32-bit values.
- Use higher level functions like htons(), htonl(), ntohs(), ntohl() when converting between host and network byte order for socket programming.
- Use hardware modules or byte swapping functions to convert between little and big endian values for external interfaces.
- Keep endianness in mind when transmitting binary data over a network or serial connection.
- Document the endianness used in file formats and external data interfaces.
- Use compiler intrinsics like __rev() to reverse byte order when needed.
Understanding endianness helps ensure data is ordered correctly when interacting with external big endian systems. With some care, the Cortex-M33’s little endian approach can be leveraged efficiently while still conforming to standards that utilize big endian.
Conclusion
The ARM Cortex-M33 uses little endian byte ordering to store multi-byte data types in memory. This means the least significant bytes will be at lower addresses. Knowing the processor’s endianness allows correctly interpreting and manipulating data at the byte level. Simple checks can verify the expected little endian format. When interfacing with other systems, endianness must be accounted for to avoid mixed-up data. Overall the Cortex-M33’s approach matches common conventions for embedded systems and microcontrollers.