Hello everyone,
I'm having trouble understanding some endianness-related macros provided on my platform.
typedef volatile U32 FOOBA_MU32; typedef volatile U16 FOOBA_MU16; typedef volatile U8 FOOBA_MU8;
/* ------------------------------------------------------- */ /* void FOOBA_WriteRegMem32BE(void *Address_p, U32 Value); */ /* ------------------------------------------------------- */ #ifndef FOOBA_MEMORY_ACCESS_NO_OPTIMIZATION /* optimized */ #ifndef FOOBA_MEMORY_ACCESS_BIG_NOT_LITTLE /* little endian CPU */ #define FOOBA_WriteRegMem32BE(Address_p, Value) \ { \ *((FOOBA_MU32 *) (Address_p)) = (U32) ((((Value) & 0xFF000000) >> 24) | \ (((Value) & 0x00FF0000) >> 8 ) | \ (((Value) & 0x0000FF00) 24); \ *(((FOOBA_MU8 *) (Address_p)) + 1) = (U8) ((Value) >> 16); \ *(((FOOBA_MU8 *) (Address_p)) + 2) = (U8) ((Value) >> 8 ); \ *(((FOOBA_MU8 *) (Address_p)) + 3) = (U8) ((Value) ); \ } #endif /* _NO_OPTIMIZATION */
/* ------------------------------------------------------- */ /* void FOOBA_WriteRegMem32LE(void *Address_p, U32 Value); */ /* ------------------------------------------------------- */ #ifndef FOOBA_MEMORY_ACCESS_NO_OPTIMIZATION /* optimized */ #ifndef FOOBA_MEMORY_ACCESS_BIG_NOT_LITTLE /* little endian CPU */ #define FOOBA_WriteRegMem32LE(Address_p, Value) \ { \ *((FOOBA_MU32 *) (Address_p)) = (U32) (Value); \ } #else /* big endian CPU */ #define FOOBA_WriteRegMem32LE(Address_p, Value) \ { \ *((FOOBA_MU32 *) (Address_p)) = (U32) ((((Value) & 0xFF000000) >> 24) | \ (((Value) & 0x00FF0000) >> 8 ) | \ (((Value) & 0x0000FF00) 8 ); \ *(((FOOBA_MU8 *) (Address_p)) + 2) = (U8) ((Value) >> 16); \ *(((FOOBA_MU8 *) (Address_p)) + 3) = (U8) ((Value) >> 24); \ } #endif /* _NO_OPTIMIZATION */
(As far as I understand, registers are memory-mapped, but this should not matter (or does it?) for this discussion.)
Suppose I want to write the *value* 259 to address "addr"
259(base 10) = 0x00000103(base 16)I shouldn't have to care whether the data is stored least-significant octet first or most-significant octet first, right?
I'd just write:
FOOBA_WriteRegMem32(addr, 259);
As far as I understand, endianness only matters when considering a number's representation, not when considering a number's value?
Whether a system is big-endian, little-endian, or weird-endian, value & 0xff gives the number's least-significant octet, right?
So, in my case, should I write FOOBA_WriteRegMem32LE(addr, 259); or FOOBA_WriteRegMem32BE(addr, 259); ??
And if I change to a different platform, do I have to change all my calls? (That would not make sense, I must've missed something.)
...
I've been discussing this issue with a colleague, and he suggested that perhaps many differing components' registers may be mapped in the address space, some big-endian, other little-endian, thus the programmer must know what kind of register he is accessing. Would that be a plausible explanation?
Regards.