Nanokernel APIs

Fibers

nano_thread_id_t fiber_start(char *stack, unsigned stack_size, nano_fiber_entry_t entry, int arg1, int arg2, unsigned prio, unsigned options)

Initialize and start a fiber.

This routine initializes and starts a fiber. It can be called from either a fiber or a task. When this routine is called from a task, the newly created fiber will start executing immediately.

Return
nanokernel thread identifier
Parameters
  • stack: Pointer to the stack space.
  • stack_size: Stack size in bytes.
  • entry: Fiber entry.
  • arg1: 1st entry point parameter.
  • arg2: 2nd entry point parameter.
  • prio: The fiber’s priority.
  • options: Not used currently.

nano_thread_id_t fiber_fiber_start(char *pStack, unsigned int stackSize, nano_fiber_entry_t entry, int arg1, int arg2, unsigned prio, unsigned options)

Initialize and start a fiber from a fiber.

This routine initializes and starts a fiber. It can only be called from a fiber.

Return
nanokernel thread identifier
Parameters
  • pStack: Pointer to the stack space.
  • stackSize: Stack size in bytes.
  • entry: Fiber entry.
  • arg1: 1st entry point parameter.
  • arg2: 2nd entry point parameter.
  • prio: The fiber’s priority.
  • options: Not used currently.

void fiber_yield(void)

Yield the current fiber.

Calling this routine results in the current fiber yielding to another fiber of the same or higher priority. If there are no other runnable fibers of the same or higher priority, the routine will return immediately.

This routine can only be called from a fiber.

Return
N/A

void fiber_abort(void)

Abort the currently executing fiber.

This routine aborts the currently executing fiber. An abort can occur because of one of three reasons:

  • The fiber has explicitly aborted itself by calling this routine.
  • The fiber has implicitly aborted itself by returning from its entry point.
  • The fiber has encountered a fatal exception.

This routine can only be called from a fiber.

Return
N/A

static nano_thread_id_t fiber_fiber_start_config(const struct fiber_config *config, nano_fiber_entry_t entry, int arg1, int arg2, unsigned options)

Start a fiber based on a fiber_config, from fiber context.

static nano_thread_id_t fiber_start_config(const struct fiber_config *config, nano_fiber_entry_t entry, int arg1, int arg2, unsigned options)

Start a fiber based on a fiber_config.

This routine can be called from either a fiber or a task.

void fiber_sleep(int32_t timeout_in_ticks)

Put the current fiber to sleep.

This routine puts the currently running fiber to sleep for the number of system ticks passed in the timeout_in_ticks parameter.

Return
N/A
Parameters
  • timeout_in_ticks: Number of system ticks the fiber sleeps.

void isr_fiber_wakeup(nano_thread_id_t fiber)

Wake the specified fiber from sleep.

This routine wakes the fiber specified by fiber from its sleep. It may only be called from an ISR.

Return
N/A
Parameters
  • fiber: Identifies fiber to wake

void fiber_fiber_wakeup(nano_thread_id_t fiber)

Wake the specified fiber from sleep.

This routine wakes the fiber specified by fiber from its sleep. It may only be called from a fiber.

Return
N/A
Parameters
  • fiber: Identifies fiber to wake

void task_fiber_wakeup(nano_thread_id_t fiber)

Wake the specified fiber from sleep.

This routine wakes the fiber specified by fiber from its sleep. It may only be called from a task.

Return
N/A
Parameters
  • fiber: Identifies fiber to wake

void fiber_wakeup(nano_thread_id_t fiber)

Wake the specified fiber from sleep.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • fiber: Identifies fiber to wake

void task_sleep(int32_t timeout_in_ticks)

Put the task to sleep.

This routine puts the currently running task to sleep for the number of system ticks passed in the timeout_in_ticks parameter.

Warning
A value of TICKS_UNLIMITED is considered invalid and may result in unexpected behavior.
Return
N/A
See
TICKS_UNLIMITED
Parameters
  • timeout_in_ticks: Number of system ticks the task sleeps.

nano_thread_id_t fiber_fiber_delayed_start(char *stack, unsigned int stack_size_in_bytes, nano_fiber_entry_t entry_point, int param1, int param2, unsigned int priority, unsigned int options, int32_t timeout_in_ticks)

Start a fiber while delaying its execution.

This routine can only be called from a fiber.

Return
A handle potentially used to cancel the delayed start.
Parameters
  • stack: Pointer to the stack space.
  • stack_size_in_bytes: Stack size in bytes.
  • entry_point: The fiber’s entry point.
  • param1: 1st entry point parameter.
  • param2: 2nd entry point parameter.
  • priority: The fiber’s priority.
  • options: Not used currently.
  • timeout_in_ticks: Timeout duration in ticks.

nano_thread_id_t fiber_delayed_start(char *stack, unsigned int stack_size_in_bytes, nano_fiber_entry_t entry_point, int param1, int param2, unsigned int priority, unsigned int options, int32_t timeout_in_ticks)
void fiber_delayed_start_cancel(nano_thread_id_t handle)
void fiber_fiber_delayed_start_cancel(nano_thread_id_t handle)

