If you need urgent consulting help click here
Utilities
This page contains reference documentation for <sys/util.h>
, which provides
miscellaneous utility functions and macros.
- group sys-util
Defines
-
POINTER_TO_UINT(x)
Cast
x
, a pointer, to an unsigned integer.
-
UINT_TO_POINTER(x)
Cast
x
, an unsigned integer, to avoid*
.
-
POINTER_TO_INT(x)
Cast
x
, a pointer, to a signed integer.
-
INT_TO_POINTER(x)
Cast
x
, a signed integer, to avoid*
.
-
BITS_PER_LONG
Number of bits in a long int.
-
GENMASK(h, l)
Create a contiguous bitmask starting at bit position
l
and ending at positionh
.
-
LSB_GET(value)
Extract the Least Significant Bit from
value
.
-
FIELD_GET(mask, value)
Extract a bitfield element from
value
corresponding to the field maskmask
.
-
FIELD_PREP(mask, value)
Prepare a bitfield element using
value
withmask
representing its field position and width. The result should be combined with other fields using a logical OR.
-
ZERO_OR_COMPILE_ERROR(cond)
0 if
cond
is true-ish; causes a compile error otherwise.
-
IS_ARRAY(array)
Zero if
array
has an array type, a compile error otherwise.This macro is available only from C, not C++.
-
ARRAY_SIZE(array)
Number of elements in the given
array
.In C++, due to language limitations, this will accept as
array
any type that implementsoperator[]
. The results may not be particularly meaningful in this case.In C, passing a pointer as
array
causes a compile error.
-
PART_OF_ARRAY(array, ptr)
Check if a pointer
ptr
lies withinarray
.In C but not C++, this causes a compile error if
array
is not an array (e.g. ifptr
andarray
are mixed up).- Parameters
ptr – a pointer
array – an array
- Returns
1 if
ptr
is part ofarray
, 0 otherwise
-
CONTAINER_OF(ptr, type, field)
Get a pointer to a structure containing the element.
Example:
struct foo { int bar; }; struct foo my_foo; int *ptr = &my_foo.bar; struct foo *container = CONTAINER_OF(ptr, struct foo, bar);
Above,
container
points atmy_foo
.- Parameters
ptr – pointer to a structure element
type – name of the type that
ptr
is an element offield – the name of the field within the struct
ptr
points to
- Returns
a pointer to the structure that contains
ptr
-
ROUND_UP(x, align)
Value of
x
rounded up to the next multiple ofalign
, which must be a power of 2.
-
ROUND_DOWN(x, align)
Value of
x
rounded down to the previous multiple ofalign
, which must be a power of 2.
-
WB_UP(x)
Value of
x
rounded up to the next word boundary.
-
WB_DN(x)
Value of
x
rounded down to the previous word boundary.
-
ceiling_fraction(numerator, divider)
Ceiling function applied to
numerator
/divider
as a fraction.
-
MAX(a, b)
Obtain the maximum of two values.
Note
Arguments are evaluated twice. Use Z_MAX for a GCC-only, single evaluation version
- Parameters
a – First value.
b – Second value.
- Returns
Maximum value of
a
andb
.
-
MIN(a, b)
Obtain the minimum of two values.
Note
Arguments are evaluated twice. Use Z_MIN for a GCC-only, single evaluation version
- Parameters
a – First value.
b – Second value.
- Returns
Minimum value of
a
andb
.
-
CLAMP(val, low, high)
Clamp a value to a given range.
Note
Arguments are evaluated multiple times. Use Z_CLAMP for a GCC-only, single evaluation version.
- Parameters
val – Value to be clamped.
low – Lowest allowed value (inclusive).
high – Highest allowed value (inclusive).
- Returns
Clamped value.
-
IN_RANGE(val, min, max)
Checks if a value is within range.
Note
val
is evaluated twice.- Parameters
val – Value to be checked.
min – Lower bound (inclusive).
max – Upper bound (inclusive).
- Return values
true – If value is within range
false – If the value is not within range
-
KB(x)
Number of bytes in
x
kibibytes.
-
MB(x)
Number of bytes in
x
mebibytes.
-
GB(x)
Number of bytes in
x
gibibytes.
-
KHZ(x)
Number of Hz in
x
kHz.
-
MHZ(x)
Number of Hz in
x
MHz.
-
WAIT_FOR(expr, timeout, delay_stmt)
Wait for an expression to return true with a timeout.
Spin on an expression with a timeout and optional delay between iterations
Commonly needed when waiting on hardware to complete an asynchronous request to read/write/initialize/reset, but useful for any expression.
- Parameters
expr – Truth expression upon which to poll, e.g.: XYZREG & XYZREG_EN
timeout – Timeout to wait for in microseconds, e.g.: 1000 (1ms)
delay_stmt – Delay statement to perform each poll iteration e.g.: NULL, k_yield(), k_msleep(1) or k_busy_wait(1)
- Return values
expr – As a boolean return, if false then it has timed out.
-
BIT(n)
Unsigned integer with bit position
n
set (signed in assembly language).
-
BIT64(_n)
64-bit unsigned integer with bit position
_n
set.
-
WRITE_BIT(var, bit, set)
Set or clear a bit depending on a boolean value.
The argument
var
is a variable whose value is written to as a side effect.- Parameters
var – Variable to be altered
bit – Bit number
set – if 0, clears
bit
invar
; any other value setsbit
-
BIT_MASK(n)
Bit mask with bits 0 through
n-1
(inclusive) set, or 0 ifn
is 0.
-
BIT64_MASK(n)
64-bit bit mask with bits 0 through
n-1
(inclusive) set, or 0 ifn
is 0.
-
IS_ENABLED(config_macro)
Check for macro definition in compiler-visible expressions.
This trick was pioneered in Linux as the config_enabled() macro. It has the effect of taking a macro value that may be defined to “1” or may not be defined at all and turning it into a literal expression that can be handled by the C compiler instead of just the preprocessor. It is often used with a
CONFIG_FOO
macro which may be defined to 1 via Kconfig, or left undefined.That is, it works similarly to
#if defined(CONFIG_FOO)
except that its expansion is a C expression. Thus, much#ifdef
usage can be replaced with equivalents like:if (IS_ENABLED(CONFIG_FOO)) { do_something_with_foo }
This is cleaner since the compiler can generate errors and warnings for
do_something_with_foo
even whenCONFIG_FOO
is undefined.- Parameters
config_macro – Macro to check
- Returns
1 if
config_macro
is defined to 1, 0 otherwise (including ifconfig_macro
is not defined)
-
COND_CODE_1(_flag, _if_1_code, _else_code)
Insert code depending on whether
_flag
expands to 1 or not.This relies on similar tricks as IS_ENABLED(), but as the result of
_flag
expansion, results in either_if_1_code
or_else_code
is expanded.To prevent the preprocessor from treating commas as argument separators, the
_if_1_code
and_else_code
expressions must be inside brackets/parentheses:()
. These are stripped away during macro expansion.Example:
COND_CODE_1(CONFIG_FLAG, (uint32_t x;), (there_is_no_flag();))
If
CONFIG_FLAG
is defined to 1, this expands to:uint32_t x;
It expands to
there_is_no_flag();
otherwise.This could be used as an alternative to:
#if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1) #define MAYBE_DECLARE(x) uint32_t x #else #define MAYBE_DECLARE(x) there_is_no_flag() #endif MAYBE_DECLARE(x);
However, the advantage of COND_CODE_1() is that code is resolved in place where it is used, while the
#if
method definesMAYBE_DECLARE
on two lines and requires it to be invoked again on a separate line. This makes COND_CODE_1() more concise and also sometimes more useful when used within another macro’s expansion.Note
_flag
can be the result of preprocessor expansion, e.g. an expression involvingNUM_VA_ARGS_LESS_1(...)
. However,_if_1_code
is only expanded if_flag
expands to the integer literal 1. Integer expressions that evaluate to 1, e.g. after doing some arithmetic, will not work.- Parameters
_flag – evaluated flag
_if_1_code – result if
_flag
expands to 1; must be in parentheses_else_code – result otherwise; must be in parentheses
-
COND_CODE_0(_flag, _if_0_code, _else_code)
Like COND_CODE_1() except tests if
_flag
is 0.This is like COND_CODE_1(), except that it tests whether
_flag
expands to the integer literal 0. It expands to_if_0_code
if so, and_else_code
otherwise; both of these must be enclosed in parentheses.See also
- Parameters
_flag – evaluated flag
_if_0_code – result if
_flag
expands to 0; must be in parentheses_else_code – result otherwise; must be in parentheses
-
IF_ENABLED(_flag, _code)
Insert code if
_flag
is defined and equals 1.Like COND_CODE_1(), this expands to
_code
if_flag
is defined to 1; it expands to nothing otherwise.Example:
IF_ENABLED(CONFIG_FLAG, (uint32_t foo;))
If
CONFIG_FLAG
is defined to 1, this expands to:uint32_t foo;
and to nothing otherwise.
It can be considered as a more compact alternative to:
#if defined(CONFIG_FLAG) && (CONFIG_FLAG == 1) uint32_t foo; #endif
- Parameters
_flag – evaluated flag
_code – result if
_flag
expands to 1; must be in parentheses
-
IS_EMPTY(...)
Check if a macro has a replacement expression.
If
a
is a macro defined to a nonempty value, this will return true, otherwise it will return false. It only works with defined macros, so an additional#ifdef
test may be needed in some cases.This macro may be used with COND_CODE_1() and COND_CODE_0() while processing
__VA_ARGS__
to avoid processing empty arguments.Example:
#define EMPTY #define NON_EMPTY 1 #undef UNDEFINED IS_EMPTY(EMPTY) IS_EMPTY(NON_EMPTY) IS_EMPTY(UNDEFINED) #if defined(EMPTY) && IS_EMPTY(EMPTY) == true some_conditional_code #endif
In above examples, the invocations of IS_EMPTY(…) return
true
,false
, andtrue
;some_conditional_code
is included.- Parameters
... – macro to check for emptiness (may be
__VA_ARGS__
)
-
LIST_DROP_EMPTY(...)
Remove empty arguments from list.
During macro expansion,
__VA_ARGS__
and other preprocessor generated lists may contain empty elements, e.g.:#define LIST ,a,b,,d,
Using EMPTY to show each empty element, LIST contains:
EMPTY, a, b, EMPTY, d
When processing such lists, e.g. using FOR_EACH(), all empty elements will be processed, and may require filtering out. To make that process easier, it is enough to invoke LIST_DROP_EMPTY which will remove all empty elements.
Example:
LIST_DROP_EMPTY(LIST)
expands to:
a, b, d
- Parameters
... – list to be processed
-
EMPTY
Macro with an empty expansion.
This trivial definition is provided for readability when a macro should expand to an empty result, which e.g. is sometimes needed to silence checkpatch.
Example:
#define LIST_ITEM(n) , item##n
The above would cause checkpatch to complain, but:
#define LIST_ITEM(n) EMPTY, item##n
would not.
-
IDENTITY(V)
Macro that expands to its argument.
This is useful in macros like
FOR_EACH()
when there is no transformation required on the list elements.- Parameters
V – any value
-
GET_ARG_N(N, ...)
Get nth argument from argument list.
- Parameters
N – Argument index to fetch. Counter from 1.
... – Variable list of arguments from which one argument is returned.
- Returns
Nth argument.
-
GET_ARGS_LESS_N(N, ...)
Strips n first arguments from the argument list.
- Parameters
N – Number of arguments to discard.
... – Variable list of arguments.
- Returns
argument list without N first arguments.
-
UTIL_OR(a, b)
Like
a || b
, but does evaluation and short-circuiting at C preprocessor time.This is not the same as the binary
||
operator; in particular,a
should expand to an integer literal 0 or 1. However,b
can be any value.This can be useful when
b
is an expression that would cause a build error whena
is 1.
-
UTIL_AND(a, b)
Like
a && b
, but does evaluation and short-circuiting at C preprocessor time.This is not the same as the binary
&&
, however; in particular,a
should expand to an integer literal 0 or 1. However,b
can be any value.This can be useful when
b
is an expression that would cause a build error whena
is 0.
-
LISTIFY(LEN, F, sep, ...)
Generates a sequence of code with configurable separator.
Example:
#define FOO(i, _) MY_PWM ## i { LISTIFY(PWM_COUNT, FOO, (,)) }
The above two lines expand to:
{ MY_PWM0 , MY_PWM1 }
Note
Calling LISTIFY with undefined arguments has undefined behavior.
- Parameters
LEN – The length of the sequence. Must be an integer literal less than 255.
F – A macro function that accepts at least two arguments:
F(i, ...)
.F
is called repeatedly in the expansion. Its first argumenti
is the index in the sequence, and the variable list of arguments passed to LISTIFY are passed through toF
.sep – Separator (e.g. comma or semicolon). Must be in parentheses; this is required to enable providing a comma as separator.
-
UTIL_LISTIFY(LEN, F, ...)
Generates a sequence of code. Deprecated, use LISTIFY.
- Deprecated:
Use LISTIFY instead.
Example:
#define FOO(i, _) MY_PWM ## i , { UTIL_LISTIFY(PWM_COUNT, FOO) }
The above two lines expand to:
{ MY_PWM0 , MY_PWM1 , }
Note
Calling UTIL_LISTIFY with undefined arguments has undefined behavior.
- Parameters
LEN – The length of the sequence. Must be an integer literal less than 255.
F – A macro function that accepts at least two arguments:
F(i, ...)
.F
is called repeatedly in the expansion. Its first argumenti
is the index in the sequence, and the variable list of arguments passed to UTIL_LISTIFY are passed through toF
.
-
FOR_EACH(F, sep, ...)
Call a macro
F
on each provided argument with a given separator between each call.Example:
#define F(x) int a##x FOR_EACH(F, (;), 4, 5, 6);
This expands to:
int a4; int a5; int a6;
- Parameters
F – Macro to invoke
sep – Separator (e.g. comma or semicolon). Must be in parentheses; this is required to enable providing a comma as separator.
... – Variable argument list. The macro
F
is invoked asF(element)
for each element in the list.
-
FOR_EACH_NONEMPTY_TERM(F, term, ...)
Like FOR_EACH(), but with a terminator instead of a separator, and drops empty elements from the argument list.
The
sep
argument toFOR_EACH(F, (sep), a, b)
is a separator which is placed between calls toF
, like this:FOR_EACH(F, (sep), a, b) // F(a) sep F(b) // ^^^ no sep here!
By contrast, the
term
argument toFOR_EACH_NONEMPTY_TERM(F, (term), a, b)
is added after each timeF
appears in the expansion:FOR_EACH_NONEMPTY_TERM(F, (term), a, b) // F(a) term F(b) term // ^^^^
Further, any empty elements are dropped:
FOR_EACH_NONEMPTY_TERM(F, (term), a, EMPTY, b) // F(a) term F(b) term
This is more convenient in some cases, because FOR_EACH_NONEMPTY_TERM() expands to nothing when given an empty argument list, and it’s often cumbersome to write a macro
F
that does the right thing even when given an empty argument.One example is when
__VA_ARGS__
may or may not be empty, and the results are embedded in a larger initializer:#define SQUARE(x) ((x)*(x)) int my_array[] = { FOR_EACH_NONEMPTY_TERM(SQUARE, (,), FOO(...)) FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAR(...)) FOR_EACH_NONEMPTY_TERM(SQUARE, (,), BAZ(...)) };
This is more convenient than:
figuring out whether the
FOO
,BAR
, andBAZ
expansions are empty and adding a comma manually (or not) between FOR_EACH() callsrewriting SQUARE so it reacts appropriately when “x” is empty (which would be necessary if e.g.
FOO
expands to nothing)
- Parameters
F – Macro to invoke on each nonempty element of the variable arguments
term – Terminator (e.g. comma or semicolon) placed after each invocation of F. Must be in parentheses; this is required to enable providing a comma as separator.
... – Variable argument list. The macro
F
is invoked asF(element)
for each nonempty element in the list.
-
FOR_EACH_IDX(F, sep, ...)
Call macro
F
on each provided argument, with the argument’s index as an additional parameter.This is like FOR_EACH(), except
F
should be a macro which takes two arguments:F(index, variable_arg)
.Example:
#define F(idx, x) int a##idx = x FOR_EACH_IDX(F, (;), 4, 5, 6);
This expands to:
int a0 = 4; int a1 = 5; int a2 = 6;
- Parameters
F – Macro to invoke
sep – Separator (e.g. comma or semicolon). Must be in parentheses; this is required to enable providing a comma as separator.
... – Variable argument list. The macro
F
is invoked asF(index, element)
for each element in the list.
-
FOR_EACH_FIXED_ARG(F, sep, fixed_arg, ...)
Call macro
F
on each provided argument, with an additional fixed argument as a parameter.This is like FOR_EACH(), except
F
should be a macro which takes two arguments:F(variable_arg, fixed_arg)
.Example:
static void func(int val, void *dev); FOR_EACH_FIXED_ARG(func, (;), dev, 4, 5, 6);
This expands to:
func(4, dev); func(5, dev); func(6, dev);
- Parameters
F – Macro to invoke
sep – Separator (e.g. comma or semicolon). Must be in parentheses; this is required to enable providing a comma as separator.
fixed_arg – Fixed argument passed to
F
as the second macro parameter.... – Variable argument list. The macro
F
is invoked asF(element, fixed_arg)
for each element in the list.
-
FOR_EACH_IDX_FIXED_ARG(F, sep, fixed_arg, ...)
Calls macro
F
for each variable argument with an index and fixed argument.This is like the combination of FOR_EACH_IDX() with FOR_EACH_FIXED_ARG().
Example:
#define F(idx, x, fixed_arg) int fixed_arg##idx = x FOR_EACH_IDX_FIXED_ARG(F, (;), a, 4, 5, 6);
This expands to:
int a0 = 4; int a1 = 5; int a2 = 6;
- Parameters
F – Macro to invoke
sep – Separator (e.g. comma or semicolon). Must be in parentheses; This is required to enable providing a comma as separator.
fixed_arg – Fixed argument passed to
F
as the third macro parameter.... – Variable list of arguments. The macro
F
is invoked asF(index, element, fixed_arg)
for each element in the list.
-
REVERSE_ARGS(...)
Reverse arguments order.
- Parameters
... – Variable argument list.
-
NUM_VA_ARGS_LESS_1(...)
Number of arguments in the variable arguments list minus one.
- Parameters
... – List of arguments
- Returns
Number of variadic arguments in the argument list, minus one
-
MACRO_MAP_CAT(...)
Mapping macro that pastes results together.
This is similar to FOR_EACH() in that it invokes a macro repeatedly on each element of
__VA_ARGS__
. However, unlike FOR_EACH(), MACRO_MAP_CAT() pastes the results together into a single token.For example, with this macro FOO:
#define FOO(x) item_##x##_
MACRO_MAP_CAT(FOO, a, b, c),
expands to the token:item_a_item_b_item_c_
- Parameters
... – Macro to expand on each argument, followed by its arguments. (The macro should take exactly one argument.)
- Returns
The results of expanding the macro on each argument, all pasted together
-
MACRO_MAP_CAT_N(N, ...)
Mapping macro that pastes a fixed number of results together.
Similar to MACRO_MAP_CAT(), but expects a fixed number of arguments. If more arguments are given than are expected, the rest are ignored.
- Parameters
N – Number of arguments to map
... – Macro to expand on each argument, followed by its arguments. (The macro should take exactly one argument.)
- Returns
The results of expanding the macro on each argument, all pasted together
Functions
-
static inline bool is_power_of_two(unsigned int x)
Is
x
a power of two?- Parameters
x – value to check
- Returns
true if
x
is a power of two, false otherwise
-
static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift)
Arithmetic shift right.
- Parameters
value – value to shift
shift – number of bits to shift
- Returns
value
shifted right byshift
; opened bit positions are filled with the sign bit
-
static inline void bytecpy(void *dst, const void *src, size_t size)
byte by byte memcpy.
Copy
size
bytes ofsrc
intodest
. This is guaranteed to be done byte by byte.- Parameters
dst – Pointer to the destination memory.
src – Pointer to the source of the data.
size – The number of bytes to copy.
-
static inline void byteswp(void *a, void *b, size_t size)
byte by byte swap.
Swap size bytes between memory regions a and b. This is guaranteed to be done byte by byte.
- Parameters
a – Pointer to the the first memory region.
b – Pointer to the the second memory region.
size – The number of bytes to swap.
-
int char2hex(char c, uint8_t *x)
Convert a single character into a hexadecimal nibble.
- Parameters
c – The character to convert
x – The address of storage for the converted number.
- Returns
Zero on success or (negative) error code otherwise.
-
int hex2char(uint8_t x, char *c)
Convert a single hexadecimal nibble into a character.
- Parameters
c – The number to convert
x – The address of storage for the converted character.
- Returns
Zero on success or (negative) error code otherwise.
-
size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen)
Convert a binary array into string representation.
- Parameters
buf – The binary array to convert
buflen – The length of the binary array to convert
hex – Address of where to store the string representation.
hexlen – Size of the storage area for string representation.
- Returns
The length of the converted string, or 0 if an error occurred.
-
size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen)
Convert a hexadecimal string into a binary array.
- Parameters
hex – The hexadecimal string to convert
hexlen – The length of the hexadecimal string to convert.
buf – Address of where to store the binary data
buflen – Size of the storage area for binary data
- Returns
The length of the binary array, or 0 if an error occurred.
-
static inline uint8_t bcd2bin(uint8_t bcd)
Convert a binary coded decimal (BCD 8421) value to binary.
- Parameters
bcd – BCD 8421 value to convert.
- Returns
Binary representation of input value.
-
static inline uint8_t bin2bcd(uint8_t bin)
Convert a binary value to binary coded decimal (BCD 8421).
- Parameters
bin – Binary value to convert.
- Returns
BCD 8421 representation of input value.
-
uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value)
Convert a uint8_t into a decimal string representation.
Convert a uint8_t value into its ASCII decimal string representation. The string is terminated if there is enough space in buf.
- Parameters
buf – Address of where to store the string representation.
buflen – Size of the storage area for string representation.
value – The value to convert to decimal string
- Returns
The length of the converted string (excluding terminator if any), or 0 if an error occurred.
-
char *utf8_trunc(char *utf8_str)
Properly truncate a NULL-terminated UTF-8 string.
Take a NULL-terminated UTF-8 string and ensure that if the string has been truncated (by setting the NULL terminator) earlier by other means, that the string ends with a properly formatted UTF-8 character (1-4 bytes).
- Parameters
utf8_str – NULL-terminated string
- Returns
Pointer to the
utf8_str
-
char *utf8_lcpy(char *dst, const char *src, size_t n)
Copies a UTF-8 encoded string from
src
todst
.The resulting
dst
will always be NULL terminated, and thedst
string will always be properly UTF-8 truncated.return Pointer to the
dst
- Parameters
dst – The destination of the UTF-8 string.
src – The source string
n – The size of the
dst
buffer. Shall not be 0.
-
POINTER_TO_UINT(x)