Kernel utilities

Utilities and data structures used by the kernel.

BIT0
1
0x00000001
BIT1
1
0x00000002
BIT2
1
0x00000004
BIT3
1
0x00000008
BIT4
1
0x00000010
BIT5
1
0x00000020
BIT6
1
0x00000040
BIT7
1
0x00000080
BIT8
1
0x00000100
BIT9
1
0x00000200
BIT10
1
0x00000400
BIT11
1
0x00000800
BIT12
1
0x00001000
BIT13
1
0x00002000
BIT14
1
0x00004000
BIT15
1
0x00008000
BIT16
1
0x00010000
BIT17
1
0x00020000
BIT18
1
0x00040000
BIT19
1
0x00080000
BIT20
1
0x00100000
BIT21
1
0x00200000
BIT22
1
0x00400000
BIT23
1
0x00800000
BIT24
1
0x01000000
BIT25
1
0x02000000
BIT26
1
0x04000000
BIT27
1
0x08000000
BIT28
1
0x10000000
BIT29
1
0x20000000
BIT30
1
0x40000000
BIT31
1
0x80000000
DEBUG_FUNC

Contains the function name if given compiler supports it.

1
""

Otherwise it is an empty string.

DEBUG( )

Print debug information to stdout.

1
if (ENABLE_DEBUG) DEBUG_PRINT(__VA_ARGS__)

Note

Another name for debug.h::DEBUG_PRINT

LOG_ERROR( )
1
LOG(LOG_ERROR, __VA_ARGS__)
LOG_WARNING( )
1
LOG(LOG_WARNING, __VA_ARGS__)
LOG_INFO( )
1
LOG(LOG_INFO, __VA_ARGS__)
LOG_DEBUG( )
1
LOG(LOG_DEBUG, __VA_ARGS__)
enum @0
LOG_NONE
Lowest log level, will output nothing.
LOG_ERROR
Error log level, will print only critical, non-recoverable errors like hardware initialization failures.
LOG_WARNING
Warning log level, will print warning messages for temporary errors.
LOG_INFO
Informational log level, will print purely informational messages like successful system bootup, network link state, …
LOG_DEBUG
Debug log level, printing developer stuff considered too verbose for production use.
LOG_ALL
print everything
enum core_panic_t
PANIC_GENERAL_ERROR
PANIC_SOFT_REBOOT
PANIC_HARD_REBOOT
PANIC_ASSERT_FAIL
PANIC_SSP
stack smashing protector failure
PANIC_UNDEFINED
be_uint16_t network_uint16_t

A 16 bit integer in network byte order.

be_uint32_t network_uint32_t

A 32 bit integer in network byte order.

be_uint64_t network_uint64_t

A 64 bit integer in network byte order.

list.h::list_node_t clist_node_t

List node structure.

Used as is as reference to a list.