Cancel a delayed fiber start.

Return
N/A
See
fiber_fiber_delayed_start
Parameters
  • handle: The handle returned when starting the delayed fiber.

struct fiber_config
#include <nanokernel.h>

Fiber configuration structure.

Parameters such as stack size and fiber priority are often user configurable. This structure makes it simple to specify such a configuration.

Tasks

nano_thread_id_t task_fiber_start(char *pStack, unsigned int stackSize, nano_fiber_entry_t entry, int arg1, int arg2, unsigned prio, unsigned options)

Initialize and start a fiber from a task.

See
fiber_fiber_start

static nano_thread_id_t task_fiber_start_config(const struct fiber_config *config, nano_fiber_entry_t entry, int arg1, int arg2, unsigned options)

Start a fiber based on a fiber_config, from task context.

nano_thread_id_t task_fiber_delayed_start(char *stack, unsigned int stack_size_in_bytes, nano_fiber_entry_t entry_point, int param1, int param2, unsigned int priority, unsigned int options, int32_t timeout_in_ticks)

Start a fiber from a task while delaying its execution.

See
fiber_fiber_delayed_start

void task_fiber_delayed_start_cancel(nano_thread_id_t handle)

Cancel a delayed fiber start from a task.

See
fiber_fiber_delayed_start_cancel

Semaphores

void nano_sem_init(struct nano_sem *sem)

Initialize a nanokernel semaphore object.

This function initializes a nanokernel semaphore object structure. After initialization, the semaphore count is 0.

It can be called from either a fiber or task.

Return
N/A
Parameters
  • sem: Pointer to a nano_sem structure.

void nano_sem_give(struct nano_sem *sem)

Give a nanokernel semaphore.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • sem: Pointer to a nano_sem structure.

int nano_sem_take(struct nano_sem *sem, int32_t timeout_in_ticks)

Take a nanokernel semaphore, poll/pend if not available.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Warning
If it is to be called from the context of an ISR, then timeout_in_ticks must be set to TICKS_NONE.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • sem: Pointer to a nano_sem structure.
  • timeout_in_ticks: Determines the action to take when the semaphore is unavailable. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: When semaphore is available
  • 0: Otherwise

void nano_isr_sem_give(struct nano_sem *sem)

Give a nanokernel semaphore (no context switch).

This routine performs a “give” operation on a nanokernel semaphore object; it can only be called from an ISR context. A fiber pending on the semaphore object will be made ready, but will NOT be scheduled to execute.

Return
N/A
Parameters
  • sem: Pointer to a nano_sem structure.

int nano_isr_sem_take(struct nano_sem *sem, int32_t timeout_in_ticks)

Take a nanokernel semaphore, fail if unavailable.

Attempts to take a nanokernel semaphore. It can only be called from a ISR context.

If the semaphore is not available, this function returns immediately, i.e. a wait (pend) operation will NOT be performed.

Parameters
  • sem: Pointer to a nano_sem structure.
  • timeout_in_ticks: Always use TICKS_NONE.
Return Value
  • 1: When semaphore is available
  • 0: Otherwise

void nano_fiber_sem_give(struct nano_sem *sem)

Give a nanokernel semaphore (no context switch).

This routine performs a “give” operation on a nanokernel semaphore object; it can only be called from a fiber. A fiber pending on the semaphore object will be made ready, but will NOT be scheduled to execute.

Return
N/A
Parameters
  • sem: Pointer to a nano_sem structure.

int nano_fiber_sem_take(struct nano_sem *sem, int32_t timeout_in_ticks)

Take a nanokernel semaphore, wait or fail if unavailable.

Attempts to take a nanokernel semaphore. It can only be called from a fiber.

Parameters
  • sem: Pointer to a nano_sem structure.
  • timeout_in_ticks: Determines the action to take when the semaphore is unavailable. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: When semaphore is available.
  • 0: Otherwise.

void nano_task_sem_give(struct nano_sem *sem)

Give a nanokernel semaphore.

This routine performs a “give” operation on a nanokernel semaphore object; it can only be called from a task. A fiber pending on the semaphore object will be made ready, and will preempt the running task immediately.

Return
N/A
Parameters
  • sem: Pointer to a nano_sem structure.

int nano_task_sem_take(struct nano_sem *sem, int32_t timeout_in_ticks)

Take a nanokernel semaphore, fail if unavailable.

Attempts to take a nanokernel semaphore; it can only be called from a task.

See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • sem: Pointer to a nano_sem structure.
  • timeout_in_ticks: Determines the action to take when the semaphore is unavailable. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: when the semaphore is available.
  • 0: Otherwise.

LIFOs

void nano_lifo_init(struct nano_lifo *lifo)

Initialize a nanokernel linked list LIFO (lifo) object.

This function initializes a nanokernel system-level linked list LIFO (lifo) object structure.

It is called from either a fiber or task.

Return
N/A
Parameters
  • lifo: LIFO to initialize.

void nano_lifo_put(struct nano_lifo *lifo, void *data)

