LCOV - code coverage report
Current view: top level - zephyr/sys - util.h Hit Total Coverage
Test: new.info Lines: 67 67 100.0 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /*
       2             :  * Copyright (c) 2011-2014, Wind River Systems, Inc.
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : /**
       8             :  * @file
       9             :  * @brief Misc utilities
      10             :  *
      11             :  * Misc utilities usable by the kernel and application code.
      12             :  */
      13             : 
      14             : #ifndef ZEPHYR_INCLUDE_SYS_UTIL_H_
      15             : #define ZEPHYR_INCLUDE_SYS_UTIL_H_
      16             : 
      17             : #include <zephyr/sys/util_macro.h>
      18             : #include <zephyr/toolchain.h>
      19             : 
      20             : /* needs to be outside _ASMLANGUAGE so 'true' and 'false' can turn
      21             :  * into '1' and '0' for asm or linker scripts
      22             :  */
      23             : #include <stdbool.h>
      24             : 
      25             : #ifndef _ASMLANGUAGE
      26             : 
      27             : #include <zephyr/sys/__assert.h>
      28             : #include <zephyr/types.h>
      29             : #include <stddef.h>
      30             : #include <stdint.h>
      31             : 
      32             : /** @brief Number of bits that make up a type */
      33           1 : #define NUM_BITS(t) (sizeof(t) * BITS_PER_BYTE)
      34             : 
      35             : #ifdef __cplusplus
      36             : extern "C" {
      37             : #endif
      38             : 
      39             : /**
      40             :  * @defgroup sys-util Utility Functions
      41             :  * @since 2.4
      42             :  * @version 0.1.0
      43             :  * @ingroup utilities
      44             :  * @{
      45             :  */
      46             : 
      47             : /** @brief Cast @p x, a pointer, to an unsigned integer. */
      48           1 : #define POINTER_TO_UINT(x) ((uintptr_t) (x))
      49             : /** @brief Cast @p x, an unsigned integer, to a <tt>void*</tt>. */
      50           1 : #define UINT_TO_POINTER(x) ((void *) (uintptr_t) (x))
      51             : /** @brief Cast @p x, a pointer, to a signed integer. */
      52           1 : #define POINTER_TO_INT(x)  ((intptr_t) (x))
      53             : /** @brief Cast @p x, a signed integer, to a <tt>void*</tt>. */
      54           1 : #define INT_TO_POINTER(x)  ((void *) (intptr_t) (x))
      55             : 
      56             : #if !(defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__) && defined(__SIZEOF_LONG_LONG__))
      57             : #       error Missing required predefined macros for BITS_PER_LONG calculation
      58             : #endif
      59             : 
      60             : /** Number of bits in a byte. */
      61           1 : #define BITS_PER_BYTE (__CHAR_BIT__)
      62             : 
      63             : /** Number of bits in a nibble. */
      64           1 : #define BITS_PER_NIBBLE (__CHAR_BIT__ / 2)
      65             : 
      66             : /** Number of nibbles in a byte. */
      67           1 : #define NIBBLES_PER_BYTE (BITS_PER_BYTE / BITS_PER_NIBBLE)
      68             : 
      69             : /** Number of bits in a long int. */
      70           1 : #define BITS_PER_LONG   (__CHAR_BIT__ * __SIZEOF_LONG__)
      71             : 
      72             : /** Number of bits in a long long int. */
      73           1 : #define BITS_PER_LONG_LONG      (__CHAR_BIT__ * __SIZEOF_LONG_LONG__)
      74             : 
      75             : /**
      76             :  * @brief Create a contiguous bitmask starting at bit position @p l
      77             :  *        and ending at position @p h.
      78             :  */
      79           1 : #define GENMASK(h, l) \
      80             :         (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
      81             : 
      82             : /**
      83             :  * @brief Create a contiguous 64-bit bitmask starting at bit position @p l
      84             :  *        and ending at position @p h.
      85             :  */
      86           1 : #define GENMASK64(h, l) \
      87             :         (((~0ULL) - (1ULL << (l)) + 1) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
      88             : 
      89             : /** @brief 0 if @p cond is true-ish; causes a compile error otherwise. */
      90           1 : #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
      91             : 
      92             : #if defined(__cplusplus)
      93             : 
      94             : /* The built-in function used below for type checking in C is not
      95             :  * supported by GNU C++.
      96             :  */
      97             : #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
      98             : 
      99             : #else /* __cplusplus */
     100             : 
     101             : /**
     102             :  * @brief Zero if @p array has an array type, a compile error otherwise
     103             :  *
     104             :  * This macro is available only from C, not C++.
     105             :  */
     106           1 : #define IS_ARRAY(array) \
     107             :         ZERO_OR_COMPILE_ERROR( \
     108             :                 !__builtin_types_compatible_p(__typeof__(array), \
     109             :                                               __typeof__(&(array)[0])))
     110             : 
     111             : /**
     112             :  * @brief Number of elements in the given @p array
     113             :  *
     114             :  * In C++, due to language limitations, this will accept as @p array
     115             :  * any type that implements <tt>operator[]</tt>. The results may not be
     116             :  * particularly meaningful in this case.
     117             :  *
     118             :  * In C, passing a pointer as @p array causes a compile error.
     119             :  */
     120           1 : #define ARRAY_SIZE(array) \
     121             :         ((size_t) (IS_ARRAY(array) + (sizeof(array) / sizeof((array)[0]))))
     122             : 
     123             : #endif /* __cplusplus */
     124             : 
     125             : /**
     126             :  * @brief Declare a flexible array member.
     127             :  *
     128             :  * This macro declares a flexible array member in a struct. The member
     129             :  * is named @p name and has type @p type.
     130             :  *
     131             :  * Since C99, flexible arrays are part of the C standard, but for historical
     132             :  * reasons many places still use an older GNU extension that is declare
     133             :  * zero length arrays.
     134             :  *
     135             :  * Although zero length arrays are flexible arrays, we can't blindly
     136             :  * replace [0] with [] because of some syntax limitations. This macro
     137             :  * workaround these limitations.
     138             :  *
     139             :  * It is specially useful for cases where flexible arrays are
     140             :  * used in unions or are not the last element in the struct.
     141             :  */
     142           1 : #define FLEXIBLE_ARRAY_DECLARE(type, name) \
     143             :         struct { \
     144             :                 struct { } __unused_##name; \
     145             :                 type name[]; \
     146             :         }
     147             : 
     148             : /**
     149             :  * @brief Whether @p ptr is an element of @p array
     150             :  *
     151             :  * This macro can be seen as a slightly stricter version of @ref PART_OF_ARRAY
     152             :  * in that it also ensures that @p ptr is aligned to an array-element boundary
     153             :  * of @p array.
     154             :  *
     155             :  * In C, passing a pointer as @p array causes a compile error.
     156             :  *
     157             :  * @param array the array in question
     158             :  * @param ptr the pointer to check
     159             :  *
     160             :  * @return 1 if @p ptr is part of @p array, 0 otherwise
     161             :  */
     162           1 : #define IS_ARRAY_ELEMENT(array, ptr)                                                               \
     163             :         ((ptr) && POINTER_TO_UINT(array) <= POINTER_TO_UINT(ptr) &&                          \
     164             :          POINTER_TO_UINT(ptr) < POINTER_TO_UINT(&(array)[ARRAY_SIZE(array)]) &&                    \
     165             :          (POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) % sizeof((array)[0]) == 0)
     166             : 
     167             : /**
     168             :  * @brief Index of @p ptr within @p array
     169             :  *
     170             :  * With `CONFIG_ASSERT=y`, this macro will trigger a runtime assertion
     171             :  * when @p ptr does not fall into the range of @p array or when @p ptr
     172             :  * is not aligned to an array-element boundary of @p array.
     173             :  *
     174             :  * In C, passing a pointer as @p array causes a compile error.
     175             :  *
     176             :  * @param array the array in question
     177             :  * @param ptr pointer to an element of @p array
     178             :  *
     179             :  * @return the array index of @p ptr within @p array, on success
     180             :  */
     181           1 : #define ARRAY_INDEX(array, ptr)                                                                    \
     182             :         ({                                                                                         \
     183             :                 __ASSERT_NO_MSG(IS_ARRAY_ELEMENT(array, ptr));                                     \
     184             :                 (__typeof__((array)[0]) *)(ptr) - (array);                                         \
     185             :         })
     186             : 
     187             : /**
     188             :  * @brief Check if a pointer @p ptr lies within @p array.
     189             :  *
     190             :  * In C but not C++, this causes a compile error if @p array is not an array
     191             :  * (e.g. if @p ptr and @p array are mixed up).
     192             :  *
     193             :  * @param array an array
     194             :  * @param ptr a pointer
     195             :  * @return 1 if @p ptr is part of @p array, 0 otherwise
     196             :  */
     197           1 : #define PART_OF_ARRAY(array, ptr)                                                                  \
     198             :         ((ptr) && POINTER_TO_UINT(array) <= POINTER_TO_UINT(ptr) &&                                \
     199             :          POINTER_TO_UINT(ptr) < POINTER_TO_UINT(&(array)[ARRAY_SIZE(array)]))
     200             : 
     201             : /**
     202             :  * @brief Array-index of @p ptr within @p array, rounded down
     203             :  *
     204             :  * This macro behaves much like @ref ARRAY_INDEX with the notable
     205             :  * difference that it accepts any @p ptr in the range of @p array rather than
     206             :  * exclusively a @p ptr aligned to an array-element boundary of @p array.
     207             :  *
     208             :  * With `CONFIG_ASSERT=y`, this macro will trigger a runtime assertion
     209             :  * when @p ptr does not fall into the range of @p array.
     210             :  *
     211             :  * In C, passing a pointer as @p array causes a compile error.
     212             :  *
     213             :  * @param array the array in question
     214             :  * @param ptr pointer to an element of @p array
     215             :  *
     216             :  * @return the array index of @p ptr within @p array, on success
     217             :  */
     218           1 : #define ARRAY_INDEX_FLOOR(array, ptr)                                                              \
     219             :         ({                                                                                         \
     220             :                 __ASSERT_NO_MSG(PART_OF_ARRAY(array, ptr));                                        \
     221             :                 (POINTER_TO_UINT(ptr) - POINTER_TO_UINT(array)) / sizeof((array)[0]);              \
     222             :         })
     223             : 
     224             : /**
     225             :  * @brief Iterate over members of an array using an index variable
     226             :  *
     227             :  * @param array the array in question
     228             :  * @param idx name of array index variable
     229             :  */
     230           1 : #define ARRAY_FOR_EACH(array, idx) for (size_t idx = 0; (idx) < ARRAY_SIZE(array); ++(idx))
     231             : 
     232             : /**
     233             :  * @brief Iterate over members of an array using a pointer
     234             :  *
     235             :  * @param array the array in question
     236             :  * @param ptr pointer to an element of @p array
     237             :  */
     238           1 : #define ARRAY_FOR_EACH_PTR(array, ptr)                                                             \
     239             :         for (__typeof__(*(array)) *ptr = (array); (size_t)((ptr) - (array)) < ARRAY_SIZE(array);   \
     240             :              ++(ptr))
     241             : 
     242             : /**
     243             :  * @brief Validate if two entities have a compatible type
     244             :  *
     245             :  * @param a the first entity to be compared
     246             :  * @param b the second entity to be compared
     247             :  * @return 1 if the two elements are compatible, 0 if they are not
     248             :  */
     249           1 : #define SAME_TYPE(a, b) __builtin_types_compatible_p(__typeof__(a), __typeof__(b))
     250             : 
     251             : /**
     252             :  * @brief Validate CONTAINER_OF parameters, only applies to C mode.
     253             :  */
     254             : #ifndef __cplusplus
     255           1 : #define CONTAINER_OF_VALIDATE(ptr, type, field)               \
     256             :         BUILD_ASSERT(SAME_TYPE(*(ptr), ((type *)0)->field) || \
     257             :                      SAME_TYPE(*(ptr), void),                 \
     258             :                      "pointer type mismatch in CONTAINER_OF");
     259             : #else
     260             : #define CONTAINER_OF_VALIDATE(ptr, type, field)
     261             : #endif
     262             : 
     263             : /**
     264             :  * @brief Get a pointer to a structure containing the element
     265             :  *
     266             :  * Example:
     267             :  *
     268             :  *      struct foo {
     269             :  *              int bar;
     270             :  *      };
     271             :  *
     272             :  *      struct foo my_foo;
     273             :  *      int *ptr = &my_foo.bar;
     274             :  *
     275             :  *      struct foo *container = CONTAINER_OF(ptr, struct foo, bar);
     276             :  *
     277             :  * Above, @p container points at @p my_foo.
     278             :  *
     279             :  * @param ptr pointer to a structure element
     280             :  * @param type name of the type that @p ptr is an element of
     281             :  * @param field the name of the field within the struct @p ptr points to
     282             :  * @return a pointer to the structure that contains @p ptr
     283             :  */
     284           1 : #define CONTAINER_OF(ptr, type, field)                               \
     285             :         ({                                                           \
     286             :                 CONTAINER_OF_VALIDATE(ptr, type, field)              \
     287             :                 ((type *)(((char *)(ptr)) - offsetof(type, field))); \
     288             :         })
     289             : 
     290             : /**
     291             :  * @brief Report the size of a struct field in bytes.
     292             :  *
     293             :  * @param type The structure containing the field of interest.
     294             :  * @param member The field to return the size of.
     295             :  *
     296             :  * @return The field size.
     297             :  */
     298           1 : #define SIZEOF_FIELD(type, member) sizeof((((type *)0)->member))
     299             : 
     300             : /**
     301             :  * @brief Concatenate input arguments
     302             :  *
     303             :  * Concatenate provided tokens into a combined token during the preprocessor pass.
     304             :  * This can be used to, for ex., build an identifier out of multiple parts,
     305             :  * where one of those parts may be, for ex, a number, another macro, or a macro argument.
     306             :  *
     307             :  * @param ... Tokens to concatencate
     308             :  *
     309             :  * @return Concatenated token.
     310             :  */
     311           1 : #define CONCAT(...) \
     312             :         UTIL_CAT(_CONCAT_, NUM_VA_ARGS_LESS_1(__VA_ARGS__))(__VA_ARGS__)
     313             : 
     314             : /**
     315             :  * @brief Check if @p ptr is aligned to @p align alignment
     316             :  */
     317           1 : #define IS_ALIGNED(ptr, align) (((uintptr_t)(ptr)) % (align) == 0)
     318             : 
     319             : /**
     320             :  * @brief Value of @p x rounded up to the next multiple of @p align.
     321             :  */
     322           1 : #define ROUND_UP(x, align)                                   \
     323             :         ((((unsigned long)(x) + ((unsigned long)(align) - 1)) / \
     324             :           (unsigned long)(align)) * (unsigned long)(align))
     325             : 
     326             : /**
     327             :  * @brief Value of @p x rounded down to the previous multiple of @p align.
     328             :  */
     329           1 : #define ROUND_DOWN(x, align)                                 \
     330             :         (((unsigned long)(x) / (unsigned long)(align)) * (unsigned long)(align))
     331             : 
     332             : /** @brief Value of @p x rounded up to the next word boundary. */
     333           1 : #define WB_UP(x) ROUND_UP(x, sizeof(void *))
     334             : 
     335             : /** @brief Value of @p x rounded down to the previous word boundary. */
     336           1 : #define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
     337             : 
     338             : /**
     339             :  * @brief Divide and round up.
     340             :  *
     341             :  * Example:
     342             :  * @code{.c}
     343             :  * DIV_ROUND_UP(1, 2); // 1
     344             :  * DIV_ROUND_UP(3, 2); // 2
     345             :  * @endcode
     346             :  *
     347             :  * @param n Numerator.
     348             :  * @param d Denominator.
     349             :  *
     350             :  * @return The result of @p n / @p d, rounded up.
     351             :  */
     352           1 : #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
     353             : 
     354             : /**
     355             :  * @brief Divide and round to the nearest integer.
     356             :  *
     357             :  * Example:
     358             :  * @code{.c}
     359             :  * DIV_ROUND_CLOSEST(5, 2); // 3
     360             :  * DIV_ROUND_CLOSEST(5, -2); // -3
     361             :  * DIV_ROUND_CLOSEST(5, 3); // 2
     362             :  * @endcode
     363             :  *
     364             :  * @param n Numerator.
     365             :  * @param d Denominator.
     366             :  *
     367             :  * @return The result of @p n / @p d, rounded to the nearest integer.
     368             :  */
     369           1 : #define DIV_ROUND_CLOSEST(n, d)                                                                    \
     370             :         (((((__typeof__(n))-1) < 0) && (((__typeof__(d))-1) < 0) && ((n) < 0) ^ ((d) < 0))         \
     371             :                  ? ((n) - ((d) / 2)) / (d)                                                         \
     372             :                  : ((n) + ((d) / 2)) / (d))
     373             : 
     374             : #ifndef MAX
     375             : /**
     376             :  * @brief Obtain the maximum of two values.
     377             :  *
     378             :  * @note Arguments are evaluated twice. Use Z_MAX for a GCC-only, single
     379             :  * evaluation version
     380             :  *
     381             :  * @param a First value.
     382             :  * @param b Second value.
     383             :  *
     384             :  * @returns Maximum value of @p a and @p b.
     385             :  */
     386           1 : #define MAX(a, b) (((a) > (b)) ? (a) : (b))
     387             : #endif
     388             : 
     389             : #ifndef MIN
     390             : /**
     391             :  * @brief Obtain the minimum of two values.
     392             :  *
     393             :  * @note Arguments are evaluated twice. Use Z_MIN for a GCC-only, single
     394             :  * evaluation version
     395             :  *
     396             :  * @param a First value.
     397             :  * @param b Second value.
     398             :  *
     399             :  * @returns Minimum value of @p a and @p b.
     400             :  */
     401           1 : #define MIN(a, b) (((a) < (b)) ? (a) : (b))
     402             : #endif
     403             : 
     404             : #ifndef CLAMP
     405             : /**
     406             :  * @brief Clamp a value to a given range.
     407             :  *
     408             :  * @note Arguments are evaluated multiple times. Use Z_CLAMP for a GCC-only,
     409             :  * single evaluation version.
     410             :  *
     411             :  * @param val Value to be clamped.
     412             :  * @param low Lowest allowed value (inclusive).
     413             :  * @param high Highest allowed value (inclusive).
     414             :  *
     415             :  * @returns Clamped value.
     416             :  */
     417           1 : #define CLAMP(val, low, high) (((val) <= (low)) ? (low) : MIN(val, high))
     418             : #endif
     419             : 
     420             : /**
     421             :  * @brief Checks if a value is within range.
     422             :  *
     423             :  * @note @p val is evaluated twice.
     424             :  *
     425             :  * @param val Value to be checked.
     426             :  * @param min Lower bound (inclusive).
     427             :  * @param max Upper bound (inclusive).
     428             :  *
     429             :  * @retval true If value is within range
     430             :  * @retval false If the value is not within range
     431             :  */
     432           1 : #define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
     433             : 
     434             : /**
     435             :  * @brief Is @p x a power of two?
     436             :  * @param x value to check
     437             :  * @return true if @p x is a power of two, false otherwise
     438             :  */
     439           1 : static inline bool is_power_of_two(unsigned int x)
     440             : {
     441             :         return IS_POWER_OF_TWO(x);
     442             : }
     443             : 
     444             : /**
     445             :  * @brief Is @p p equal to ``NULL``?
     446             :  *
     447             :  * Some macros may need to check their arguments against NULL to support
     448             :  * multiple use-cases, but NULL checks can generate warnings if such a macro
     449             :  * is used in contexts where that particular argument can never be NULL.
     450             :  *
     451             :  * The warnings can be triggered if:
     452             :  * a) all macros are expanded (e.g. when using CONFIG_COMPILER_SAVE_TEMPS=y)
     453             :  * or
     454             :  * b) tracking of macro expansions are turned off (-ftrack-macro-expansion=0)
     455             :  *
     456             :  * The warnings can be circumvented by using this inline function for doing
     457             :  * the NULL check within the macro. The compiler is still able to optimize the
     458             :  * NULL check out at a later stage.
     459             :  *
     460             :  * @param p Pointer to check
     461             :  * @return true if @p p is equal to ``NULL``, false otherwise
     462             :  */
     463           1 : static ALWAYS_INLINE bool is_null_no_warn(void *p)
     464             : {
     465             :         return p == NULL;
     466             : }
     467             : 
     468             : /**
     469             :  * @brief Arithmetic shift right
     470             :  * @param value value to shift
     471             :  * @param shift number of bits to shift
     472             :  * @return @p value shifted right by @p shift; opened bit positions are
     473             :  *         filled with the sign bit
     474             :  */
     475           1 : static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift)
     476             : {
     477             :         int64_t sign_ext;
     478             : 
     479             :         if (shift == 0U) {
     480             :                 return value;
     481             :         }
     482             : 
     483             :         /* extract sign bit */
     484             :         sign_ext = (value >> 63) & 1;
     485             : 
     486             :         /* make all bits of sign_ext be the same as the value's sign bit */
     487             :         sign_ext = -sign_ext;
     488             : 
     489             :         /* shift value and fill opened bit positions with sign bit */
     490             :         return (value >> shift) | (sign_ext << (64 - shift));
     491             : }
     492             : 
     493             : /**
     494             :  * @brief byte by byte memcpy.
     495             :  *
     496             :  * Copy `size` bytes of `src` into `dest`. This is guaranteed to be done byte by byte.
     497             :  *
     498             :  * @param dst Pointer to the destination memory.
     499             :  * @param src Pointer to the source of the data.
     500             :  * @param size The number of bytes to copy.
     501             :  */
     502           1 : static inline void bytecpy(void *dst, const void *src, size_t size)
     503             : {
     504             :         size_t i;
     505             : 
     506             :         for (i = 0; i < size; ++i) {
     507             :                 ((volatile uint8_t *)dst)[i] = ((volatile const uint8_t *)src)[i];
     508             :         }
     509             : }
     510             : 
     511             : /**
     512             :  * @brief byte by byte swap.
     513             :  *
     514             :  * Swap @a size bytes between memory regions @a a and @a b. This is
     515             :  * guaranteed to be done byte by byte.
     516             :  *
     517             :  * @param a Pointer to the first memory region.
     518             :  * @param b Pointer to the second memory region.
     519             :  * @param size The number of bytes to swap.
     520             :  */
     521           1 : static inline void byteswp(void *a, void *b, size_t size)
     522             : {
     523             :         uint8_t t;
     524             :         uint8_t *aa = (uint8_t *)a;
     525             :         uint8_t *bb = (uint8_t *)b;
     526             : 
     527             :         for (; size > 0; --size) {
     528             :                 t = *aa;
     529             :                 *aa++ = *bb;
     530             :                 *bb++ = t;
     531             :         }
     532             : }
     533             : 
     534             : /**
     535             :  * @brief      Convert a single character into a hexadecimal nibble.
     536             :  *
     537             :  * @param c     The character to convert
     538             :  * @param x     The address of storage for the converted number.
     539             :  *
     540             :  *  @return Zero on success or (negative) error code otherwise.
     541             :  */
     542           1 : int char2hex(char c, uint8_t *x);
     543             : 
     544             : /**
     545             :  * @brief      Convert a single hexadecimal nibble into a character.
     546             :  *
     547             :  * @param c     The number to convert
     548             :  * @param x     The address of storage for the converted character.
     549             :  *
     550             :  *  @return Zero on success or (negative) error code otherwise.
     551             :  */
     552           1 : int hex2char(uint8_t x, char *c);
     553             : 
     554             : /**
     555             :  * @brief      Convert a binary array into string representation.
     556             :  *
     557             :  * @param buf     The binary array to convert
     558             :  * @param buflen  The length of the binary array to convert
     559             :  * @param hex     Address of where to store the string representation.
     560             :  * @param hexlen  Size of the storage area for string representation.
     561             :  *
     562             :  * @return     The length of the converted string, or 0 if an error occurred.
     563             :  */
     564           1 : size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen);
     565             : 
     566             : /**
     567             :  * @brief      Convert a hexadecimal string into a binary array.
     568             :  *
     569             :  * @param hex     The hexadecimal string to convert
     570             :  * @param hexlen  The length of the hexadecimal string to convert.
     571             :  * @param buf     Address of where to store the binary data
     572             :  * @param buflen  Size of the storage area for binary data
     573             :  *
     574             :  * @return     The length of the binary array, or 0 if an error occurred.
     575             :  */
     576           1 : size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen);
     577             : 
     578             : /**
     579             :  * @brief Convert a binary coded decimal (BCD 8421) value to binary.
     580             :  *
     581             :  * @param bcd BCD 8421 value to convert.
     582             :  *
     583             :  * @return Binary representation of input value.
     584             :  */
     585           1 : static inline uint8_t bcd2bin(uint8_t bcd)
     586             : {
     587             :         return ((10 * (bcd >> 4)) + (bcd & 0x0F));
     588             : }
     589             : 
     590             : /**
     591             :  * @brief Convert a binary value to binary coded decimal (BCD 8421).
     592             :  *
     593             :  * @param bin Binary value to convert.
     594             :  *
     595             :  * @return BCD 8421 representation of input value.
     596             :  */
     597           1 : static inline uint8_t bin2bcd(uint8_t bin)
     598             : {
     599             :         return (((bin / 10) << 4) | (bin % 10));
     600             : }
     601             : 
     602             : /**
     603             :  * @brief      Convert a uint8_t into a decimal string representation.
     604             :  *
     605             :  * Convert a uint8_t value into its ASCII decimal string representation.
     606             :  * The string is terminated if there is enough space in buf.
     607             :  *
     608             :  * @param buf     Address of where to store the string representation.
     609             :  * @param buflen  Size of the storage area for string representation.
     610             :  * @param value   The value to convert to decimal string
     611             :  *
     612             :  * @return     The length of the converted string (excluding terminator if
     613             :  *             any), or 0 if an error occurred.
     614             :  */
     615           1 : uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
     616             : 
     617             : /**
     618             :  * @brief Sign extend an 8, 16 or 32 bit value using the index bit as sign bit.
     619             :  *
     620             :  * @param value The value to sign expand.
     621             :  * @param index 0 based bit index to sign bit (0 to 31)
     622             :  */
     623           1 : static inline int32_t sign_extend(uint32_t value, uint8_t index)
     624             : {
     625             :         __ASSERT_NO_MSG(index <= 31);
     626             : 
     627             :         uint8_t shift = 31 - index;
     628             : 
     629             :         return (int32_t)(value << shift) >> shift;
     630             : }
     631             : 
     632             : /**
     633             :  * @brief Sign extend a 64 bit value using the index bit as sign bit.
     634             :  *
     635             :  * @param value The value to sign expand.
     636             :  * @param index 0 based bit index to sign bit (0 to 63)
     637             :  */
     638           1 : static inline int64_t sign_extend_64(uint64_t value, uint8_t index)
     639             : {
     640             :         __ASSERT_NO_MSG(index <= 63);
     641             : 
     642             :         uint8_t shift = 63 - index;
     643             : 
     644             :         return (int64_t)(value << shift) >> shift;
     645             : }
     646             : 
     647             : /**
     648             :  * @brief Properly truncate a NULL-terminated UTF-8 string
     649             :  *
     650             :  * Take a NULL-terminated UTF-8 string and ensure that if the string has been
     651             :  * truncated (by setting the NULL terminator) earlier by other means, that
     652             :  * the string ends with a properly formatted UTF-8 character (1-4 bytes).
     653             :  *
     654             :  * @htmlonly
     655             :  * Example:
     656             :  *      char test_str[] = "€€€";
     657             :  *      char trunc_utf8[8];
     658             :  *
     659             :  *      printf("Original : %s\n", test_str); // €€€
     660             :  *      strncpy(trunc_utf8, test_str, sizeof(trunc_utf8));
     661             :  *      trunc_utf8[sizeof(trunc_utf8) - 1] = '\0';
     662             :  *      printf("Bad      : %s\n", trunc_utf8); // €€�
     663             :  *      utf8_trunc(trunc_utf8);
     664             :  *      printf("Truncated: %s\n", trunc_utf8); // €€
     665             :  * @endhtmlonly
     666             :  *
     667             :  * @param utf8_str NULL-terminated string
     668             :  *
     669             :  * @return Pointer to the @p utf8_str
     670             :  */
     671           1 : char *utf8_trunc(char *utf8_str);
     672             : 
     673             : /**
     674             :  * @brief Copies a UTF-8 encoded string from @p src to @p dst
     675             :  *
     676             :  * The resulting @p dst will always be NULL terminated if @p n is larger than 0,
     677             :  * and the @p dst string will always be properly UTF-8 truncated.
     678             :  *
     679             :  * @param dst The destination of the UTF-8 string.
     680             :  * @param src The source string
     681             :  * @param n   The size of the @p dst buffer. Maximum number of characters copied
     682             :  *            is @p n - 1. If 0 nothing will be done, and the @p dst will not be
     683             :  *            NULL terminated.
     684             :  *
     685             :  * @return Pointer to the @p dst
     686             :  */
     687           1 : char *utf8_lcpy(char *dst, const char *src, size_t n);
     688             : 
     689             : #define __z_log2d(x) (32 - __builtin_clz(x) - 1)
     690             : #define __z_log2q(x) (64 - __builtin_clzll(x) - 1)
     691             : #define __z_log2(x) (sizeof(__typeof__(x)) > 4 ? __z_log2q(x) : __z_log2d(x))
     692             : 
     693             : /**
     694             :  * @brief Compute log2(x)
     695             :  *
     696             :  * @note This macro expands its argument multiple times (to permit use
     697             :  *       in constant expressions), which must not have side effects.
     698             :  *
     699             :  * @param x An unsigned integral value to compute logarithm of (positive only)
     700             :  *
     701             :  * @return log2(x) when 1 <= x <= max(x), -1 when x < 1
     702             :  */
     703           1 : #define LOG2(x) ((x) < 1 ? -1 : __z_log2(x))
     704             : 
     705             : /**
     706             :  * @brief Compute ceil(log2(x))
     707             :  *
     708             :  * @note This macro expands its argument multiple times (to permit use
     709             :  *       in constant expressions), which must not have side effects.
     710             :  *
     711             :  * @param x An unsigned integral value
     712             :  *
     713             :  * @return ceil(log2(x)) when 1 <= x <= max(type(x)), 0 when x < 1
     714             :  */
     715           1 : #define LOG2CEIL(x) ((x) <= 1 ?  0 : __z_log2((x)-1) + 1)
     716             : 
     717             : /**
     718             :  * @brief Compute next highest power of two
     719             :  *
     720             :  * Equivalent to 2^ceil(log2(x))
     721             :  *
     722             :  * @note This macro expands its argument multiple times (to permit use
     723             :  *       in constant expressions), which must not have side effects.
     724             :  *
     725             :  * @param x An unsigned integral value
     726             :  *
     727             :  * @return 2^ceil(log2(x)) or 0 if 2^ceil(log2(x)) would saturate 64-bits
     728             :  */
     729           1 : #define NHPOT(x) ((x) < 1 ? 1 : ((x) > (1ULL<<63) ? 0 : 1ULL << LOG2CEIL(x)))
     730             : 
     731             : /**
     732             :  * @brief Determine if a buffer exceeds highest address
     733             :  *
     734             :  * This macro determines if a buffer identified by a starting address @a addr
     735             :  * and length @a buflen spans a region of memory that goes beyond the highest
     736             :  * possible address (thereby resulting in a pointer overflow).
     737             :  *
     738             :  * @param addr Buffer starting address
     739             :  * @param buflen Length of the buffer
     740             :  *
     741             :  * @return true if pointer overflow detected, false otherwise
     742             :  */
     743             : #define Z_DETECT_POINTER_OVERFLOW(addr, buflen)  \
     744             :         (((buflen) != 0) &&                        \
     745             :         ((UINTPTR_MAX - (uintptr_t)(addr)) <= ((uintptr_t)((buflen) - 1))))
     746             : 
     747             : /**
     748             :  * @brief XOR n bytes
     749             :  *
     750             :  * @param dst  Destination of where to store result. Shall be @p len bytes.
     751             :  * @param src1 First source. Shall be @p len bytes.
     752             :  * @param src2 Second source. Shall be @p len bytes.
     753             :  * @param len  Number of bytes to XOR.
     754             :  */
     755           1 : static inline void mem_xor_n(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, size_t len)
     756             : {
     757             :         while (len--) {
     758             :                 *dst++ = *src1++ ^ *src2++;
     759             :         }
     760             : }
     761             : 
     762             : /**
     763             :  * @brief XOR 32 bits
     764             :  *
     765             :  * @param dst  Destination of where to store result. Shall be 32 bits.
     766             :  * @param src1 First source. Shall be 32 bits.
     767             :  * @param src2 Second source. Shall be 32 bits.
     768             :  */
     769           1 : static inline void mem_xor_32(uint8_t dst[4], const uint8_t src1[4], const uint8_t src2[4])
     770             : {
     771             :         mem_xor_n(dst, src1, src2, 4U);
     772             : }
     773             : 
     774             : /**
     775             :  * @brief XOR 128 bits
     776             :  *
     777             :  * @param dst  Destination of where to store result. Shall be 128 bits.
     778             :  * @param src1 First source. Shall be 128 bits.
     779             :  * @param src2 Second source. Shall be 128 bits.
     780             :  */
     781           1 : static inline void mem_xor_128(uint8_t dst[16], const uint8_t src1[16], const uint8_t src2[16])
     782             : {
     783             :         mem_xor_n(dst, src1, src2, 16);
     784             : }
     785             : 
     786             : #ifdef __cplusplus
     787             : }
     788             : #endif
     789             : 
     790             : /* This file must be included at the end of the !_ASMLANGUAGE guard.
     791             :  * It depends on macros defined in this file above which cannot be forward declared.
     792             :  */
     793             : #include <zephyr/sys/time_units.h>
     794             : 
     795             : #endif /* !_ASMLANGUAGE */
     796             : 
     797             : /** @brief Number of bytes in @p x kibibytes */
     798             : #ifdef _LINKER
     799             : /* This is used in linker scripts so need to avoid type casting there */
     800           1 : #define KB(x) ((x) << 10)
     801             : #else
     802             : #define KB(x) (((size_t)(x)) << 10)
     803             : #endif
     804             : /** @brief Number of bytes in @p x mebibytes */
     805           1 : #define MB(x) (KB(x) << 10)
     806             : /** @brief Number of bytes in @p x gibibytes */
     807           1 : #define GB(x) (MB(x) << 10)
     808             : 
     809             : /** @brief Number of Hz in @p x kHz */
     810           1 : #define KHZ(x) ((x) * 1000)
     811             : /** @brief Number of Hz in @p x MHz */
     812           1 : #define MHZ(x) (KHZ(x) * 1000)
     813             : 
     814             : /**
     815             :  * @brief For the POSIX architecture add a minimal delay in a busy wait loop.
     816             :  * For other architectures this is a no-op.
     817             :  *
     818             :  * In the POSIX ARCH, code takes zero simulated time to execute,
     819             :  * so busy wait loops become infinite loops, unless we
     820             :  * force the loop to take a bit of time.
     821             :  * Include this macro in all busy wait/spin loops
     822             :  * so they will also work when building for the POSIX architecture.
     823             :  *
     824             :  * @param t Time in microseconds we will busy wait
     825             :  */
     826             : #if defined(CONFIG_ARCH_POSIX)
     827             : #define Z_SPIN_DELAY(t) k_busy_wait(t)
     828             : #else
     829             : #define Z_SPIN_DELAY(t)
     830             : #endif
     831             : 
     832             : /**
     833             :  * @brief Wait for an expression to return true with a timeout
     834             :  *
     835             :  * Spin on an expression with a timeout and optional delay between iterations
     836             :  *
     837             :  * Commonly needed when waiting on hardware to complete an asynchronous
     838             :  * request to read/write/initialize/reset, but useful for any expression.
     839             :  *
     840             :  * @param expr Truth expression upon which to poll, e.g.: XYZREG & XYZREG_EN
     841             :  * @param timeout Timeout to wait for in microseconds, e.g.: 1000 (1ms)
     842             :  * @param delay_stmt Delay statement to perform each poll iteration
     843             :  *                   e.g.: NULL, k_yield(), k_msleep(1) or k_busy_wait(1)
     844             :  *
     845             :  * @retval expr As a boolean return, if false then it has timed out.
     846             :  */
     847           1 : #define WAIT_FOR(expr, timeout, delay_stmt)                                                        \
     848             :         ({                                                                                         \
     849             :                 uint32_t _wf_cycle_count = k_us_to_cyc_ceil32(timeout);                            \
     850             :                 uint32_t _wf_start = k_cycle_get_32();                                             \
     851             :                 while (!(expr) && (_wf_cycle_count > (k_cycle_get_32() - _wf_start))) {            \
     852             :                         delay_stmt;                                                                \
     853             :                         Z_SPIN_DELAY(10);                                                          \
     854             :                 }                                                                                  \
     855             :                 (expr);                                                                            \
     856             :         })
     857             : 
     858             : /**
     859             :  * @}
     860             :  */
     861             : 
     862             : #endif /* ZEPHYR_INCLUDE_SYS_UTIL_H_ */

Generated by: LCOV version 1.14