LCOV - code coverage report
Current view: top level - include/zephyr/sys - util.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 10 0.0 %
Date: 2022-08-18 11:36:24 Functions: 0 2 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 6 0.0 %

           Branch data     Line data    Source code
       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 <sys/util_macro.h>
      18                 :            : 
      19                 :            : /* needs to be outside _ASMLANGUAGE so 'true' and 'false' can turn
      20                 :            :  * into '1' and '0' for asm or linker scripts
      21                 :            :  */
      22                 :            : #include <stdbool.h>
      23                 :            : 
      24                 :            : #ifndef _ASMLANGUAGE
      25                 :            : 
      26                 :            : #include <zephyr/types.h>
      27                 :            : #include <stddef.h>
      28                 :            : 
      29                 :            : #ifdef __cplusplus
      30                 :            : extern "C" {
      31                 :            : #endif
      32                 :            : 
      33                 :            : /**
      34                 :            :  * @defgroup sys-util Utility Functions
      35                 :            :  * @{
      36                 :            :  */
      37                 :            : 
      38                 :            : /** @brief Cast @p x, a pointer, to an unsigned integer. */
      39                 :            : #define POINTER_TO_UINT(x) ((uintptr_t) (x))
      40                 :            : /** @brief Cast @p x, an unsigned integer, to a <tt>void*</tt>. */
      41                 :            : #define UINT_TO_POINTER(x) ((void *) (uintptr_t) (x))
      42                 :            : /** @brief Cast @p x, a pointer, to a signed integer. */
      43                 :            : #define POINTER_TO_INT(x)  ((intptr_t) (x))
      44                 :            : /** @brief Cast @p x, a signed integer, to a <tt>void*</tt>. */
      45                 :            : #define INT_TO_POINTER(x)  ((void *) (intptr_t) (x))
      46                 :            : 
      47                 :            : #if !(defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__))
      48                 :            : #       error Missing required predefined macros for BITS_PER_LONG calculation
      49                 :            : #endif
      50                 :            : 
      51                 :            : /** Number of bits in a long int. */
      52                 :            : #define BITS_PER_LONG   (__CHAR_BIT__ * __SIZEOF_LONG__)
      53                 :            : 
      54                 :            : /**
      55                 :            :  * @brief Create a contiguous bitmask starting at bit position @p l
      56                 :            :  *        and ending at position @p h.
      57                 :            :  */
      58                 :            : #define GENMASK(h, l) \
      59                 :            :         (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
      60                 :            : 
      61                 :            : /** @brief Extract the Least Significant Bit from @p value. */
      62                 :            : #define LSB_GET(value) ((value) & -(value))
      63                 :            : 
      64                 :            : /**
      65                 :            :  * @brief Extract a bitfield element from @p value corresponding to
      66                 :            :  *        the field mask @p mask.
      67                 :            :  */
      68                 :            : #define FIELD_GET(mask, value)  (((value) & (mask)) / LSB_GET(mask))
      69                 :            : 
      70                 :            : /**
      71                 :            :  * @brief Prepare a bitfield element using @p value with @p mask representing
      72                 :            :  *        its field position and width. The result should be combined
      73                 :            :  *        with other fields using a logical OR.
      74                 :            :  */
      75                 :            : #define FIELD_PREP(mask, value) (((value) * LSB_GET(mask)) & (mask))
      76                 :            : 
      77                 :            : /** @brief 0 if @p cond is true-ish; causes a compile error otherwise. */
      78                 :            : #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
      79                 :            : 
      80                 :            : #if defined(__cplusplus)
      81                 :            : 
      82                 :            : /* The built-in function used below for type checking in C is not
      83                 :            :  * supported by GNU C++.
      84                 :            :  */
      85                 :            : #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
      86                 :            : 
      87                 :            : #else /* __cplusplus */
      88                 :            : 
      89                 :            : /**
      90                 :            :  * @brief Zero if @p array has an array type, a compile error otherwise
      91                 :            :  *
      92                 :            :  * This macro is available only from C, not C++.
      93                 :            :  */
      94                 :            : #define IS_ARRAY(array) \
      95                 :            :         ZERO_OR_COMPILE_ERROR( \
      96                 :            :                 !__builtin_types_compatible_p(__typeof__(array), \
      97                 :            :                                               __typeof__(&(array)[0])))
      98                 :            : 
      99                 :            : /**
     100                 :            :  * @brief Number of elements in the given @p array
     101                 :            :  *
     102                 :            :  * In C++, due to language limitations, this will accept as @p array
     103                 :            :  * any type that implements <tt>operator[]</tt>. The results may not be
     104                 :            :  * particularly meaningful in this case.
     105                 :            :  *
     106                 :            :  * In C, passing a pointer as @p array causes a compile error.
     107                 :            :  */
     108                 :            : #define ARRAY_SIZE(array) \
     109                 :            :         ((size_t) (IS_ARRAY(array) + (sizeof(array) / sizeof((array)[0]))))
     110                 :            : 
     111                 :            : #endif /* __cplusplus */
     112                 :            : 
     113                 :            : /**
     114                 :            :  * @brief Check if a pointer @p ptr lies within @p array.
     115                 :            :  *
     116                 :            :  * In C but not C++, this causes a compile error if @p array is not an array
     117                 :            :  * (e.g. if @p ptr and @p array are mixed up).
     118                 :            :  *
     119                 :            :  * @param ptr a pointer
     120                 :            :  * @param array an array
     121                 :            :  * @return 1 if @p ptr is part of @p array, 0 otherwise
     122                 :            :  */
     123                 :            : #define PART_OF_ARRAY(array, ptr) \
     124                 :            :         ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)]))
     125                 :            : 
     126                 :            : /**
     127                 :            :  * @brief Get a pointer to a structure containing the element
     128                 :            :  *
     129                 :            :  * Example:
     130                 :            :  *
     131                 :            :  *      struct foo {
     132                 :            :  *              int bar;
     133                 :            :  *      };
     134                 :            :  *
     135                 :            :  *      struct foo my_foo;
     136                 :            :  *      int *ptr = &my_foo.bar;
     137                 :            :  *
     138                 :            :  *      struct foo *container = CONTAINER_OF(ptr, struct foo, bar);
     139                 :            :  *
     140                 :            :  * Above, @p container points at @p my_foo.
     141                 :            :  *
     142                 :            :  * @param ptr pointer to a structure element
     143                 :            :  * @param type name of the type that @p ptr is an element of
     144                 :            :  * @param field the name of the field within the struct @p ptr points to
     145                 :            :  * @return a pointer to the structure that contains @p ptr
     146                 :            :  */
     147                 :            : #define CONTAINER_OF(ptr, type, field) \
     148                 :            :         ((type *)(((char *)(ptr)) - offsetof(type, field)))
     149                 :            : 
     150                 :            : /**
     151                 :            :  * @brief Value of @p x rounded up to the next multiple of @p align,
     152                 :            :  *        which must be a power of 2.
     153                 :            :  */
     154                 :            : #define ROUND_UP(x, align)                                   \
     155                 :            :         (((unsigned long)(x) + ((unsigned long)(align) - 1)) & \
     156                 :            :          ~((unsigned long)(align) - 1))
     157                 :            : 
     158                 :            : /**
     159                 :            :  * @brief Value of @p x rounded down to the previous multiple of @p
     160                 :            :  *        align, which must be a power of 2.
     161                 :            :  */
     162                 :            : #define ROUND_DOWN(x, align)                                 \
     163                 :            :         ((unsigned long)(x) & ~((unsigned long)(align) - 1))
     164                 :            : 
     165                 :            : /** @brief Value of @p x rounded up to the next word boundary. */
     166                 :            : #define WB_UP(x) ROUND_UP(x, sizeof(void *))
     167                 :            : 
     168                 :            : /** @brief Value of @p x rounded down to the previous word boundary. */
     169                 :            : #define WB_DN(x) ROUND_DOWN(x, sizeof(void *))
     170                 :            : 
     171                 :            : /**
     172                 :            :  * @brief Ceiling function applied to @p numerator / @p divider as a fraction.
     173                 :            :  */
     174                 :            : #define ceiling_fraction(numerator, divider) \
     175                 :            :         (((numerator) + ((divider) - 1)) / (divider))
     176                 :            : 
     177                 :            : #ifndef MAX
     178                 :            : /**
     179                 :            :  * @brief Obtain the maximum of two values.
     180                 :            :  *
     181                 :            :  * @note Arguments are evaluated twice. Use Z_MAX for a GCC-only, single
     182                 :            :  * evaluation version
     183                 :            :  *
     184                 :            :  * @param a First value.
     185                 :            :  * @param b Second value.
     186                 :            :  *
     187                 :            :  * @returns Maximum value of @p a and @p b.
     188                 :            :  */
     189                 :            : #define MAX(a, b) (((a) > (b)) ? (a) : (b))
     190                 :            : #endif
     191                 :            : 
     192                 :            : #ifndef MIN
     193                 :            : /**
     194                 :            :  * @brief Obtain the minimum of two values.
     195                 :            :  *
     196                 :            :  * @note Arguments are evaluated twice. Use Z_MIN for a GCC-only, single
     197                 :            :  * evaluation version
     198                 :            :  *
     199                 :            :  * @param a First value.
     200                 :            :  * @param b Second value.
     201                 :            :  *
     202                 :            :  * @returns Minimum value of @p a and @p b.
     203                 :            :  */
     204                 :            : #define MIN(a, b) (((a) < (b)) ? (a) : (b))
     205                 :            : #endif
     206                 :            : 
     207                 :            : #ifndef CLAMP
     208                 :            : /**
     209                 :            :  * @brief Clamp a value to a given range.
     210                 :            :  *
     211                 :            :  * @note Arguments are evaluated multiple times. Use Z_CLAMP for a GCC-only,
     212                 :            :  * single evaluation version.
     213                 :            :  *
     214                 :            :  * @param val Value to be clamped.
     215                 :            :  * @param low Lowest allowed value (inclusive).
     216                 :            :  * @param high Highest allowed value (inclusive).
     217                 :            :  *
     218                 :            :  * @returns Clamped value.
     219                 :            :  */
     220                 :            : #define CLAMP(val, low, high) (((val) <= (low)) ? (low) : MIN(val, high))
     221                 :            : #endif
     222                 :            : 
     223                 :            : /**
     224                 :            :  * @brief Checks if a value is within range.
     225                 :            :  *
     226                 :            :  * @note @p val is evaluated twice.
     227                 :            :  *
     228                 :            :  * @param val Value to be checked.
     229                 :            :  * @param min Lower bound (inclusive).
     230                 :            :  * @param max Upper bound (inclusive).
     231                 :            :  *
     232                 :            :  * @retval true If value is within range
     233                 :            :  * @retval false If the value is not within range
     234                 :            :  */
     235                 :            : #define IN_RANGE(val, min, max) ((val) >= (min) && (val) <= (max))
     236                 :            : 
     237                 :            : /**
     238                 :            :  * @brief Is @p x a power of two?
     239                 :            :  * @param x value to check
     240                 :            :  * @return true if @p x is a power of two, false otherwise
     241                 :            :  */
     242                 :          0 : static inline bool is_power_of_two(unsigned int x)
     243                 :            : {
     244   [ #  #  #  # ]:          0 :         return (x != 0U) && ((x & (x - 1U)) == 0U);
     245                 :            : }
     246                 :            : 
     247                 :            : /**
     248                 :            :  * @brief Arithmetic shift right
     249                 :            :  * @param value value to shift
     250                 :            :  * @param shift number of bits to shift
     251                 :            :  * @return @p value shifted right by @p shift; opened bit positions are
     252                 :            :  *         filled with the sign bit
     253                 :            :  */
     254                 :            : static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift)
     255                 :            : {
     256                 :            :         int64_t sign_ext;
     257                 :            : 
     258                 :            :         if (shift == 0U) {
     259                 :            :                 return value;
     260                 :            :         }
     261                 :            : 
     262                 :            :         /* extract sign bit */
     263                 :            :         sign_ext = (value >> 63) & 1;
     264                 :            : 
     265                 :            :         /* make all bits of sign_ext be the same as the value's sign bit */
     266                 :            :         sign_ext = -sign_ext;
     267                 :            : 
     268                 :            :         /* shift value and fill opened bit positions with sign bit */
     269                 :            :         return (value >> shift) | (sign_ext << (64 - shift));
     270                 :            : }
     271                 :            : 
     272                 :            : /**
     273                 :            :  * @brief byte by byte memcpy.
     274                 :            :  *
     275                 :            :  * Copy `size` bytes of `src` into `dest`. This is guaranteed to be done byte by byte.
     276                 :            :  *
     277                 :            :  * @param dst Pointer to the destination memory.
     278                 :            :  * @param src Pointer to the source of the data.
     279                 :            :  * @param size The number of bytes to copy.
     280                 :            :  */
     281                 :            : static inline void bytecpy(void *dst, const void *src, size_t size)
     282                 :            : {
     283                 :            :         size_t i;
     284                 :            : 
     285                 :            :         for (i = 0; i < size; ++i) {
     286                 :            :                 ((volatile uint8_t *)dst)[i] = ((volatile const uint8_t *)src)[i];
     287                 :            :         }
     288                 :            : }
     289                 :            : 
     290                 :            : /**
     291                 :            :  * @brief byte by byte swap.
     292                 :            :  *
     293                 :            :  * Swap @a size bytes between memory regions @a a and @a b. This is
     294                 :            :  * guaranteed to be done byte by byte.
     295                 :            :  *
     296                 :            :  * @param a Pointer to the the first memory region.
     297                 :            :  * @param b Pointer to the the second memory region.
     298                 :            :  * @param size The number of bytes to swap.
     299                 :            :  */
     300                 :          0 : static inline void byteswp(void *a, void *b, size_t size)
     301                 :            : {
     302                 :            :         uint8_t t;
     303                 :          0 :         uint8_t *aa = (uint8_t *)a;
     304                 :          0 :         uint8_t *bb = (uint8_t *)b;
     305                 :            : 
     306         [ #  # ]:          0 :         for (; size > 0; --size) {
     307                 :          0 :                 t = *aa;
     308                 :          0 :                 *aa++ = *bb;
     309                 :          0 :                 *bb++ = t;
     310                 :            :         }
     311                 :          0 : }
     312                 :            : 
     313                 :            : /**
     314                 :            :  * @brief      Convert a single character into a hexadecimal nibble.
     315                 :            :  *
     316                 :            :  * @param c     The character to convert
     317                 :            :  * @param x     The address of storage for the converted number.
     318                 :            :  *
     319                 :            :  *  @return Zero on success or (negative) error code otherwise.
     320                 :            :  */
     321                 :            : int char2hex(char c, uint8_t *x);
     322                 :            : 
     323                 :            : /**
     324                 :            :  * @brief      Convert a single hexadecimal nibble into a character.
     325                 :            :  *
     326                 :            :  * @param c     The number to convert
     327                 :            :  * @param x     The address of storage for the converted character.
     328                 :            :  *
     329                 :            :  *  @return Zero on success or (negative) error code otherwise.
     330                 :            :  */
     331                 :            : int hex2char(uint8_t x, char *c);
     332                 :            : 
     333                 :            : /**
     334                 :            :  * @brief      Convert a binary array into string representation.
     335                 :            :  *
     336                 :            :  * @param buf     The binary array to convert
     337                 :            :  * @param buflen  The length of the binary array to convert
     338                 :            :  * @param hex     Address of where to store the string representation.
     339                 :            :  * @param hexlen  Size of the storage area for string representation.
     340                 :            :  *
     341                 :            :  * @return     The length of the converted string, or 0 if an error occurred.
     342                 :            :  */
     343                 :            : size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen);
     344                 :            : 
     345                 :            : /**
     346                 :            :  * @brief      Convert a hexadecimal string into a binary array.
     347                 :            :  *
     348                 :            :  * @param hex     The hexadecimal string to convert
     349                 :            :  * @param hexlen  The length of the hexadecimal string to convert.
     350                 :            :  * @param buf     Address of where to store the binary data
     351                 :            :  * @param buflen  Size of the storage area for binary data
     352                 :            :  *
     353                 :            :  * @return     The length of the binary array, or 0 if an error occurred.
     354                 :            :  */
     355                 :            : size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen);
     356                 :            : 
     357                 :            : /**
     358                 :            :  * @brief Convert a binary coded decimal (BCD 8421) value to binary.
     359                 :            :  *
     360                 :            :  * @param bcd BCD 8421 value to convert.
     361                 :            :  *
     362                 :            :  * @return Binary representation of input value.
     363                 :            :  */
     364                 :            : static inline uint8_t bcd2bin(uint8_t bcd)
     365                 :            : {
     366                 :            :         return ((10 * (bcd >> 4)) + (bcd & 0x0F));
     367                 :            : }
     368                 :            : 
     369                 :            : /**
     370                 :            :  * @brief Convert a binary value to binary coded decimal (BCD 8421).
     371                 :            :  *
     372                 :            :  * @param bin Binary value to convert.
     373                 :            :  *
     374                 :            :  * @return BCD 8421 representation of input value.
     375                 :            :  */
     376                 :            : static inline uint8_t bin2bcd(uint8_t bin)
     377                 :            : {
     378                 :            :         return (((bin / 10) << 4) | (bin % 10));
     379                 :            : }
     380                 :            : 
     381                 :            : /**
     382                 :            :  * @brief      Convert a uint8_t into a decimal string representation.
     383                 :            :  *
     384                 :            :  * Convert a uint8_t value into its ASCII decimal string representation.
     385                 :            :  * The string is terminated if there is enough space in buf.
     386                 :            :  *
     387                 :            :  * @param buf     Address of where to store the string representation.
     388                 :            :  * @param buflen  Size of the storage area for string representation.
     389                 :            :  * @param value   The value to convert to decimal string
     390                 :            :  *
     391                 :            :  * @return     The length of the converted string (excluding terminator if
     392                 :            :  *             any), or 0 if an error occurred.
     393                 :            :  */
     394                 :            : uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
     395                 :            : 
     396                 :            : /**
     397                 :            :  * @brief Properly truncate a NULL-terminated UTF-8 string
     398                 :            :  *
     399                 :            :  * Take a NULL-terminated UTF-8 string and ensure that if the string has been
     400                 :            :  * truncated (by setting the NULL terminator) earlier by other means, that
     401                 :            :  * the string ends with a properly formatted UTF-8 character (1-4 bytes).
     402                 :            :  *
     403                 :            :  * @htmlonly
     404                 :            :  * Example:
     405                 :            :  *      char test_str[] = "€€€";
     406                 :            :  *      char trunc_utf8[8];
     407                 :            :  *
     408                 :            :  *      printf("Original : %s\n", test_str); // €€€
     409                 :            :  *      strncpy(trunc_utf8, test_str, sizeof(trunc_utf8));
     410                 :            :  *      trunc_utf8[sizeof(trunc_utf8) - 1] = '\0';
     411                 :            :  *      printf("Bad      : %s\n", trunc_utf8); // €€�
     412                 :            :  *      utf8_trunc(trunc_utf8);
     413                 :            :  *      printf("Truncated: %s\n", trunc_utf8); // €€
     414                 :            :  * @endhtmlonly
     415                 :            :  *
     416                 :            :  * @param utf8_str NULL-terminated string
     417                 :            :  *
     418                 :            :  *  @return Pointer to the @p utf8_str
     419                 :            :  */
     420                 :            : char *utf8_trunc(char *utf8_str);
     421                 :            : 
     422                 :            : /**
     423                 :            :  * @brief Copies a UTF-8 encoded string from @p src to @p dst
     424                 :            :  *
     425                 :            :  * The resulting @p dst will always be NULL terminated, and the @p dst string
     426                 :            :  * will always be properly UTF-8 truncated.
     427                 :            :  *
     428                 :            :  * @param dst The destination of the UTF-8 string.
     429                 :            :  * @param src The source string
     430                 :            :  * @param n   The size of the @p dst buffer. Shall not be 0.
     431                 :            :  *
     432                 :            :  * return Pointer to the @p dst
     433                 :            :  */
     434                 :            : char *utf8_lcpy(char *dst, const char *src, size_t n);
     435                 :            : 
     436                 :            : #ifdef __cplusplus
     437                 :            : }
     438                 :            : #endif
     439                 :            : 
     440                 :            : #endif /* !_ASMLANGUAGE */
     441                 :            : 
     442                 :            : /** @brief Number of bytes in @p x kibibytes */
     443                 :            : #ifdef _LINKER
     444                 :            : /* This is used in linker scripts so need to avoid type casting there */
     445                 :            : #define KB(x) ((x) << 10)
     446                 :            : #else
     447                 :            : #define KB(x) (((size_t)x) << 10)
     448                 :            : #endif
     449                 :            : /** @brief Number of bytes in @p x mebibytes */
     450                 :            : #define MB(x) (KB(x) << 10)
     451                 :            : /** @brief Number of bytes in @p x gibibytes */
     452                 :            : #define GB(x) (MB(x) << 10)
     453                 :            : 
     454                 :            : /** @brief Number of Hz in @p x kHz */
     455                 :            : #define KHZ(x) ((x) * 1000)
     456                 :            : /** @brief Number of Hz in @p x MHz */
     457                 :            : #define MHZ(x) (KHZ(x) * 1000)
     458                 :            : 
     459                 :            : /**
     460                 :            :  * @brief Wait for an expression to return true with a timeout
     461                 :            :  *
     462                 :            :  * Spin on an expression with a timeout and optional delay between iterations
     463                 :            :  *
     464                 :            :  * Commonly needed when waiting on hardware to complete an asynchronous
     465                 :            :  * request to read/write/initialize/reset, but useful for any expression.
     466                 :            :  *
     467                 :            :  * @param expr Truth expression upon which to poll, e.g.: XYZREG & XYZREG_EN
     468                 :            :  * @param timeout Timeout to wait for in microseconds, e.g.: 1000 (1ms)
     469                 :            :  * @param delay_stmt Delay statement to perform each poll iteration
     470                 :            :  *                   e.g.: NULL, k_yield(), k_msleep(1) or k_busy_wait(1)
     471                 :            :  *
     472                 :            :  * @retval expr As a boolean return, if false then it has timed out.
     473                 :            :  */
     474                 :            : #define WAIT_FOR(expr, timeout, delay_stmt)                                                        \
     475                 :            :         ({                                                                                         \
     476                 :            :                 uint32_t cycle_count = (sys_clock_hw_cycles_per_sec() / USEC_PER_SEC) * (timeout); \
     477                 :            :                 uint32_t start = k_cycle_get_32();                                                 \
     478                 :            :                 while (!(expr) && (cycle_count > (k_cycle_get_32() - start))) {                    \
     479                 :            :                         delay_stmt;                                                                \
     480                 :            :                 }                                                                                  \
     481                 :            :                 (expr);                                                                            \
     482                 :            :         })
     483                 :            : 
     484                 :            : /**
     485                 :            :  * @}
     486                 :            :  */
     487                 :            : 
     488                 :            : #endif /* ZEPHYR_INCLUDE_SYS_UTIL_H_ */

Generated by: LCOV version 1.14