Prepend an element to a LIFO.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • lifo: LIFO on which to put.
  • data: Data to insert.

void *nano_lifo_get(struct nano_lifo *lifo, int32_t timeout_in_ticks)

Get the first element from a LIFO.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Warning
If it is to be called from the context of an ISR, then timeout_in_ticks must be set to TICKS_NONE.
Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • lifo: LIFO on which to receive.
  • timeout_in_ticks: Affects the action taken should the LIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then wait as long as necesssary. Otherwise wait up to the specified number of ticks before timing out.

void nano_isr_lifo_put(struct nano_lifo *lifo, void *data)

Prepend an element to a LIFO without a context switch.

This routine adds an element to the LIFOs’ object head; it may be called from an ISR context. A fiber pending on the LIFO object will be made ready, but will NOT be scheduled to execute.

Return
N/A
Parameters
  • lifo: LIFO on which to put.
  • data: Data to insert.

void *nano_isr_lifo_get(struct nano_lifo *lifo, int32_t timeout_in_ticks)

Remove the first element from a LIFO linked list.

Removes the first element from the specified nanokernel LIFO linked list; it can only be called from an ISR context.

If no elements are available, NULL is returned. The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
Parameters
  • lifo: LIFO from which to receive.
  • timeout_in_ticks: Always use TICKS_NONE.

void nano_fiber_lifo_put(struct nano_lifo *lifo, void *data)

Prepend an element to a LIFO without a context switch.

This routine adds an element to the LIFOs’ object head; it can only be called from a fiber. A fiber pending on the LIFO object will be made ready, but will NOT be scheduled to execute.

Return
N/A
Parameters
  • lifo: LIFO from which to put.
  • data: Data to insert.

void *nano_fiber_lifo_get(struct nano_lifo *lifo, int32_t timeout_in_ticks)

Remove the first element from a LIFO linked list.

Removes the first element from the specified nanokernel LIFO linked list; it can only be called from a fiber.

If no elements are available, NULL is returned. The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • lifo: LIFO from which to receive.
  • timeout_in_ticks: Affects the action taken should the LIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then wait as long as necessary. Otherwise wait up to the specified number of ticks before timing out.

void nano_task_lifo_put(struct nano_lifo *lifo, void *data)

Add an element to the LIFO’s linked list head.

This routine adds an element to the head of a LIFO object; it can only be called only from a task. A fiber pending on the LIFO object will be made ready and will preempt the running task immediately.

This API can only be called by a task.

Return
N/A
Parameters
  • lifo: LIFO from which to put.
  • data: Data to insert.

void *nano_task_lifo_get(struct nano_lifo *lifo, int32_t timeout_in_ticks)

Remove the first element from a LIFO linked list.

Removes the first element from the specified nanokernel LIFO linked list; it can only be called from a task.

If no elements are available, NULL is returned. The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • lifo: LIFO from which to receive.
  • timeout_in_ticks: Affects the action taken should the LIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then wait as long as necessary. Otherwise wait up to the specified number of ticks before timing out.

FIFOs

void nano_fifo_init(struct nano_fifo *fifo)

Initialize a nanokernel FIFO (fifo) object.

This function initializes a nanokernel FIFO (fifo) object structure.

It can be called from either a fiber or task.

Return
N/A
Parameters
  • fifo: FIFO to initialize.

void nano_fifo_put(struct nano_fifo *fifo, void *data)

Add an element to the end of a FIFO.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • fifo: FIFO on which to interact.
  • data: Data to send.

void nano_fifo_put_list(struct nano_fifo *fifo, void *head, void *tail)

Atomically add a list of elements to the end of a FIFO.

This routine adds a list of elements in one shot to the end of a FIFO object. If fibers are pending on the FIFO object, they become ready to run. If this API is called from a task, the highest priority one will preempt the running task once the put operation is complete.

If enough fibers are waiting on the FIFO, the address of each element given to fibers is returned to the waiting fiber. The remaining elements are linked to the end of the list.

The list must be a singly-linked list, where each element only has a pointer to the next one. The list must be NULL-terminated.

Unlike the fiber/ISR versions of this API which is not much different conceptually than calling nano_fifo_put once for each element to queue, the behaviour is indeed different for tasks. There is no context switch being done for each element queued, so the task can enqueue all elements without being interrupted by a fiber being woken up.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
See
nano_fifo_put_slist, nano_isr_fifo_put_list, nano_fiber_fifo_put_list, nano_task_fifo_put_list
Parameters
  • fifo: FIFO on which to interact.
  • head: head of singly-linked list
  • tail: tail of singly-linked list

void nano_fifo_put_slist(struct nano_fifo *fifo, sys_slist_t *list)

Atomically add a list of elements to the end of a FIFO.

See nano_fifo_put_list for the description of the behaviour.

It takes a pointer to a sys_slist_t object instead of the head and tail of a custom singly-linked list. The sys_slist_t object is invalid afterwards and must be re-initialized via sys_slist_init().

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
See
nano_fifo_put_list, nano_isr_fifo_put_slist, nano_fiber_fifo_put_slist, nano_task_fifo_put_slist
Parameters
  • fifo: FIFO on which to interact.
  • list: pointer to singly-linked list

