diff --git a/cpu/sam0_common/include/cpu_conf.h b/cpu/sam0_common/include/cpu_conf.h index a4b513e51f47..dd697e8e37b4 100644 --- a/cpu/sam0_common/include/cpu_conf.h +++ b/cpu/sam0_common/include/cpu_conf.h @@ -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 diff --git a/cpu/sam0_common/include/vendor/README.md b/cpu/sam0_common/include/vendor/README.md index d72bced2a800..f6226ed5359d 100644 --- a/cpu/sam0_common/include/vendor/README.md +++ b/cpu/sam0_common/include/vendor/README.md @@ -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 `` + +Both tinyDTLS as well as `` 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 diff --git a/cpu/sam0_common/include/vendor/fix_cxx_compat.sh b/cpu/sam0_common/include/vendor/fix_cxx_compat.sh deleted file mode 100755 index 686d55e424f7..000000000000 --- a/cpu/sam0_common/include/vendor/fix_cxx_compat.sh +++ /dev/null @@ -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 diff --git a/cpu/sam0_common/include/vendor/fix_headers.sh b/cpu/sam0_common/include/vendor/fix_headers.sh new file mode 100755 index 000000000000..c27fc41e97ac --- /dev/null +++ b/cpu/sam0_common/include/vendor/fix_headers.sh @@ -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 +# 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 diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21e16a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21e16a.h index 479115dceddc..d6d956cf1d24 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21e16a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21e16a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21e17a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21e17a.h index 2747d1e0ee22..4b6240841138 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21e17a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21e17a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21e18a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21e18a.h index 3f7af6382be5..e341cbd7dbe6 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21e18a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21e18a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21e19a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21e19a.h index 29e221d6a3e4..a23da83ec518 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21e19a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21e19a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21g16a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21g16a.h index 4cb91a8f1130..d059a3a019b5 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21g16a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21g16a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21g17a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21g17a.h index 5532a679df69..b28d578a58bc 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21g17a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21g17a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr21/include/samr21g18a.h b/cpu/sam0_common/include/vendor/samr21/include/samr21g18a.h index 0976f3520288..28eb56893ca3 100644 --- a/cpu/sam0_common/include/vendor/samr21/include/samr21g18a.h +++ b/cpu/sam0_common/include/vendor/samr21/include/samr21g18a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr30/include/samr30e18a.h b/cpu/sam0_common/include/vendor/samr30/include/samr30e18a.h index ae46f365f4b1..8a549d23a8bf 100644 --- a/cpu/sam0_common/include/vendor/samr30/include/samr30e18a.h +++ b/cpu/sam0_common/include/vendor/samr30/include/samr30e18a.h @@ -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 */ diff --git a/cpu/sam0_common/include/vendor/samr30/include/samr30g18a.h b/cpu/sam0_common/include/vendor/samr30/include/samr30g18a.h index 8752c20cb09a..7a3c20100e04 100644 --- a/cpu/sam0_common/include/vendor/samr30/include/samr30g18a.h +++ b/cpu/sam0_common/include/vendor/samr30/include/samr30g18a.h @@ -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 */ diff --git a/pkg/esp8266_sdk/patches/0002-components-lwip-port-esp8266-use-endian.h.patch b/pkg/esp8266_sdk/patches/0002-components-lwip-port-esp8266-use-endian.h.patch new file mode 100644 index 000000000000..20b3b005abd7 --- /dev/null +++ b/pkg/esp8266_sdk/patches/0002-components-lwip-port-esp8266-use-endian.h.patch @@ -0,0 +1,30 @@ +From 64a9b435bcc38a11568854f31845e58f11a0001e Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Thu, 1 Feb 2024 18:22:27 +0100 +Subject: [PATCH] components/lwip/port/esp8266: use + +Now that there is an ``, it can be used :) +--- + components/lwip/port/esp8266/include/arch/cc.h | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/components/lwip/port/esp8266/include/arch/cc.h b/components/lwip/port/esp8266/include/arch/cc.h +index c815a67..1648fc0 100644 +--- a/components/lwip/port/esp8266/include/arch/cc.h ++++ b/components/lwip/port/esp8266/include/arch/cc.h +@@ -38,11 +38,7 @@ + + #define LWIP_ERRNO_INCLUDE "sys/errno.h" + +-#if (1) +-#define BYTE_ORDER LITTLE_ENDIAN +-#else +-#define BYTE_ORDER BIG_ENDIAN +-#endif ++#include + + typedef int sys_prot_t; + +-- +2.43.0 + diff --git a/pkg/tinydtls/patches/0002-platform-specific-riot_boards.h-fix-conflict-with-en.patch b/pkg/tinydtls/patches/0002-platform-specific-riot_boards.h-fix-conflict-with-en.patch new file mode 100644 index 000000000000..7d66d227cd5e --- /dev/null +++ b/pkg/tinydtls/patches/0002-platform-specific-riot_boards.h-fix-conflict-with-en.patch @@ -0,0 +1,44 @@ +From 9b62250bf6561aed372429eb551bd75f8f5fde16 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Wed, 31 Jan 2024 17:58:13 +0100 +Subject: [PATCH] platform-specific/riot_boards.h: fix conflict with endian.h + +--- + platform-specific/riot_boards.h | 23 ----------------------- + 1 file changed, 23 deletions(-) + +diff --git a/platform-specific/riot_boards.h b/platform-specific/riot_boards.h +index f18e5ae..d7680d5 100644 +--- a/platform-specific/riot_boards.h ++++ b/platform-specific/riot_boards.h +@@ -126,27 +126,4 @@ + /* RIOT "supports" memset()/memcpy() BUT not bzero()/mcopy(). */ + #define SHA2_USE_MEMSET_MEMCPY 1 + +- +-/* +- * NOTE Gcc is who define if we are big endian or little endian. +- * Because RIOT has __BYTE_ORDER__ and BYTE_ORDER it is not clear which one +- * should take preference here. Or, if the #define inside of sha2/sha2.h +- * should be removed at all. +- */ +-#ifndef BIG_ENDIAN +-#if !defined(__BIG_ENDIAN__) +-# define BIG_ENDIAN 4321 +-# else +-# define BIG_ENDIAN __BIG_ENDIAN__ +-# endif +-#endif +- +-#ifndef LITTLE_ENDIAN +-#if !defined(__LITTLE_ENDIAN__) +-# define LITTLE_ENDIAN 1234 +-# else +-# define LITTLE_ENDIAN __LITTLE_ENDIAN__ +-# endif +-#endif +- + #endif /* _RIOT_BOARDS_H_ */ +-- +2.43.0 + diff --git a/sys/include/byteorder.h b/sys/include/byteorder.h index 6cebdae9c376..af5e74f183dd 100644 --- a/sys/include/byteorder.h +++ b/sys/include/byteorder.h @@ -21,6 +21,7 @@ #include #include +#include #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 diff --git a/sys/libc/include/endian.h b/sys/include/endian.h similarity index 67% rename from sys/libc/include/endian.h rename to sys/include/endian.h index ca90d3b12807..4d0b4bb50b25 100644 --- a/sys/libc/include/endian.h +++ b/sys/include/endian.h @@ -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 diff --git a/tests/unittests/tests-libc/tests-libc.c b/tests/unittests/tests-libc/tests-libc.c index 82796c312c28..9fa8f10c2008 100644 --- a/tests/unittests/tests-libc/tests-libc.c +++ b/tests/unittests/tests-libc/tests-libc.c @@ -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); } /** @} */