int(* clist_cmp_func_t()

Typedef for comparison function used by clist.h::clist_sort()

int16_t kernel_pid_t

Unique process identifier.

struct list_node list_node_t

List node structure.

Used as is as reference to a list, or as member of any data structure that should be member of a list.

Actual list objects should have a list_node_t as member and then use the kernel_defines.h::container_of macro in list operations. See thread.h::thread_add_to_list() as example.

struct priority_queue_node priority_queue_node_t

data type for priority queue nodes

const char assert_crash_message()

the string that is passed to panic in case of a failing assertion

kernel_defines.h::NORETURN void _assert_failure(const char * file, unsigned line)

Function to handle failed assertion.

Note

This function was introduced for memory size optimization

Parameters

file:The file name of the file the assertion failed in
line:The code line of file the assertion failed in

unsigned bitarithm_msb(unsigned v)

Returns the number of the highest ‘1’ bit in a value.

Parameters

v:Input value
Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

Return values

  • Bit Number
unsigned bitarithm_lsb(unsigned v)

Returns the number of the lowest ‘1’ bit in a value.

Parameters

v:Input value - must be unequal to ‘0’, otherwise the function will produce an infinite loop

Return values

  • Bit Number
unsigned bitarithm_bits_set(unsigned v)

Returns the number of bits set in a value.

Parameters

v:Input value with platform-dependent word size

Return values

  • Number of set bits
uint8_t bitarithm_bits_set_u32(uint32_t v)

Returns the (uint32_t version) number of bits set in a value.

Parameters

v:Input value with 32 bit size

Return values

  • Number of set bits
be_uint16_t byteorder_ltobs(le_uint16_t v)

Convert from little endian to big endian, 16 bit.

Parameters

v:The integer in little endian.

Return values

  • v converted to big endian.
be_uint32_t byteorder_ltobl(le_uint32_t v)

Convert from little endian to big endian, 32 bit.

Parameters

v:The integer in little endian.

Return values

  • v converted to big endian.
be_uint64_t byteorder_ltobll(le_uint64_t v)

Convert from little endian to big endian, 64 bit.

Parameters

v:The integer in little endian.

Return values

  • v converted to big endian.
le_uint16_t byteorder_btols(be_uint16_t v)

Convert from big endian to little endian, 16 bit.

Parameters

v:The integer in big endian.

Return values

  • v converted to little endian.
le_uint32_t byteorder_btoll(be_uint32_t v)

Convert from big endian to little endian, 32 bit.

Parameters

v:The integer in big endian.

Return values

  • v converted to little endian.
le_uint64_t byteorder_btolll(be_uint64_t v)

Convert from big endian to little endian, 64 bit.

Parameters

v:The integer in big endian.

Return values

  • v converted to little endian.
byteorder.h::network_uint16_t byteorder_htons(uint16_t v)

Convert from host byte order to network byte order, 16 bit.

Parameters

v:The integer in host byte order.

Return values

  • v converted to network byte order.
byteorder.h::network_uint32_t byteorder_htonl(uint32_t v)

Convert from host byte order to network byte order, 32 bit.

Parameters

v:The integer in host byte order.

Return values

  • v converted to network byte order.
byteorder.h::network_uint64_t byteorder_htonll(uint64_t v)

Convert from host byte order to network byte order, 64 bit.

Parameters

v:The integer in host byte order.

Return values

  • v converted to network byte order.
uint16_t byteorder_ntohs(byteorder.h::network_uint16_t v)

Convert from network byte order to host byte order, 16 bit.

Parameters

v:The integer in network byte order.

Return values

  • v converted to host byte order.
uint32_t byteorder_ntohl(byteorder.h::network_uint32_t v)

Convert from network byte order to host byte order, 32 bit.

Parameters

v:The integer in network byte order.

Return values

  • v converted to host byte order.
uint64_t byteorder_ntohll(byteorder.h::network_uint64_t v)

Convert from network byte order to host byte order, 64 bit.

Parameters

v:The integer in network byte order.

Return values

  • v converted to host byte order.
uint16_t byteorder_swaps(uint16_t v)

Swap byte order, 16 bit.

Parameters

v:The integer to swap.

Return values

  • The swapped integer.
uint32_t byteorder_swapl(uint32_t v)

Swap byte order, 32 bit.

Parameters

v:The integer to swap.

Return values

  • The swapped integer.
uint64_t byteorder_swapll(uint64_t v)

Swap byte order, 64 bit.

Parameters

v:The integer to swap.

Return values

  • The swapped integer.
uint16_t byteorder_bebuftohs(const uint8_t * buf)

Read a big endian encoded unsigned integer from a buffer into host byte order encoded variable, 16-bit.

Note

This function is agnostic to the alignment of the target value in the given buffer

Parameters

buf:position in a buffer holding the target value

Return values

  • 16-bit unsigned integer in host byte order
void byteorder_htobebufs(uint8_t * buf, uint16_t val)

Write a host byte order encoded unsigned integer as big endian encoded value into a buffer, 16-bit.

Note

This function is alignment agnostic and works with any given memory location of the buffer

Parameters

buf:target buffer, must be able to accept 2 bytes
val:value written to the buffer, in host byte order

uint16_t htons(uint16_t v)

Convert from host byte order to network byte order, 16 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
uint32_t htonl(uint32_t v)

Convert from host byte order to network byte order, 32 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
uint64_t htonll(uint64_t v)

Convert from host byte order to network byte order, 64 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
uint16_t ntohs(uint16_t v)

Convert from network byte order to host byte order, 16 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
uint32_t ntohl(uint32_t v)

Convert from network byte order to host byte order, 32 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
uint64_t ntohll(uint64_t v)

Convert from network byte order to host byte order, 64 bit.

Parameters

v:The integer to convert.

Return values

  • Converted integer.
void cib_init(cib_t *__restrict cib, unsigned int size)

Initialize cib to 0 and set buffer size to size.

Parameters

cib:Buffer to initialize. Must not be NULL.
size:Size of the buffer, must not exceed MAXINT/2. Should be equal to 0 or power of 2.

unsigned int cib_avail(const cib_t * cib)

Calculates difference between cib.h::cib_put() and cib.h::cib_get() accesses.

Parameters

cib:the cib_t to check. Must not be NULL.

Return values

unsigned int cib_full(const cib_t * cib)

Check if cib is full.

Parameters

cib:the cib_t to check. Must not be NULL.

Return values

int cib_get(cib_t *__restrict cib)

Get the index of the next item in buffer.

Parameters

cib:corresponding cib to buffer. Must not be NULL.

Return values

  • index of next item, -1 if the buffer is empty
int cib_peek(cib_t *__restrict cib)

Get the index of the next item in buffer without removing it.

Parameters

cib:corresponding cib to buffer. Must not be NULL.

Return values

  • index of next item, -1 if the buffer is empty
int cib_get_unsafe(cib_t * cib)

Get the index of the next item in buffer.

Unsafe version, must not be called if buffer is empty!

Parameters

cib:corresponding cib to buffer. Must not be NULL.

Return values

  • index of next item
int cib_put(cib_t *__restrict cib)

Get index for item in buffer to put to.

Parameters

cib:corresponding cib to buffer. Must not be NULL.

Return values

  • index of item to put to, -1 if the buffer is full
int cib_put_unsafe(cib_t * cib)

Get index for item in buffer to put to.

Unsafe version, must not be called if buffer is full!

Parameters

cib:corresponding cib to buffer. Must not be NULL.

Return values

  • index of item to put to
void clist_rpush(clist.h::clist_node_t * list, clist.h::clist_node_t * new_node)

Appends new_node at the end of *list.

Note

Complexity: O(1)

Parameters

list:Pointer to clist
new_node:Node which gets inserted. Must not be NULL.

void clist_lpush(clist.h::clist_node_t * list, clist.h::clist_node_t * new_node)

Inserts new_node at the beginning of *list.

Note

Complexity: O(1)

Parameters

list:Pointer to clist
new_node:Node which gets inserted. Must not be NULL.

clist.h::clist_node_t * clist_lpop(clist.h::clist_node_t * list)

Removes and returns first element from list.

Note

Complexity: O(1)

Parameters

list:Pointer to the list to remove first element from.

void clist_lpoprpush(clist.h::clist_node_t * list)

Advances the circle list.

The result of this function is will be a list with nodes shifted by one. So second list entry will be first, first is last.

[ A, B, C ] becomes [ B, C, A ]

Note

Complexity: O(1)

Parameters

list:The list to work upon.

clist.h::clist_node_t * clist_lpeek(const clist.h::clist_node_t * list)

Returns first element in list.

Note

: Complexity: O(1)

Parameters

list:The list to work upon.

Return values

  • first (leftmost) list element, or NULL if list is empty
clist.h::clist_node_t * clist_rpeek(const clist.h::clist_node_t * list)

Returns last element in list.

Note

: Complexity: O(1)

Parameters

list:The list to work upon.

Return values

  • last (rightmost) list element, or NULL if list is empty
clist.h::clist_node_t * clist_rpop(clist.h::clist_node_t * list)

Removes and returns last element from list.

Note

Complexity: O(n) with n being the number of elements in the list.

Parameters

list:Pointer to the list to remove last element from.

clist.h::clist_node_t * clist_find_before(const clist.h::clist_node_t * list, const clist.h::clist_node_t * node)

Finds node and returns its predecessor.

Note

Complexity: O(n)

Parameters

list:pointer to clist
node:Node to look for Must not be NULL.

Return values

  • predecessor of node if found
  • NULL if node is not a list member
clist.h::clist_node_t * clist_find(const clist.h::clist_node_t * list, const clist.h::clist_node_t * node)

Finds and returns node.

Note

Complexity: O(n)

Parameters

list:pointer to clist
node:Node to look for Must not be NULL.

Return values

  • node if found
  • NULL if node is not a list member
clist.h::clist_node_t * clist_remove(clist.h::clist_node_t * list, clist.h::clist_node_t * node)

Finds and removes node.

Note

Complexity: O(n)

Parameters

list:pointer to clist
node:Node to remove for Must not be NULL.

Return values

  • node if found and removed
  • NULL if node is not a list member
clist.h::clist_node_t * clist_foreach(clist.h::clist_node_t * list, int(*)(clist.h::clist_node_t *, void *) func, void * arg)

Traverse clist, call function for each member.

The pointer supplied by arg will be passed to every call to func.

If func returns non-zero, traversal will be aborted like when calling break within a for loop, returning the corresponding node.

Parameters

list:List to traverse.
func:Function to call for each member.
arg:Pointer to pass to every call to func

Return values

  • NULL on empty list or full traversal
  • node that caused func(node, arg) to exit non-zero
clist.h::clist_node_t * _clist_sort(clist.h::clist_node_t * list_head, clist.h::clist_cmp_func_t cmp)

List sorting helper function.

void clist_sort(clist.h::clist_node_t * list, clist.h::clist_cmp_func_t cmp)

Sort a list.

This function will sort list using merge sort. The sorting algorithm runs in O(N log N) time. It is also stable.

Apart from the to-be-sorted list, the function needs a comparison function. That function will be called by the sorting implementation for every comparison. It gets two pointers a, b of type “clist_node_t” as parameters and must return <0, 0 or >0 if a is lesser, equal or larger than b.

Example:

Parameters

list:List to sort
cmp:Comparison function

int pid_is_valid(kernel_types.h::kernel_pid_t pid)

Determine if the given pid is valid.

Parameters

pid:The pid to check

Return values

  • true if the pid is valid, false otherwise
int lifo_empty(int * array)

Check if the given lifo is empty.

Parameters

array:The lifo array to check.

Return values

  • 1, if empty
  • 0, otherwise.
void lifo_init(int * array, int n)

Initialize a lifo array.

Parameters

array:An array of size n + 1. Must not be NULL.
n:Maximum integer value the lifo is able to store.

void lifo_insert(int * array, int i)

Insert an element into the lifo.

Parameters

array:An integer array of least i + 1 size that **does not already contain *i***. Must not be NULL.
i:The integer value to store, between 0 and the size of the array - 1, must not be stored already.

int lifo_get(int * array)

Extract the least recently inserted element from the lifo.

Parameters

array:An integer array. Must not be NULL.

Return values

  • -1, if the lifo is empty.
  • the least recently inserted element, otherwise.
void list_add(list.h::list_node_t * node, list.h::list_node_t * new_node)

Insert object into list.

If called with a list reference as node, the new node will become the new list head.

Parameters

node:list node before new entry
new_node:list node to insert

list.h::list_node_t * list_remove_head(list.h::list_node_t * list)

Removes the head of the list and returns it.

Parameters

list:Pointer to the list itself, where list->next points to the root node

Return values

  • removed old list head, or NULL if empty
list.h::list_node_t * list_remove(list.h::list_node_t * list, list.h::list_node_t * node)

Removes the node from the list.

Parameters

list:Pointer to the list itself, where list->next points to the root node
node:List node to remove from the list

Return values

  • removed node, or NULL if empty or not found
kernel_defines.h::NORETURN void core_panic(panic.h::core_panic_t crash_code, const char * message)

Handle an unrecoverable error by halting or rebooting the system.

A numeric code indicating the failure reason can be given as the crash_code parameter.

Detailing the failure is possible using the message parameter. This function should serve a similar purpose as the panic() function of Unix/Linux kernels.

If the DEVELHELP macro is defined, the system will be halted; the system will be rebooted otherwise.

Parameters

crash_code:a unique code for identifying the crash reason
message:a human readable reason for the crash

Return values

  • this function never returns
void panic_arch(void)

architecture dependent handling of a panic case

This function gives the CPU the possibility to execute architecture dependent code in case of a severe error.

void priority_queue_node_init(priority_queue.h::priority_queue_node_t * priority_queue_node)

Initialize a priority queue node object.

For initialization of variables use PRIORITY_QUEUE_NODE_INIT instead. Only use this function for dynamically allocated priority queue nodes.

Parameters

priority_queue_node:
 pre-allocated priority_queue_node_t object, must not be NULL.

void priority_queue_init(priority_queue_t * priority_queue)

Initialize a priority queue object.

For initialization of variables use PRIORITY_QUEUE_INIT instead. Only use this function for dynamically allocated priority queues.

Parameters

priority_queue:pre-allocated priority_queue_t object, must not be NULL.

priority_queue.h::priority_queue_node_t * priority_queue_remove_head(priority_queue_t * root)

remove the priority queue’s head

Parameters

root:the queue’s root

Return values

  • the old head
void priority_queue_add(priority_queue_t * root, priority_queue.h::priority_queue_node_t * new_obj)

insert new_obj into root based on its priority

The new object will be appended after objects with the same priority.

Parameters

root:the queue’s root
new_obj:the object to prepend

void priority_queue_remove(priority_queue_t * root, priority_queue.h::priority_queue_node_t * node)

remove node from root

Parameters

root:the priority queue’s root
node:the node to remove

void priority_queue_print(priority_queue_t * root)

print the data and priority of every node in the given priority queue

Note

requires nhdp.h::ENABLE_DEBUG to be set to 1 for this file

void priority_queue_print_node(priority_queue_t * root)

print the data, priority, and successor of a given node

Note

requires nhdp.h::ENABLE_DEBUG to be set to 1 for this file

DEBUG_ASSERT_VERBOSE

Activate verbose output for assert.h::assert when defined.

Without this macro defined the assert.h::assert macro will just print the address of the code line the assertion failed in. With the macro defined the macro will also print the file, the code line and the function this macro failed in.

To define just add it to your CFLAGS in your application’s Makefile:

1
CFLAGS += -DDEBUG_ASSERT_VERBOSE

assert( cond)

abort the program if assertion is false

1
((cond) ? (void)0 :  _assert_failure(RIOT_FILE_RELATIVE, __LINE__))

If the macro NDEBUG was defined at the moment <assert.h> was last included, the macro assert.h::assert generates no code, and hence does nothing at all.

Otherwise, the macro assert.h::assert prints an error message to standard error and terminates the application by calling panic.h::core_panic().

The purpose of this macro is to help programmers find bugs in their programs.

With assert.h::DEBUG_ASSERT_VERBOSE defined this will print also the file, the line and the function this assertion failed in.

If NDEBUG and assert.h::DEBUG_ASSERT_VERBOSE are not defined, a failed assertion generates output similar to:

Where 0x89abcdef is an address. This address can be used with tools like addr2line (or e.g. arm-none-eabi-addr2line for ARM-based code), objdump, or gdb (with the command info line *(0x89abcdef)) to identify the line the assertion failed in.

static_assert( cond, )

static_assert for c-version < c11

1
enum { static_assert_failed_on_div_by_0 = 1 / (!!(cond)) }

Generates a division by zero compile error when cond is false

SETBIT( val, bit)

Sets a bitmask for a bitfield.

1
val |= (bit)

Parameters

val:The bitfield
bit:Specifies the bits to be set

Return values

  • The modified bitfield
CLRBIT( val, bit)

Clears bitmask for a bitfield.

1
val &= (~(bit))

Parameters

val:The bitfield
bit:Specifies the bits to be cleared

Return values

  • The modified bitfield
ARCH_32_BIT

1 for 32 bit architectures, 0 otherwise

1
(__INT_MAX__ == 2147483647)
_byteorder_swap( V, T)

Swaps the byteorder according to the endianess.

1
(byteorder_swap##T((V)))
CIB_INIT( SIZE)

Initialize cib_t to a given size.

1
{ 0, 0, (SIZE) - 1 }
DEBUG_PRINT( )

Print debug information if the calling thread stack is large enough.

1
2
3
4
5
6
7
8
do { \
        if ((sched_active_thread == NULL) || (sched_active_thread->stack_size >= THREAD_EXTRA_STACKSIZE_PRINTF)) { \
            printf(__VA_ARGS__); \
        } \
        else { \
            puts("Cannot debug, stack too small"); \
        } \
    } while (0)

Use this macro the same as printf. When DEVELHELP is defined inside an implementation file, all usages of debug.h::DEBUG_PRINT will print the given information to stdout after verifying the stack is big enough. If DEVELHELP is not set, this check is not performed. (CPU exception may occur)

DEBUG_EXTRA_STACKSIZE

Extra stacksize needed when ENABLE_DEBUG==1.

1
THREAD_EXTRA_STACKSIZE_PRINTF
SSIZE_MAX

Maximum value for ssize_t.

1
((ssize_t) (SIZE_MAX / 2))
MAXTHREADS

The maximum number of threads to be scheduled.

1
32
KERNEL_PID_UNDEF

Canonical identifier for an invalid PID.

1
0
KERNEL_PID_FIRST

The first valid PID (inclusive).

1
(KERNEL_PID_UNDEF + 1)
KERNEL_PID_LAST

The last valid PID (inclusive).

1
(KERNEL_PID_FIRST + MAXTHREADS - 1)
PRIkernel_pid

Macro for printing formatter.

1
PRIi16
LOG_LEVEL

Default log level define.

1
LOG_INFO
LOG( level, )

Log message if level <= LOG_LEVEL.

1
2
do { \
    if ((level) <= LOG_LEVEL) log_write((level), __VA_ARGS__); } while (0U)
log_write( level, )

Default log_write function, just maps to printf.

1
printf(__VA_ARGS__)
PRIORITY_QUEUE_NODE_INIT

Static initializer for priority_queue_node_t.

1
{ NULL, 0, 0 }
PRIORITY_QUEUE_INIT

Static initializer for priority_queue_t.

1
{ NULL }
union le_uint16_t

A 16 bit integer in little endian.

This is a wrapper around an uint16_t to catch missing conversions between different byte orders at compile time.

union le_uint32_t

A 32 bit integer in little endian.

This is a wrapper around an uint32_t to catch missing conversions between different byte orders at compile time.

union le_uint64_t

A 64 bit integer in little endian.

This is a wrapper around an uint64_t to catch missing conversions between different byte orders at compile time.

union be_uint16_t

A 16 bit integer in big endian aka network byte order.

This is a wrapper around an uint16_t to catch missing conversions between different byte orders at compile time.

union be_uint32_t

A 32 bit integer in big endian aka network byte order.

This is a wrapper around an uint32_t to catch missing conversions between different byte orders at compile time.

union be_uint64_t

A 64 bit integer in big endian aka network byte order.

This is a wrapper around an uint64_t to catch missing conversions between different byte orders at compile time.

struct cib_t

circular integer buffer structure

unsigned int read_count

number of (successful) read accesses

unsigned int write_count

number of (successful) write accesses

unsigned int mask

Size of buffer -1, i.e.

mask of the bits

struct list_node

List node structure.

Used as is as reference to a list, or as member of any data structure that should be member of a list.

Actual list objects should have a list_node_t as member and then use the kernel_defines.h::container_of macro in list operations. See thread.h::thread_add_to_list() as example.

struct list_node * next

pointer to next list entry

struct priority_queue_node

data type for priority queue nodes

struct priority_queue_node * next

next queue node

uint32_t priority

queue node priority

unsigned int data

queue node data

struct priority_queue_t

data type for priority queues

priority_queue.h::priority_queue_node_t * first

first queue node