void *nano_fifo_get(struct nano_fifo *fifo, int32_t timeout_in_ticks)

Get an element from the head a FIFO.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

If no element is available, the function returns NULL. The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Warning
If it is to be called from the context of an ISR, then timeout_in_ticks must be set to TICKS_NONE.
Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • fifo: FIFO on which to interact.
  • timeout_in_ticks: Affects the action taken should the FIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.

void nano_isr_fifo_put(struct nano_fifo *fifo, void *data)

Add an element to the end of a FIFO from an ISR context.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
Parameters
  • fifo: FIFO on which to interact.
  • data: Data to send.

void nano_isr_fifo_put_list(struct nano_fifo *fifo, void *head, void *tail)

Atomically add a list of elements to the end of a FIFO from an ISR.

See nano_fifo_put_list for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_list
Parameters
  • fifo: FIFO on which to interact.
  • head: head of singly-linked list
  • tail: tail of singly-linked list

void nano_isr_fifo_put_slist(struct nano_fifo *fifo, sys_slist_t *list)

Atomically add a list of elements to the end of a FIFO from an ISR.

See nano_fifo_put_slist for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_slist
Parameters
  • fifo: FIFO on which to interact.
  • list: pointer to singly-linked list

void *nano_isr_fifo_get(struct nano_fifo *fifo, int32_t timeout_in_ticks)

Get an element from the head of a FIFO from an ISR context.

Remove the head element from the specified nanokernel FIFO linked list FIFO. It can only be called from an ISR context.

The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
Parameters
  • fifo: FIFO on which to interact.
  • timeout_in_ticks: Always use TICKS_NONE.

void nano_fiber_fifo_put(struct nano_fifo *fifo, void *data)

Add an element to the end of a FIFO from a fiber.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
Parameters
  • fifo: FIFO on which to interact.
  • data: Data to send.

void nano_fiber_fifo_put_list(struct nano_fifo *fifo, void *head, void *tail)

Atomically add a list of elements to the end of a FIFO from a fiber.

See nano_fifo_put_list for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_list
Parameters
  • fifo: FIFO on which to interact.
  • head: head of singly-linked list
  • tail: tail of singly-linked list

void nano_fiber_fifo_put_slist(struct nano_fifo *fifo, sys_slist_t *list)

Atomically add a list of elements to the end of a FIFO from a fiber.

See nano_fifo_put_slist for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_slist
Parameters
  • fifo: FIFO on which to interact.
  • list: pointer to singly-linked list

void *nano_fiber_fifo_get(struct nano_fifo *fifo, int32_t timeout_in_ticks)

Get an element from the head of a FIFO from a fiber.

Remove the head element from the specified nanokernel FIFO linked list. It can only be called from a fiber.

The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • fifo: FIFO on which to interact.
  • timeout_in_ticks: Affects the action taken should the FIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.

void nano_task_fifo_put(struct nano_fifo *fifo, void *data)

Add an element to the end of a FIFO.

This routine adds an element to the end of a FIFO object. It can only be called from a task. If a fiber is pending on the FIFO object, it becomes ready and will preempt the running task immediately.

If a fiber is waiting on the FIFO, the address of the element is returned to the waiting fiber. Otherwise, the element is linked to the end of the list.

Return
N/A
Parameters
  • fifo: FIFO on which to interact.
  • data: Data to send.

void nano_task_fifo_put_list(struct nano_fifo *fifo, void *head, void *tail)

Atomically add a list of elements to the end of a FIFO from a fiber.

See nano_fifo_put_list for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_list
Parameters
  • fifo: FIFO on which to interact.
  • head: head of singly-linked list
  • tail: tail of singly-linked list

void nano_task_fifo_put_slist(struct nano_fifo *fifo, sys_slist_t *list)

Atomically add a list of elements to the end of a FIFO from a fiber.

See nano_fifo_put_slist for the description of the behaviour.

This is an alias for the execution context-specific API. This is helpful whenever the exact execution context is known. Its use avoids unnecessary overhead.

Return
N/A
See
nano_fifo_put_slist
Parameters
  • fifo: FIFO on which to interact.
  • list: pointer to singly-linked list

void *nano_task_fifo_get(struct nano_fifo *fifo, int32_t timeout_in_ticks)

Get an element from a FIFO’s head that comes from a task, poll if empty.

Removes the head element from the specified nanokernel FIFO linked list. It can only be called from a task.

The first word in the element contains invalid data because its memory location was used to store a pointer to the next element in the linked list.

Return
Pointer to head element in the list when available. NULL Otherwise.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • fifo: FIFO on which to interact.
  • timeout_in_ticks: Affects the action taken should the FIFO be empty. If TICKS_NONE, then return immediately. If TICKS_UNLIMITED, then poll as long as necessary. Otherwise poll up to the specified number of ticks have elapsed before timing out.

Ring Buffers

static void sys_ring_buf_init(struct ring_buf *buf, uint32_t size, uint32_t *data)

