mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #20313 from maribu/sys/byteorder/cleanup-implementation
sys/byteorder: clean up implementation
This commit is contained in:
commit
3b3da09ec6
@ -23,12 +23,6 @@
|
||||
|
||||
#include "cpu_conf_common.h"
|
||||
|
||||
/* Workaround redefinition of LITTLE_ENDIAN macro (part1) */
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#define __TMP_LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#undef LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined(CPU_SAMD10)
|
||||
#include "vendor/samd10/include/samd10.h"
|
||||
#elif defined(CPU_SAMD20)
|
||||
@ -63,15 +57,6 @@
|
||||
#include "vendor/samr34/include/samr34.h"
|
||||
#endif
|
||||
|
||||
/* Workaround redefinition of LITTLE_ENDIAN macro (part2) */
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#undef LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef __TMP_LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN __TMP_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
10
cpu/sam0_common/include/vendor/README.md
vendored
10
cpu/sam0_common/include/vendor/README.md
vendored
@ -40,10 +40,18 @@ changes will be lost when a new ASF release is going to be used.
|
||||
|
||||
Many of the header files where generated with an outdated version of SVDConv
|
||||
that adds the `__I` qualifier to anonymous bit fields, which `clang++` won't
|
||||
compile. Run the script `fix_cxx_compat.sh` in this directory whenever you
|
||||
compile. Run the script `fix_headers.sh` in this directory whenever you
|
||||
add or update vendor header filers until Microchips starts using a fixed version
|
||||
of SVDConv.
|
||||
|
||||
### compatibility with tinyDTLS and `<endian.h>`
|
||||
|
||||
Both tinyDTLS as well as `<endian.h>` expect `LITTLE_ENDIAN` to be a magic
|
||||
number to compare the byte order (as provided by the compiler) against. The
|
||||
vendor header files provide the macro with the wrong magic number without
|
||||
ever using this macro. We can just strip using the `fix_headers.sh` script
|
||||
in this directory.
|
||||
|
||||
### sam0.h
|
||||
|
||||
A SAM based CPU should include `sam0.h` in this directory, which will
|
||||
|
10
cpu/sam0_common/include/vendor/fix_cxx_compat.sh
vendored
10
cpu/sam0_common/include/vendor/fix_cxx_compat.sh
vendored
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script removes type qualifiers from anonymous padding fields in bit
|
||||
# fields for compatibility with clang++.
|
||||
|
||||
offenders="$(grep -Erl '__I [u]*int[0-9]*_t[ \t]*:[0-9]*;')"
|
||||
|
||||
for file in $offenders; do
|
||||
sed -i "$file" -e 's/__I \([u]*int[0-9]*_t[\t ]*:[0-9]*;\)/\1 /g'
|
||||
done
|
29
cpu/sam0_common/include/vendor/fix_headers.sh
vendored
Executable file
29
cpu/sam0_common/include/vendor/fix_headers.sh
vendored
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This function removes type qualifiers from anonymous padding fields in bit
|
||||
# fields for compatibility with clang++.
|
||||
strip_type_qualifiers_from_bit_fields() {
|
||||
echo "Searching for header files with bogus type qualifiers"
|
||||
offenders="$(grep -Erl '__I [u]*int[0-9]*_t[ \t]*:[0-9]*;')"
|
||||
|
||||
for file in $offenders; do
|
||||
echo "Sanitizing $file for type qualifiers in padding"
|
||||
sed -i "$file" -e 's/__I \([u]*int[0-9]*_t[\t ]*:[0-9]*;\)/\1 /g'
|
||||
done
|
||||
}
|
||||
|
||||
# This functions removes a bogus `LITTLE_ENDIAN` define which conflicts with
|
||||
# <endian.h> and tinyDTLS notion of it. Luckily, that define is not used
|
||||
# anywhere in the vendor header files, so we can just drop it.
|
||||
remove_bogus_endian_define() {
|
||||
echo "Searching for header files with bogus LITTLE_ENDIAN define"
|
||||
offenders="$(grep -rl '^#define LITTLE_ENDIAN')"
|
||||
|
||||
for file in $offenders; do
|
||||
echo "Removing bogus LITTLE_ENDIAN define from $file"
|
||||
sed -i "$file" -e '/^#define LITTLE_ENDIAN/d'
|
||||
done
|
||||
}
|
||||
|
||||
strip_type_qualifiers_from_bit_fields
|
||||
remove_bogus_endian_define
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -216,7 +216,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -234,7 +234,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
@ -234,7 +234,6 @@ void PTC_Handler ( void );
|
||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||
*/
|
||||
|
||||
#define LITTLE_ENDIAN 1
|
||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||
|
Binary file not shown.
Binary file not shown.
@ -21,6 +21,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include "unaligned.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -388,13 +389,6 @@ static inline uint64_t ntohll(uint64_t v);
|
||||
|
||||
/* **************************** IMPLEMENTATION ***************************** */
|
||||
|
||||
#ifdef HAVE_NO_BUILTIN_BSWAP16
|
||||
static inline unsigned short __builtin_bswap16(unsigned short a)
|
||||
{
|
||||
return (a << 8) | (a >> 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint16_t byteorder_swaps(uint16_t v)
|
||||
{
|
||||
return __builtin_bswap16(v);
|
||||
@ -410,30 +404,19 @@ static inline uint64_t byteorder_swapll(uint64_t v)
|
||||
return __builtin_bswap64(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swaps the byteorder according to the endianness (host -> le)
|
||||
*/
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define _byteorder_swap_le(V, T) (V)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define _byteorder_swap_le(V, T) (byteorder_swap ## T((V)))
|
||||
#else
|
||||
# error "Byte order is neither little nor big!"
|
||||
#endif
|
||||
|
||||
static inline uint16_t byteorder_ltohs(le_uint16_t v)
|
||||
{
|
||||
return _byteorder_swap_le(v.u16, s);
|
||||
return le16toh(v.u16);
|
||||
}
|
||||
|
||||
static inline uint32_t byteorder_ltohl(le_uint32_t v)
|
||||
{
|
||||
return _byteorder_swap_le(v.u32, l);
|
||||
return le32toh(v.u32);
|
||||
}
|
||||
|
||||
static inline uint64_t byteorder_ltohll(le_uint64_t v)
|
||||
{
|
||||
return _byteorder_swap_le(v.u64, ll);
|
||||
return le64toh(v.u64);
|
||||
}
|
||||
|
||||
static inline be_uint16_t byteorder_ltobs(le_uint16_t v)
|
||||
@ -480,280 +463,155 @@ static inline le_uint64_t byteorder_btolll(be_uint64_t v)
|
||||
|
||||
static inline le_uint16_t byteorder_htols(uint16_t v)
|
||||
{
|
||||
le_uint16_t result = { _byteorder_swap_le(v, s) };
|
||||
le_uint16_t result = { .u16 = htole16(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline le_uint32_t byteorder_htoll(uint32_t v)
|
||||
{
|
||||
le_uint32_t result = { _byteorder_swap_le(v, l) };
|
||||
le_uint32_t result = { .u32 = htole32(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline le_uint64_t byteorder_htolll(uint64_t v)
|
||||
{
|
||||
le_uint64_t result = { _byteorder_swap_le(v, ll) };
|
||||
le_uint64_t result = { .u64 = htole64(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Swaps the byteorder according to the endianness (host -> BE)
|
||||
*/
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define _byteorder_swap(V, T) (byteorder_swap ## T((V)))
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define _byteorder_swap(V, T) (V)
|
||||
#else
|
||||
# error "Byte order is neither little nor big!"
|
||||
#endif
|
||||
|
||||
static inline network_uint16_t byteorder_htons(uint16_t v)
|
||||
{
|
||||
network_uint16_t result = { _byteorder_swap(v, s) };
|
||||
network_uint16_t result = { .u16 = htobe16(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline network_uint32_t byteorder_htonl(uint32_t v)
|
||||
{
|
||||
network_uint32_t result = { _byteorder_swap(v, l) };
|
||||
network_uint32_t result = { .u32 = htobe32(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline network_uint64_t byteorder_htonll(uint64_t v)
|
||||
{
|
||||
network_uint64_t result = { _byteorder_swap(v, ll) };
|
||||
network_uint64_t result = { .u64 = htobe64(v) };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint16_t byteorder_ntohs(network_uint16_t v)
|
||||
{
|
||||
return _byteorder_swap(v.u16, s);
|
||||
return be16toh(v.u16);
|
||||
}
|
||||
|
||||
static inline uint32_t byteorder_ntohl(network_uint32_t v)
|
||||
{
|
||||
return _byteorder_swap(v.u32, l);
|
||||
return be32toh(v.u32);
|
||||
}
|
||||
|
||||
static inline uint64_t byteorder_ntohll(network_uint64_t v)
|
||||
{
|
||||
return _byteorder_swap(v.u64, ll);
|
||||
return be64toh(v.u64);
|
||||
}
|
||||
|
||||
static inline uint16_t htons(uint16_t v)
|
||||
{
|
||||
return byteorder_htons(v).u16;
|
||||
return htobe16(v);
|
||||
}
|
||||
|
||||
static inline uint32_t htonl(uint32_t v)
|
||||
{
|
||||
return byteorder_htonl(v).u32;
|
||||
return htobe32(v);
|
||||
}
|
||||
|
||||
static inline uint64_t htonll(uint64_t v)
|
||||
{
|
||||
return byteorder_htonll(v).u64;
|
||||
return htobe64(v);
|
||||
}
|
||||
|
||||
static inline uint16_t ntohs(uint16_t v)
|
||||
{
|
||||
network_uint16_t input = { v };
|
||||
|
||||
return byteorder_ntohs(input);
|
||||
return be16toh(v);
|
||||
}
|
||||
|
||||
static inline uint32_t ntohl(uint32_t v)
|
||||
{
|
||||
network_uint32_t input = { v };
|
||||
|
||||
return byteorder_ntohl(input);
|
||||
return be32toh(v);
|
||||
}
|
||||
|
||||
static inline uint64_t ntohll(uint64_t v)
|
||||
{
|
||||
network_uint64_t input = { v };
|
||||
|
||||
return byteorder_ntohll(input);
|
||||
return be64toh(v);
|
||||
}
|
||||
|
||||
static inline uint16_t byteorder_bebuftohs(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return (uint16_t)((buf[0] << 8) | (buf[1] << 0));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u16(buf);
|
||||
#endif
|
||||
return be16toh(unaligned_get_u16(buf));
|
||||
}
|
||||
|
||||
static inline uint32_t byteorder_bebuftohl(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return (((uint32_t) buf[0] << 24)
|
||||
| ((uint32_t) buf[1] << 16)
|
||||
| ((uint32_t) buf[2] << 8)
|
||||
| ((uint32_t) buf[3] << 0));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u32(buf);
|
||||
#endif
|
||||
return be32toh(unaligned_get_u32(buf));
|
||||
}
|
||||
|
||||
static inline uint64_t byteorder_bebuftohll(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
return (((uint64_t) buf[0] << 56)
|
||||
| ((uint64_t) buf[1] << 48)
|
||||
| ((uint64_t) buf[2] << 40)
|
||||
| ((uint64_t) buf[3] << 32)
|
||||
| ((uint64_t) buf[4] << 24)
|
||||
| ((uint64_t) buf[5] << 16)
|
||||
| ((uint64_t) buf[6] << 8)
|
||||
| ((uint64_t) buf[7] << 0));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u64(buf);
|
||||
#endif
|
||||
return be64toh(unaligned_get_u64(buf));
|
||||
}
|
||||
|
||||
static inline void byteorder_htobebufs(uint8_t *buf, uint16_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 8);
|
||||
buf[1] = (uint8_t)(val >> 0);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htobe16(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void byteorder_htobebufl(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 24);
|
||||
buf[1] = (uint8_t)(val >> 16);
|
||||
buf[2] = (uint8_t)(val >> 8);
|
||||
buf[3] = (uint8_t)(val >> 0);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htobe32(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void byteorder_htobebufll(uint8_t *buf, uint64_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 56);
|
||||
buf[1] = (uint8_t)(val >> 48);
|
||||
buf[2] = (uint8_t)(val >> 40);
|
||||
buf[3] = (uint8_t)(val >> 32);
|
||||
buf[4] = (uint8_t)(val >> 24);
|
||||
buf[5] = (uint8_t)(val >> 16);
|
||||
buf[6] = (uint8_t)(val >> 8);
|
||||
buf[7] = (uint8_t)(val >> 0);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
/* big endian to big endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htobe64(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint16_t byteorder_lebuftohs(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u16(buf);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
return (uint16_t)((buf[0] << 8) | (buf[1] << 0));
|
||||
#endif
|
||||
return le16toh(unaligned_get_u16(buf));
|
||||
}
|
||||
|
||||
static inline uint32_t byteorder_lebuftohl(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u32(buf);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
return (((uint32_t) buf[0] << 24)
|
||||
| ((uint32_t) buf[1] << 16)
|
||||
| ((uint32_t) buf[2] << 8)
|
||||
| ((uint32_t) buf[3] << 0));
|
||||
#endif
|
||||
return le32toh(unaligned_get_u32(buf));
|
||||
}
|
||||
|
||||
static inline uint64_t byteorder_lebuftohll(const uint8_t *buf)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
return unaligned_get_u64(buf);
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
return (((uint64_t) buf[0] << 56)
|
||||
| ((uint64_t) buf[1] << 48)
|
||||
| ((uint64_t) buf[2] << 40)
|
||||
| ((uint64_t) buf[3] << 32)
|
||||
| ((uint64_t) buf[4] << 24)
|
||||
| ((uint64_t) buf[5] << 16)
|
||||
| ((uint64_t) buf[6] << 8)
|
||||
| ((uint64_t) buf[7] << 0));
|
||||
#endif
|
||||
return le64toh(unaligned_get_u64(buf));
|
||||
}
|
||||
|
||||
static inline void byteorder_htolebufs(uint8_t *buf, uint16_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htole16(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 8);
|
||||
buf[1] = (uint8_t)(val >> 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void byteorder_htolebufl(uint8_t *buf, uint32_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htole32(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 24);
|
||||
buf[1] = (uint8_t)(val >> 16);
|
||||
buf[2] = (uint8_t)(val >> 8);
|
||||
buf[3] = (uint8_t)(val >> 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void byteorder_htolebufll(uint8_t *buf, uint64_t val)
|
||||
{
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
/* little endian to little endian conversion is easy, but buffer might be
|
||||
* unaligned */
|
||||
val = htole64(val);
|
||||
memcpy(buf, &val, sizeof(val));
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
buf[0] = (uint8_t)(val >> 56);
|
||||
buf[1] = (uint8_t)(val >> 48);
|
||||
buf[2] = (uint8_t)(val >> 40);
|
||||
buf[3] = (uint8_t)(val >> 32);
|
||||
buf[4] = (uint8_t)(val >> 24);
|
||||
buf[5] = (uint8_t)(val >> 16);
|
||||
buf[6] = (uint8_t)(val >> 8);
|
||||
buf[7] = (uint8_t)(val >> 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -7,10 +7,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup posix
|
||||
* @defgroup sys_endian endian conversions as provided by most libcs
|
||||
* @ingroup sys
|
||||
*
|
||||
* This module provides architecture-independent access to architecture details.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @file
|
||||
* @brief libc header for endian conversion
|
||||
*
|
||||
@ -30,17 +33,17 @@ extern "C" {
|
||||
/**
|
||||
* @brief A numeric constant representing little endian byte order
|
||||
*/
|
||||
#define LITTLE_ENDIAN implementation_defined
|
||||
#define LITTLE_ENDIAN magic-number
|
||||
|
||||
/**
|
||||
* @brief A numeric constant representing big endian byte order
|
||||
*/
|
||||
#define BIG_ENDIAN implementation_defined
|
||||
#define BIG_ENDIAN magic-number
|
||||
|
||||
/**
|
||||
* @brief A numeric constant representing PDP endian byte order
|
||||
*/
|
||||
#define PDP_ENDIAN implementation_defined
|
||||
#define PDP_ENDIAN magic-number
|
||||
|
||||
/**
|
||||
* @brief The byte order of this machines indicated by the constant
|
||||
@ -69,37 +72,53 @@ uint64_t le64toh(uint64_t little_endian_64bits);/**< little endian to host, 64 b
|
||||
|
||||
#else /* DOXYGEN */
|
||||
|
||||
#define LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define BIG_ENDIAN _BIG_ENDIAN
|
||||
#define PDP_ENDIAN _PDP_ENDIAN
|
||||
#define BYTE_ORDER _BYTE_ORDER
|
||||
/* Depending on the version of newlib used, newlib may provide them indirectly
|
||||
* as well. We don't want to redefine them in this case */
|
||||
#ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
#ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN 4321
|
||||
#endif
|
||||
#ifndef PDP_ENDIAN
|
||||
# define PDP_ENDIAN 3412
|
||||
#endif
|
||||
#ifndef BYTE_ORDER
|
||||
# define BYTE_ORDER __BYTE_ORDER__
|
||||
#endif
|
||||
|
||||
/* But to avoid lots of pain in the ass: Let's at least make sure everyone
|
||||
* agrees on what magic number is what */
|
||||
#if (LITTLE_ENDIAN != 1234) || (BIG_ENDIAN != 4321) || (PDP_ENDIAN != 3412)
|
||||
# error "Mismatching magic numbers to refer to endianness"
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define htobe16(_x) __builtin_bswap16(_x)
|
||||
# define htole16(_x) ((__uint16_t)(_x))
|
||||
# define htole16(_x) ((uint16_t)(_x))
|
||||
# define be16toh(_x) __builtin_bswap16(_x)
|
||||
# define le16toh(_x) ((__uint16_t)(_x))
|
||||
# define le16toh(_x) ((uint16_t)(_x))
|
||||
# define htobe32(_x) __builtin_bswap32(_x)
|
||||
# define htole32(_x) ((__uint32_t)(_x))
|
||||
# define htole32(_x) ((uint32_t)(_x))
|
||||
# define be32toh(_x) __builtin_bswap32(_x)
|
||||
# define le32toh(_x) ((__uint32_t)(_x))
|
||||
# define le32toh(_x) ((uint32_t)(_x))
|
||||
# define htobe64(_x) __builtin_bswap64(_x)
|
||||
# define htole64(_x) ((__uint64_t)(_x))
|
||||
# define htole64(_x) ((uint64_t)(_x))
|
||||
# define be64toh(_x) __builtin_bswap64(_x)
|
||||
# define le64toh(_x) ((__uint64_t)(_x))
|
||||
# define le64toh(_x) ((uint64_t)(_x))
|
||||
#elif BYTE_ORDER == BIG_ENDIAN
|
||||
# define htole16(_x) __builtin_bswap16(_x)
|
||||
# define htobe16(_x) ((__uint16_t)(_x))
|
||||
# define htobe16(_x) ((uint16_t)(_x))
|
||||
# define le16toh(_x) __builtin_bswap16(_x)
|
||||
# define be16toh(_x) ((__uint16_t)(_x))
|
||||
# define be16toh(_x) ((uint16_t)(_x))
|
||||
# define htole32(_x) __builtin_bswap32(_x)
|
||||
# define htobe32(_x) ((__uint32_t)(_x))
|
||||
# define htobe32(_x) ((uint32_t)(_x))
|
||||
# define le32toh(_x) __builtin_bswap32(_x)
|
||||
# define be32toh(_x) ((__uint32_t)(_x))
|
||||
# define be32toh(_x) ((uint32_t)(_x))
|
||||
# define htole64(_x) __builtin_bswap64(_x)
|
||||
# define htobe64(_x) ((__uint64_t)(_x))
|
||||
# define htobe64(_x) ((uint64_t)(_x))
|
||||
# define le64toh(_x) __builtin_bswap64(_x)
|
||||
# define be64toh(_x) ((__uint64_t)(_x))
|
||||
# define be64toh(_x) ((uint64_t)(_x))
|
||||
#else
|
||||
# error "Byte order not supported"
|
||||
#endif
|
@ -89,6 +89,11 @@ static void test_libc_endian(void)
|
||||
TEST_ASSERT_EQUAL_INT(le32toh(u32_le.as_number), u32_host);
|
||||
TEST_ASSERT_EQUAL_INT(be64toh(u64_be.as_number), u64_host);
|
||||
TEST_ASSERT_EQUAL_INT(le64toh(u64_le.as_number), u64_host);
|
||||
|
||||
/* check that magic numbers in the constants are what is commonly expected */
|
||||
TEST_ASSERT_EQUAL_INT(LITTLE_ENDIAN, 1234);
|
||||
TEST_ASSERT_EQUAL_INT(BIG_ENDIAN, 4321);
|
||||
TEST_ASSERT_EQUAL_INT(PDP_ENDIAN, 3412);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user