N
Noob
[ NB: cross-posted to comp.lang.c and comp.arch.embedded ]
Hello everyone,
I'm having trouble understanding some endianness-related macros
provided on my platform.
<quote>
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) << 8 ) | \
(((Value) & 0x000000FF) << 24)); \
}
#else /* big endian CPU */
#define FOOBA_WriteRegMem32BE(Address_p, Value) \
{ \
*((FOOBA_MU32 *) (Address_p)) = (U32) (Value); \
}
#endif /* _BIG_NOT_LITTLE */
#else /* not optimized */
#define FOOBA_WriteRegMem32BE(Address_p, Value) \
{ \
*(((FOOBA_MU8 *) (Address_p)) ) = (U8) ((Value) >> 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 ) | \
(((Value) & 0x000000FF) << 24)); \
}
#endif /* _BIG_NOT_LITTLE */
#else /* not optimized */
#define FOOBA_WriteRegMem32LE(Address_p, Value) \
{ \
*(((FOOBA_MU8 *) (Address_p)) ) = (U8) ((Value) ); \
*(((FOOBA_MU8 *) (Address_p)) + 1) = (U8) ((Value) >> 8 ); \
*(((FOOBA_MU8 *) (Address_p)) + 2) = (U8) ((Value) >> 16); \
*(((FOOBA_MU8 *) (Address_p)) + 3) = (U8) ((Value) >> 24); \
}
#endif /* _NO_OPTIMIZATION */
</quote>
(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.
Hello everyone,
I'm having trouble understanding some endianness-related macros
provided on my platform.
<quote>
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) << 8 ) | \
(((Value) & 0x000000FF) << 24)); \
}
#else /* big endian CPU */
#define FOOBA_WriteRegMem32BE(Address_p, Value) \
{ \
*((FOOBA_MU32 *) (Address_p)) = (U32) (Value); \
}
#endif /* _BIG_NOT_LITTLE */
#else /* not optimized */
#define FOOBA_WriteRegMem32BE(Address_p, Value) \
{ \
*(((FOOBA_MU8 *) (Address_p)) ) = (U8) ((Value) >> 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 ) | \
(((Value) & 0x000000FF) << 24)); \
}
#endif /* _BIG_NOT_LITTLE */
#else /* not optimized */
#define FOOBA_WriteRegMem32LE(Address_p, Value) \
{ \
*(((FOOBA_MU8 *) (Address_p)) ) = (U8) ((Value) ); \
*(((FOOBA_MU8 *) (Address_p)) + 1) = (U8) ((Value) >> 8 ); \
*(((FOOBA_MU8 *) (Address_p)) + 2) = (U8) ((Value) >> 16); \
*(((FOOBA_MU8 *) (Address_p)) + 3) = (U8) ((Value) >> 24); \
}
#endif /* _NO_OPTIMIZATION */
</quote>
(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.