Initialize a ring buffer, in cases where DECLARE_RING_BUF_STATIC isn’t used.

For optimal performance, use size values that are a power of 2 as they don’t require expensive modulo operations when maintaining the buffer.

Parameters
  • buf: Ring buffer to initialize
  • size: Size of the provided buffer in 32-bit chunks
  • data: Data area for the ring buffer, typically uint32_t data[size]

static int sys_ring_buf_is_empty(struct ring_buf *buf)

Determine if a ring buffer is empty.

Return
nonzero if the buffer is empty

static int sys_ring_buf_space_get(struct ring_buf *buf)

Obtain available space in a ring buffer.

Return
Available space in the buffer in 32-bit chunks
Parameters
  • buf: Ring buffer to examine

int sys_ring_buf_put(struct ring_buf *buf, uint16_t type, uint8_t value, uint32_t *data, uint8_t size32)

Place an entry into the ring buffer.

Concurrency control is not implemented, however no synchronization is needed between put() and get() operations as they independently work on the tail and head values, respectively. Any use-cases involving multiple producers will need to synchronize use of this function, by either disabling preemption or using a mutex.

Return
0 on success, -ENOSPC if there isn’t sufficient space
Parameters
  • buf: Ring buffer to insert data to
  • type: Application-specific type identifier
  • value: Integral data to include, application specific
  • data: Pointer to a buffer containing data to enqueue
  • size32: Size of data buffer, in 32-bit chunks (not bytes)

int sys_ring_buf_get(struct ring_buf *buf, uint16_t *type, uint8_t *value, uint32_t *data, uint8_t *size32)

Fetch data from the ring buffer.

Return
0 on success, -EAGAIN if the ring buffer is empty, -EMSGSIZE if the supplied buffer is too small (size32 will be updated with the actual size needed)
Parameters
  • buf: Ring buffer to extract data from
  • type: Return storage of the retrieved event type
  • value: Return storage of the data value
  • data: Buffer to copy data into
  • size32: Indicates the size of the data buffer. On return, updated with the actual amount of 32-bit chunks written to the buffer

SIZE32_OF(x) (sizeof((x))/sizeof(uint32_t))
SYS_RING_BUF_DECLARE_POW2(name, pow) static uint32_t _ring_buffer_data_##name[1 << (pow)]; \ struct ring_buf name = { \ .size = (1 << (pow)), \ .mask = (1 << (pow)) - 1, \ .buf = _ring_buffer_data_##name \ };

Declare a power-of-two sized ring buffer.

Use of this macro is preferred over SYS_RING_BUF_DECLARE_SIZE() as it will not need to use expensive modulo operations.

Parameters
  • name: File-scoped name of the ring buffer to declare
  • pow: Create a buffer of 2^pow 32-bit elements

SYS_RING_BUF_DECLARE_SIZE(name, size32) static uint32_t _ring_buffer_data_##name[size32]; \ struct ring_buf name = { \ .size = size32, \ .buf = _ring_buffer_data_##name \ };

Declare an arbitrary sized ring buffer.

A ring buffer declared in this way has more flexibility on buffer size but will use more expensive modulo operations to maintain itself.

Parameters
  • name: File-scoped name of the ring buffer to declare
  • size32: Size of buffer in 32-bit elements

struct ring_buf
#include <ring_buffer.h>

A structure to represent a ring buffer.

Stacks

void nano_stack_init(struct nano_stack *stack, uint32_t *data)

Initialize a nanokernel stack object.

This function initializes a nanokernel stack object structure.

It is called from either a fiber or a task.

Return
N/A

void nano_stack_push(struct nano_stack *stack, uint32_t data)

Push data onto a stack.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • stack: Stack on which to interact.
  • data: Data to push on stack.

int nano_stack_pop(struct nano_stack *stack, uint32_t *data, int32_t timeout_in_ticks)

Pop data from a nanokernel stack.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Warning
If called from the context of an ISR, then timeout_in_ticks must be TICKS_NONE.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • stack: Stack on which to interact.
  • data: Container for data to pop.
  • timeout_in_ticks: Determines the action to take when the FIFO is empty. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: When data is popped from the stack.
  • 0: Otherwise.

void nano_isr_stack_push(struct nano_stack *stack, uint32_t data)

Push data onto a stack (no context switch).

This routine pushes a data item onto a stack object. It can only be called from an ISR context. A fiber that pends on the stack object becomes ready but will NOT be scheduled to execute.

Return
N/A
Parameters
  • stack: Stack on which to interact.
  • data: Data to push on stack.

int nano_isr_stack_pop(struct nano_stack *stack, uint32_t *data, int32_t timeout_in_ticks)

Pop data from a nanokernel stack.

Pops the first data word from a nanokernel stack object. It can only be called from an ISR context.

When the stack is not empty, a data word is popped and copied to the provided address data and a non-zero value is returned. When the routine finds an empty stack, zero is returned.

Parameters
  • stack: Stack on which to interact.
  • data: Container for data to pop.
  • timeout_in_ticks: Must be TICKS_NONE.
