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_ */
|