Return Value
  • 1: When data is popped from the stack
  • 0: Otherwise.

void nano_fiber_stack_push(struct nano_stack *stack, uint32_t data)

Push data onto a stack (no context switch).

This routine pushes a data item onto a stack object. It can only be called from a fiber context. A fiber that pends on the stack object becomes ready but will NOT be scheduled to execute.

Return
N/A
Parameters
  • stack: Stack on which to interact.
  • data: Data to push on stack.

int nano_fiber_stack_pop(struct nano_stack *stack, uint32_t *data, int32_t timeout_in_ticks)

Pop data from a nanokernel stack.

Pops the first data word from a nanokernel stack object. It can only be called from a fiber context.

When the stack is not empty, a data word is popped and copied to the provided address data and a non-zero value is returned. When the routine finds an empty stack, zero is returned.

See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • stack: Stack on which to interact.
  • data: Container for data to pop.
  • timeout_in_ticks: Determines the action to take when the FIFO is empty. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: When data is popped from the stack
  • 0: Otherwise.

void nano_task_stack_push(struct nano_stack *stack, uint32_t data)

Push data onto a nanokernel stack.

This routine pushes a data item onto a stack object. It can only be called from a task. A fiber that pends on the stack object becomes ready and preempts the running task immediately.

Return
N/A
Parameters
  • stack: Stack on which to interact.
  • data: Data to push on stack.

int nano_task_stack_pop(struct nano_stack *stack, uint32_t *data, int32_t timeout_in_ticks)

Pop data from a nanokernel stack.

Pops the first data word from a nanokernel stack object. It can only be called from a task context.

When the stack is not empty, a data word is popped and copied to the provided address data and a non-zero value is returned. When the routine finds an empty stack, zero is returned.

See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • stack: Stack on which to interact.
  • data: Container for data to pop.
  • timeout_in_ticks: Determines the action to take when the FIFO is empty. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary. Otherwise, wait up to the specified number of ticks before timing out.
Return Value
  • 1: When data is popped from the stack
  • 0: Otherwise.

Timers

void nano_timer_init(struct nano_timer *timer, void *data)

Initialize a nanokernel timer object.

This function initializes a nanokernel timer object structure.

It can be called from either a fiber or task.

The data passed to this function is a pointer to a data structure defined by the user. It contains data that the user wishes to store when initializing the timer and recover when the timer expires. However, the first field of this data structure must be a pointer reserved for the API’s use that can be overwritten by the API and, as such, should not contain user data.

Return
N/A
Parameters
  • timer: Timer.
  • data: User Data.

void nano_timer_start(struct nano_timer *timer, int ticks)

Start a nanokernel timer.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Parameters
  • timer: Timer.
  • ticks: Number of ticks.

void *nano_timer_test(struct nano_timer *timer, int32_t timeout_in_ticks)

Wait for a nanokernel timer to expire.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
N/A
Warning
If called from an ISR, then timeout_in_ticks must be TICKS_NONE.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • timer: Timer.
  • timeout_in_ticks: Determines the action to take when the timer has not expired. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary.

void nano_timer_stop(struct nano_timer *timer)

Stop a nanokernel timer.

This routine is a convenience wrapper for the execution of context-specific APIs. It is helpful when the exact execution context is not known. However, it should be avoided when the context is known up-front to avoid unnecessary overhead.

Return
pointer to timer initialization data.
Parameters
  • timer: Timer to stop.

void nano_isr_timer_start(struct nano_timer *timer, int ticks)

Start a nanokernel timer from an ISR.

This function starts a previously initialized nanokernel timer object. The timer will expire in ticks system clock ticks.

Return
N/A
Parameters
  • timer: Timer.
  • ticks: Number of ticks.

void *nano_isr_timer_test(struct nano_timer *timer, int32_t timeout_in_ticks)

Make the current ISR check for a timer expiry.

This function checks if a previously started nanokernel timer object has expired.

Return
Pointer to timer initialization data.
Parameters
  • timer: Timer to check.
  • timeout_in_ticks: Always use TICKS_NONE.
Return Value
  • NULL: If timer not expired.

void nano_isr_timer_stop(struct nano_timer *timer)

Stop a nanokernel timer from an ISR.

This function stops a previously started nanokernel timer object.

Return
N/A
Parameters
  • timer: Timer to stop.

void nano_fiber_timer_start(struct nano_timer *timer, int ticks)

Start a nanokernel timer from a fiber.

This function starts a previously-initialized nanokernel timer object. The timer expires after ticks system clock ticks.

Return
N/A
Parameters
  • timer: Timer.
  • ticks: Number of ticks.

void *nano_fiber_timer_test(struct nano_timer *timer, int32_t timeout_in_ticks)

Make the current fiber check for a timer expiry.

This function tests whether or not a previously started nanokernel timer object has expired, or waits until it does.

Return
Pointer to timer initialization data
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • timer: Timer to check.
  • timeout_in_ticks: Determines the action to take when the timer has not expired. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary.
Return Value
  • NULL: If timer has not expired.

void nano_fiber_timer_stop(struct nano_timer *timer)

Stop a nanokernel timer.

This function stops a previously started nanokernel timer object. It can only be called from a fiber.

Return
N/A
Parameters
  • timer: Timer to stop.

void nano_task_timer_start(struct nano_timer *timer, int ticks)

Start a nanokernel timer from a task.

This function starts a previously initialized nanokernel timer object. The timer expires after ticks system clock ticks.

Return
N/A
Parameters
  • timer: Timer.
  • ticks: Number of ticks.

void *nano_task_timer_test(struct nano_timer *timer, int32_t timeout_in_ticks)

Make the current task check for a timer expiry.

This function tests whether or not a previously started nanokernel timer object has expired, or waits until it does.

Return
Pointer to timer initialization data.
See
TICKS_NONE, TICKS_UNLIMITED
Parameters
  • timer: Timer to check.
  • timeout_in_ticks: Determines the action to take when the timer has not expired. For TICKS_NONE, return immediately. For TICKS_UNLIMITED, wait as long as necessary.
Return Value
  • NULL: If timer has not expired.

void nano_task_timer_stop(struct nano_timer *timer)

Stop a nanokernel timer from a task.

This function stops a previously-started nanokernel timer object.

Return
N/A
Parameters
  • timer: Timer to stop.

int32_t nano_timer_ticks_remain(struct nano_timer *timer)

Get nanokernel timer remaining ticks.

This function returns the remaining ticks of the previously started nanokernel timer object.

Return
remaining ticks or 0 if the timer has expired

int64_t sys_tick_get(void)

Return the current system tick count.

Return
The current system tick count.

uint32_t sys_tick_get_32(void)

Return the lower part of the current system tick count.

Return
The current system tick count.

uint32_t sys_cycle_get_32(void)

Return a time stamp in high-resolution format.

This routine reads the counter register on the processor’s high precision timer device. This counter register increments at a relatively high rate (e.g. 20 MHz), and is thus considered a high-resolution timer. This is in contrast to sys_tick_get_32() which returns the value of the system ticks variable.

Return
The current high-precision clock value.

int64_t sys_tick_delta(int64_t *reftime)

Return number of ticks elapsed since a reference time.

Return
The tick count since reference time; undefined for first invocation.
Parameters
  • reftime: Reference time.

uint32_t sys_tick_delta_32(int64_t *reftime)

Return 32-bit number of ticks since a reference time.

Return
A 32-bit tick count since reference time. Undefined for first invocation.
Parameters
  • reftime: Reference time.

Kernel Event Logger

typedef uint32_t (*sys_k_timer_func)(void)

Callback used to set event timestamp

struct event_logger sys_k_event_logger

Global variable of the ring buffer that allows user to implement their own reading routine.

sys_k_timer_func timer_func
int _sys_k_event_logger_mask
int _k_monitor_mask
static uint32_t _sys_k_get_time(void)
void sys_k_event_logger_set_timer(sys_k_timer_func func)

Set kernel event logger timestamp function.

Calling this function permits to set the function to be called by kernel event logger for setting the event timestamp. By default, kernel event logger is using the system timer. But on some boards where the timer driver maintains the system timer cycle accumulator in software, such as ones using the LOAPIC timer, the system timer behavior leads to timestamp errors. For example, the timer interrupt is logged with a wrong timestamp since the HW timer value has been reset (periodic mode) but accumulated value not updated yet (done later in the ISR).

Parameters
  • func: Pointer to a function returning a 32-bit timer Prototype: uint32_t (*func)(void)

static void sys_k_event_logger_set_mask(int value)

Set kernel event logger filtering mask.

Calling this macro sets the mask used to select which events to store in the kernel event logger ring buffer. This flag can be set at runtime and at any moment. This capability is only available when CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC is set. If enabled, no event is enabled for logging at initialization. The mask bits shall be set according to events ID defined in kernel_event_logger.h For example, to enable interrupt logging the following shall be done: sys_k_event_logger_set_mask(sys_k_event_logger_get_mask | (1 << (KERNEL_EVENT_LOGGER_INTERRUPT_EVENT_ID - 1))) To disable it: sys_k_event_logger_set_mask(sys_k_event_logger_get_mask & ~(1 << (KERNEL_EVENT_LOGGER_INTERRUPT_EVENT_ID - 1)))

WARNING: task monitor events are not covered by this API. Please refer to sys_k_event_logger_set_monitor_mask / sys_k_event_logger_get_monitor_mask

static int sys_k_event_logger_get_mask(void)

Get kernel event logger filtering mask.

Calling this macro permits to read the mask used to select which events are stored in the kernel event logger ring buffer. This macro can be used at runtime and at any moment. This capability is only available when CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC is set. If enabled, no event is enabled for logging at initialization.

WARNING: task monitor events are not covered by this API. Please refer to sys_k_event_logger_set_monitor_mask / sys_k_event_logger_get_monitor_mask

See
sys_k_event_logger_set_mask(value) for details

static void sys_k_event_logger_set_monitor_mask(int value)

Set task monitor filtering mask.

Calling this function sets the mask used to select which task monitor events to store in the kernel event logger ring buffer. This flag can be set at runtime and at any moment. This capability is only available when CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC is set. If enabled, no event is enabled for logging at initialization so CONFIG_TASK_MONITOR_MASK is ignored

The mask bits shall be set according to monitor events defined in micro_private.h

For example, to enable k_swapper cmd logging the following shall be done: sys_k_event_logger_set_monitor_mask(sys_k_event_logger_get_monitor_mask | (1 << (MON_KSERV - 1))) To disable it: sys_k_event_logger_set_mask(sys_k_event_logger_get_mask & ~(1 << (MON_KSERV - 1)))

static int sys_k_event_logger_get_monitor_mask(void)

Get task monitor filtering mask.

Calling this function permits to read the mask used to select which task monitor events to store in the kernel event logger ring buffer. This function can be used at runtime and at any moment. This capability is only available when CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC is set. If enabled, no event is enabled for logging at initialization so CONFIG_TASK_MONITOR_MASK is ignored

See
sys_k_event_logger_set_monitor_mask() for details

static int sys_k_must_log_event(int event_type)

Check if an event type has to be logged or not.

This function must be used before calling any sys_k_event_logger_put* function. In case CONFIG_KERNEL_EVENT_LOGGER_DYNAMIC is enabled, that function permits to enable or disable the logging of each individual event at runtime

Parameters
  • event_type: The identification of the event.

void sys_k_event_logger_put_timed(uint16_t event_id)

Sends a event message to the kernel event logger with the current timestamp.

Sends a event message to the kernel event logger and informs that there messages available. The timestamp when the event occurred is stored as part of the event message.

Return
No return value.
Parameters
  • event_id: The identification of the event.

static void sys_k_event_logger_register_as_collector(void)
static void _sys_k_event_logger_enter_sleep(void)
static void _sys_k_event_logger_interrupt(void)
KERNEL_EVENT_LOGGER_TASK_MON_TASK_STATE_CHANGE_EVENT_ID 0x0004
KERNEL_EVENT_LOGGER_TASK_MON_CMD_PACKET_EVENT_ID 0x0005
KERNEL_EVENT_LOGGER_TASK_MON_KEVENT_EVENT_ID 0x0006
sys_k_event_logger_put(event_id, data, data_size) sys_event_logger_put(&sys_k_event_logger, event_id, data, data_size)

Sends a event message to the kernel event logger.

Sends a event message to the kernel event logger and informs that there are messages available.

Return
No return value.
Parameters
  • event_id: The identification of the event.
  • data: Pointer to the data of the message.
  • data_size: Size of the data in 32-bit words.

sys_k_event_logger_get(event_id, dropped, buffer, buffer_size) sys_event_logger_get(&sys_k_event_logger, event_id, dropped, buffer, \ buffer_size)

Retrieves a kernel event message.

Retrieves a kernel event message copying it to the provided buffer. If the buffer is smaller than the message size the function returns an error. The function retrieves messages in FIFO order.

Return
-EMSGSIZE if the buffer size is smaller than the message size, the amount of 32-bit words copied or zero if there are no kernel event messages available.
Parameters
  • event_id: Pointer to the id of the event fetched
  • dropped: Pointer to how many events were dropped
  • buffer: Pointer to the buffer where the message will be copied.
  • buffer_size: Size of the buffer in 32-bit words.

sys_k_event_logger_get_wait(event_id, dropped, buffer, buffer_size) sys_event_logger_get_wait(&sys_k_event_logger, event_id, dropped, \ buffer, buffer_size)

Retrieves a kernel event message, wait if there is no message available.

Retrieves a kernel event message copying it to the provided buffer. If the buffer is smaller than the message size the function returns an error. The function retrieves messages in FIFO order. If there is no kernel event message available the caller pends until a new message is logged.

Return
-EMSGSIZE if the buffer size is smaller than the message size, or the amount of 32-bit words copied.
Parameters
  • event_id: Pointer to the id of the event fetched
  • dropped: Pointer to how many events were dropped
  • buffer: Pointer to the buffer where the message will be copied.
  • buffer_size: Size of the buffer in 32-bit words.

sys_k_event_logger_get_wait_timeout(event_id, dropped, buffer, buffer_size, timeout) sys_event_logger_get_wait_timeout(&sys_k_event_logger, event_id, \ dropped, buffer, \ buffer_size, timeout)

Retrieves a kernel event message, wait with a timeout if there is no profiling event messages available.

Retrieves a kernel event message copying it to the provided buffer. If the buffer is smaller than the message size the function returns an error. The function retrieves messages in FIFO order. If there are no kernel event messages available the caller pends until a new message is logged or the timeout expires.

Return
-EMSGSIZE if the buffer size is smaller than the message size, the amount of 32-bit words copied or zero if the timeout expires and the was no message available.
Parameters
  • event_id: Pointer to the id of the event fetched
  • dropped: Pointer to how many events were dropped
  • buffer: Pointer to the buffer where the message will be copied.
  • buffer_size: Size of the buffer in 32-bit words.
  • timeout: Timeout in ticks.