API

This part of the documentation covers all the interfaces of Amast.

Common Constants

AM_ALIGN_MAX

The maximum compiler alignment [bytes]

Common Types

struct am_blk

Memory block descriptor

Public Members

void *ptr

memory

int size

memory size [bytes]

Singly Linked List

struct am_slist_item

Singly linked item.

There are at least two ways to make an arbitrary structure struct foo a singly linked list item:

[1]

struct foo {
    int bar;
    struct am_slist_item list;
};

[2]

struct foo {
    int bar;
};

struct foo_item {
    struct foo foo;
    struct am_slist_item list;
};

Also struct foo can be part of several independent lists. For example,

struct foo {
    int bar;
    struct am_slist_item list1;
    struct am_slist_item list2;
};
struct am_slist

Singly linked list handler

struct am_slist_iterator

Singly linked list iterator handler

void am_slist_ctor(struct am_slist *list)

Singly linked list construction.

Parameters:

list – the list

bool am_slist_is_empty(const struct am_slist *list)

Check if list is empty.

Parameters:

list – the list

Return values:
  • true – the list is empty

  • false – the list is not empty

bool am_slist_item_is_linked(const struct am_slist_item *item)

Check if given list item is part of ANY list.

Parameters:

item – the list item to check

Return values:
  • true – item IS part of SOME list

  • false – item IS NOT part of ANY list

void am_slist_item_ctor(struct am_slist_item *item)

Construct list item.

Parameters:

item – list item to construct.

void am_slist_push_after(struct am_slist *list, struct am_slist_item *item, struct am_slist_item *newitem)

Push new item after the item, which is already in list.

Parameters:
  • list – the list

  • item – the new item is pushed after this item

  • newitem – the new item to be pushed to the list

struct am_slist_item *am_slist_pop_after(struct am_slist *list, struct am_slist_item *item)

Pop item after given item.

The provided item must be part of the list. Otherwise the behavior is undefined.

Parameters:
  • list – the list

  • item – the item after this item is popped

Returns:

the popped item or NULL if nothing to pop

typedef bool (*am_slist_item_found_fn)(void *context, struct am_slist_item *item)

Predicate callback type that tells if item is found.

Param context:

the predicate context

Param item:

item to analyze

Retval true:

item was found

Retval false:

item was not found

struct am_slist_item *am_slist_find(const struct am_slist *list, am_slist_item_found_fn is_found, void *context)

Find item in list using predicate function.

Parameters:
  • list – the list

  • is_found – the predicate callback

  • context – the context, which is provided verbatim to predicate

Returns:

the item, found by the predicate callback function NULL, if nothing was found. The found item is not popped from the list.

struct am_slist_item *am_slist_peek_front(const struct am_slist *list)

Return list item at front (head) of list.

The list item is not popped from the list.

Parameters:

list – the list

Returns:

the item at the front of the list or NULL, if no item exists at the given index

struct am_slist_item *am_slist_peek_back(const struct am_slist *list)

Return list item at back (tail) of list.

The lists item is not popped from the list.

Parameters:

list – the list

Returns:

the item at the back of the list or NULL, if no item exists at the given index.

void am_slist_push_front(struct am_slist *list, struct am_slist_item *item)

Push item to front (head) of list.

Parameters:
  • list – the list

  • item – the item to be pushed

struct am_slist_item *am_slist_pop_front(struct am_slist *list)

Pop item in front (head) of list.

Parameters:

list – the list

Returns:

the popped item or NULL, if the list was empty

void am_slist_push_back(struct am_slist *list, struct am_slist_item *item)

Add new item at back (tail) of list.

Parameters:
  • list – the list

  • item – the item to be added

bool am_slist_owns(const struct am_slist *list, const struct am_slist_item *item)

Check if given item is part of list.

Parameters:
  • list – the list

  • item – the item to be checked

Return values:
  • true – the given item belongs to the list

  • false – the given item is not part of the list

struct am_slist_item *am_slist_next_item(const struct am_slist *list, const struct am_slist_item *item)

Get next list item.

Parameters:
  • list – the list

  • item – the item to be checked

Returns:

next list item or NULL

void am_slist_append(struct am_slist *to, struct am_slist *from)

Append one list to another.

Parameters:
  • to – append to this list

  • from – append this list. If from list is not empty, then it is initialized after it is appended to to list.

void am_slist_iterator_ctor(struct am_slist *list, struct am_slist_iterator *it)

Construct new iterator.

Must be called before calling am_slist_iterator_next(). If the iterator is used to traverse the list once, then it must be re-constructed by calling this function in order to be used with am_slist_iterator_next() again. The only valid operation with the iterator after this one is am_slist_iterator_next() or am_slist_iterator_pop(). Otherwise the behavior is undefined.

Parameters:
  • list – the list

  • it – the iterator to be constructed

struct am_slist_item *am_slist_iterator_next(struct am_slist_iterator *it)

Iterate over list.

Is supposed to be called in iterative way to traverse part or full list. The iteration can visit each item only once. When all items of the list were visited, the next invocation of the function returns NULL. The current visited item can only be popped with am_slist_iterator_pop().

Parameters:

it – the iterator constructed by am_slist_iterator_ctor()

Returns:

the visited item or NULL if the iteration is over. The item is not popped from the list.

struct am_slist_item *am_slist_iterator_pop(struct am_slist_iterator *it)

Pop item pointed by iterator.

The popped item is returned. The iterator is still usable after the removal. At least one am_slist_iterator_next() call is expected for the iterator before this function is called. Otherwise the behavior is undefined. The valid operations possible after this call are am_slist_iterator_next() or am_slist_iterator_ctor(). Otherwise the behavior is undefined.

Parameters:

it – the iterator

Returns:

the popped item

Bit

struct am_bit_u64

A 64 bit array

bool am_bit_u64_is_empty(const struct am_bit_u64 *u64)

Check if bit array has no bits set to 1.

Parameters:

u64 – the bit array to check

Return values:
  • true – bit array is empty

  • false – bit array is not empty

int am_bit_u64_msb(const struct am_bit_u64 *u64)

Return the index of the most significant bit (MSB) set to 1.

Parameters:

u64 – the bit array to check

Returns:

the MSB index

int am_bit_u8_msb(uint8_t u8)

Return the index of the most significant bit (MSB) set to 1.

Parameters:

u8 – the bit array to check

Returns:

the MSB index

void am_bit_u64_set(struct am_bit_u64 *u64, int n)

Set bit with index n to 1.

Parameters:
  • u64 – the bit array

  • n – the index of bit to set. Zero based. The valid range [0..63].

void am_bit_u64_clear(struct am_bit_u64 *u64, int n)

Clears a bit to 1 with index n.

Parameters:
  • u64 – the bit array

  • n – the index. Zero based. The valid range [0..63].

Ring Buffer

struct am_ringbuf

Ring buffer descriptor.

Only exposed to allow for memory allocation by ring buffer user.

void am_ringbuf_ctor(struct am_ringbuf *rb, void *buf, int buf_size)

Construct ring buffer.

Parameters:
  • rb – the ring buffer

  • buf – the ring buffer’s memory

  • buf_size – the ring buffer’s memory size [bytes]

int am_ringbuf_get_read_ptr(struct am_ringbuf *rb, uint8_t **ptr)

Return ring buffer read data pointer.

The caller can do anything with the data behind the read pointer. Call am_ringbuf_seek() to inform writer that the data reading is complete. Until then writer will not be able to write to the memory.

Parameters:
  • rb – the ring buffer

  • ptr – the read data pointer is returned here. Can be NULL.

Returns:

the byte size of the memory pointed to by *ptr. Can be 0.

int am_ringbuf_get_write_ptr(struct am_ringbuf *rb, uint8_t **ptr, int size)

Return ring buffer write data pointer.

Anything can be done with the memory pointed to by the write pointer. Call am_ringbuf_flush() to inform reader that data writing is complete. Until then reader will not be able to read the memory.

Parameters:
  • rb – the ring buffer

  • ptr – the write data pointer is returned here. Can be NULL.

  • size – the requested memory size behind the write date pointer. Can be set to 0.

Returns:

the byte size of all the available memory pointed to by *ptr. Can be 0 or more than the requested size.

void am_ringbuf_flush(struct am_ringbuf *rb, int offset)

Increase by offset bytes the amount of written data available to reader.

Called once or many times after calling am_ringbuf_get_write_ptr(). The offset or sum of offsets of multiple calls to this function must not exceed the size returned by the last call to am_ringbuf_get_write_ptr().

Parameters:
  • rb – the ring buffer

  • offset – the bytes of write data available to reader

void am_ringbuf_seek(struct am_ringbuf *rb, int offset)

Increase by offset bytes the amount of data available to writer.

Called once or many times after calling am_ringbuf_get_read_ptr(). The offset or sum of offsets of multiple calls to this function must not exceed the size returned by the last call to am_ringbuf_get_read_ptr().

Parameters:
  • rb – the ring buffer

  • offset – the bytes of memory available to writer

int am_ringbuf_get_data_size(const struct am_ringbuf *rb)

Return total number of data bytes available for reading.

Parameters:

rb – the ring buffer

Returns:

the number of data bytes available for reading

int am_ringbuf_get_free_size(const struct am_ringbuf *rb)

Return total number of free memory bytes available for writing.

Parameters:

rb – the ring buffer

Returns:

the number of memory bytes available for writing

void am_ringbuf_add_dropped(struct am_ringbuf *rb, int dropped)

Add to the number of dropped bytes.

Parameters:
  • rb – the ring buffer

  • dropped – add this many dropped bytes

unsigned am_ringbuf_get_dropped(const struct am_ringbuf *rb)

Get the number of dropped bytes.

Parameters:

rb – the ring buffer

Returns:

the number of dropped bytes

void am_ringbuf_clear_dropped(struct am_ringbuf *rb)

Clear the number of dropped bytes.

Parameters:

rb – the ring buffer

Queue

struct am_queue

Queue handler.

void am_queue_ctor(struct am_queue *queue, int isize, int alignment, struct am_blk *blk)

Queue construction with a memory block.

Parameters:
  • queue – the queue

  • isize – item size [bytes]. The queue will only support the items of this size.

  • alignment – the queue alignment [bytes]. Can be set to AM_ALIGN_MAX.

  • blk – the memory block

void am_queue_dtor(struct am_queue *queue)

Queue destruction.

Parameters:

queue – the queue

bool am_queue_is_empty(const struct am_queue *queue)

Check if queue is empty.

Parameters:

queue – the queue

Return values:
  • true – queue is empty

  • false – queue is not empty

bool am_queue_is_full(const struct am_queue *queue)

Check if queue is full.

Parameters:

queue – the queue

Return values:
  • true – queue is full

  • false – queue is not full

int am_queue_get_nbusy(const struct am_queue *queue)

Return how many items are in queue.

Parameters:

queue – the queue

Returns:

number of queued items

int am_queue_get_nfree(const struct am_queue *queue)

Get minimum number of free slots available in queue.

Parameters:

queue – the queue

Returns:

the number of free slots available now

int am_queue_get_nfree_min(const struct am_queue *queue)

Get minimum number of free slots available so far in queue.

Could be used to assess the usage of the queue.

Parameters:

queue – the queue

Returns:

the minimum number of slots available so far

int am_queue_get_capacity(const struct am_queue *queue)

Return queue capacity.

Parameters:

queue – the queue

Returns:

queue capacity

int am_queue_item_size(const struct am_queue *queue)

Return queue item size.

Parameters:

queue – the queue

Returns:

queue item size [bytes]

void *am_queue_pop_front(struct am_queue *queue)

Pop an item from the front (head) of queue.

Takes O(1) to complete.

Parameters:

queue – the queue

Returns:

The popped item. The memory is owned by the queue. Do not free it! If queue is empty, then NULL is returned.

void *am_queue_pop_front_and_copy(struct am_queue *queue, void *buf, int size)

Pop an item from the front (head) of queue to the provided buffer.

Takes O(1) to complete.

Parameters:
  • queue – the queue

  • buf – the popped item is copied here

  • size – the byte size of buf

Returns:

The popped item. NULL if queue was empty.

void *am_queue_peek_front(struct am_queue *queue)

Peek an item from the front (head) of queue.

Takes O(1) to complete.

Parameters:

queue – the queue

Returns:

The peeked item. The memory is owned by the queue. Do not free it! If queue is empty, then NULL is returned.

void *am_queue_peek_back(struct am_queue *queue)

Peek an item from the back (tail) of queue.

Takes O(1) to complete.

Parameters:

queue – the queue

Returns:

The peeked item. The memory is owned by the queue. Do not free it! If queue is empty, then NULL is returned.

bool am_queue_push_front(struct am_queue *queue, const void *ptr, int size)

Push an item to the front (head) of queue.

Takes O(1) to complete.

Parameters:
  • queue – the queue

  • ptr – the new queue item. The API copies the content of ptr.

  • size – the size of the new queue item in bytes. Must be <= than queue item size.

Return values:
  • true – success

  • false – failure

bool am_queue_push_back(struct am_queue *queue, const void *ptr, int size)

Push an item to the back (tail) of queue.

Takes O(1) to complete.

Parameters:
  • queue – the queue

  • ptr – the new queue item. The API copies the content of ptr.

  • size – the size of the new queue item in bytes. Must be <= than queue item size.

Return values:
  • true – success

  • false – failure

Onesize

struct am_onesize

onesize memory allocator descriptor

struct am_onesize_cfg

Onesize configuration.

void am_onesize_ctor(struct am_onesize *hnd, const struct am_onesize_cfg *cfg)

Construct a new onesize allocator.

Allocation requests up to block_size bytes are rounded up to block_size bytes and served from a singly-linked list of buffers. Due to the simplicity of onesize allocator management, allocations from it are fast.

Parameters:
  • hnd – the allocator

  • cfg – configuration

void *am_onesize_allocate_x(struct am_onesize *hnd, int margin)

Allocate memory block of struct of block_size (eXtended version).

Checks if there are more free memory blocks available than margin. If not, then returns NULL. Otherwise allocates memory block and returns it.o

Parameters:
  • hnd – the allocator

  • margin – free memory blocks to remain available after the allocation

Returns:

the allocated memory or NULL, if allocation failed

void *am_onesize_allocate(struct am_onesize *hnd)

Allocate one memory block of configured block size.

Asserts if no free memory block is available.

Parameters:

hnd – the allocator

Returns:

the allocated memory

void am_onesize_free(struct am_onesize *hnd, const void *ptr)

Free a memory block.

Inserts the block at the front of the free list.

Parameters:
  • hnd – the allocator

  • ptr – memory block to free

void am_onesize_free_all(struct am_onesize *hnd)

Reclaim all memory allocated so far.

Parameters:

hnd – the allocator

typedef void (*am_onesize_iterate_fn)(void *ctx, int index, const char *buf, int size)

The type of callback to be used with am_onesize_iterate_over_allocated()

Param ctx:

the caller’s context

Param index:

the buffer index

Param buf:

the buffer pointer

Param size:

the buffer size [bytes]

void am_onesize_iterate_over_allocated(struct am_onesize *hnd, int num, am_onesize_iterate_fn cb, void *ctx)

Iterate over allocated memory blocks with a provided callback function.

Could be used for inspection of allocated memory for debugging.

Parameters:
  • hnd – the allocator

  • num – the number of allocated blocks to iterate over

  • cb – the callback to call for each allocated memory block

  • ctx – the caller’s specific context to be used with the callback

int am_onesize_get_nfree(const struct am_onesize *hnd)

Returns the number of free blocks available for allocation.

Parameters:

hnd – the allocator

Returns:

the number of free blocks

int am_onesize_get_nfree_min(const struct am_onesize *hnd)

The minimum number of free memory blocks of size block_size available so far.

Could be used to assess the usage of the underlying memory pool.

Parameters:

hnd – the allocator

Returns:

the minimum number of blocks of size block_size available so far

int am_onesize_get_block_size(const struct am_onesize *hnd)

Returns the memory block size.

Parameters:

hnd – the allocator

Returns:

the block size [bytes]

int am_onesize_get_nblocks(const struct am_onesize *hnd)

Get total number of memory blocks - the total capacity of the allocator.

Parameters:

hnd – the allocator

Returns:

the total number of blocks

Event

AM_EVT_USER

The event IDs below this value are reserved and should not be used for user events.

AM_EVENT_POOLS_NUM_MAX

The max number of event pools.

Can be redefined by user.

AM_EVENT_HAS_USER_ID(event)

Check if event has a valid user event ID.

Parameters:
  • event – event to check

Return values:
  • true – the event has user event ID

  • false – the event does not have user event ID

enum am_event_rc

Event API return codes.

Values:

enumerator AM_EVENT_RC_ERR

failure

enumerator AM_EVENT_RC_OK

success

enumerator AM_EVENT_RC_OK_QUEUE_WAS_EMPTY

Success. Also tells that event queue was empty before the call. This allows to signal the event queue owner about new event available for processing.

struct am_event

Event descriptor.

struct am_event_state_cfg

Event module state configuration.

Public Members

void (*crit_enter)(void)

Enter critical section.

void (*crit_exit)(void)

Exit critical section.

void am_event_state_ctor(const struct am_event_state_cfg *cfg)

Event state constructor.

Must be called before calling any other event APIs. Not thread safe.

Parameters:

cfg – event state configuration The event module makes an internal copy of the configuration.

void am_event_add_pool(void *pool, int size, int block_size, int alignment)

Add event memory pool.

Event memory pools must be added in the order of increasing block sizes. Not thread safe. Must be called at initialization if event allocation API is used.

Parameters:
  • pool – the memory pool pointer

  • size – the memory pool size [bytes]

  • block_size – the maximum size of allocated memory block [bytes]

  • alignment – the required alignment of allocated memory blocks [bytes]

int am_event_get_pool_nfree(int index)

Get number of free memory blocks.

Thread safe, if critical section callbacks were configured. Use sparingly as the return value could be volatile due to multitasking.

Parameters:

index – memory pool index

Returns:

the number of free blocks of size block_size available now

int am_event_get_pool_nfree_min(int index)

Get minimum number of free memory blocks observed so far.

Could be used to assess the usage of the underlying memory pool. Thread safe, if critical section callbacks were configured.

Parameters:

index – memory pool index

Returns:

the minimum number of blocks of size block_size observed so far

int am_event_get_pool_nblocks(int index)

The number of blocks in the pool with the given index.

Thread safe.

Parameters:

index – the pool index

Returns:

the number of blocks

int am_event_get_pools_num(void)

The number of registered pools.

Thread safe.

Returns:

the number of pools

struct am_event *am_event_allocate_x(int id, int size, int margin)

Allocate event (eXtended version).

The event is allocated from one of the memory pools provided with am_event_add_pool() function.

Checks if there are more free memory blocks available than margin. If not, then returns NULL. Otherwise allocates the event and returns it.

Thread safe, if critical section callbacks were configured.

Parameters:
  • id – the event identifier

  • size – the event size [bytes]

  • margin – free memory blocks to remain available after the allocation

Returns:

the newly allocated event

struct am_event *am_event_allocate(int id, int size)

Allocate event.

The event is allocated from one of the memory pools provided with am_event_add_pool() function.

The function asserts if there is no memory left to accommodate the event.

Thread safe, if critical section callbacks were configured.

Parameters:
  • id – the event identifier

  • size – the event size [bytes]

Returns:

the newly allocated event

void am_event_free(const struct am_event **event)

Try to free the event allocated earlier with am_event_allocate().

Decrements event reference counter by one and free the event, if the reference counter is zero.

If the event is freed, then the pointer to the event is set to NULL to catch double free cases.

The function does nothing for statically allocated events (events for which am_event_is_static() returns true).

Thread safe, if critical section callbacks were configured.

Parameters:

event – the event to free

struct am_event *am_event_dup_x(const struct am_event *event, int size, int margin)

Duplicate an event (eXtended version).

Allocates it from memory pools provided with am_event_add_pool() function.

Checks if there are more free memory blocks available than margin. If not, then returns NULL. Otherwise allocates memory block and then copies the content of the given event to it.

Thread safe, if critical section callbacks were configured.

Parameters:
  • event – the event to duplicate

  • size – the event size [bytes]

  • margin – free memory blocks to be available after the allocation

Returns:

the newly allocated copy of event

struct am_event *am_event_dup(const struct am_event *event, int size)

Duplicate an event.

Allocates it from memory pools provided with am_event_add_pool() function.

The function asserts if there is no memory left to allocated the event.

Thread safe, if critical section callbacks were configured.

Parameters:
  • event – the event to duplicate

  • size – the event size [bytes]

Returns:

the newly allocated copy of event

typedef void (*am_event_log_fn)(int pool_index, int event_index, const struct am_event *event, int size)

Log event content callback type.

Param pool_index:

pool index

Param event_index:

event_index within the pool

Param event:

event to log

Param size:

the event size [bytes]

void am_event_log_pools(int num, am_event_log_fn cb)

Log events content of the first num events in each event pool.

To be used for debugging purposes. Not thread safe.

Parameters:
  • num – the number of events to log in each pool (if <0, then log all)

  • cb – the logging callback

bool am_event_is_static(const struct am_event *event)

Check if event is static.

Thread safe.

Parameters:

event – the event to check

Return values:
  • true – the event is static

  • false – the event is not static

void am_event_inc_ref_cnt(const struct am_event *event)

Increment event reference counter by one.

Incrementing the event reference prevents the automatic event disposal. Used to hold on to the event. Call am_event_dec_ref_cnt(), when the event is not needed anymore and can be disposed.

Thread safe, if critical section callbacks were configured.

Parameters:

event – the event

void am_event_dec_ref_cnt(const struct am_event *event)

Decrement event reference counter by one.

Frees the event, if the reference counter drops to zero.

The function does nothing for statically allocated events (events for which am_event_is_static() returns true).

Thread safe, if critical section callbacks were configured.

Parameters:

event – the event

int am_event_get_ref_cnt(const struct am_event *event)

Return event reference counter.

Thread safe, if critical section callbacks were configured. Use sparingly as the return value is volatile due to multitasking.

Parameters:

event – the event, which reference counter is to be returned

Returns:

the event reference counter

enum am_event_rc am_event_push_back_x(struct am_queue *queue, const struct am_event *event, int margin)

Push event to the back of event queue (eXtended version).

Checks if there are more free queue slots available than margin. If not, then does not push. Otherwise pushes the event to the back of the event queue.

Tries to free the event, if it was not pushed.

Statically allocated events (events for which am_event_is_static() returns true) are never freed.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the event queue

  • event – the event to push

  • margin – free event queue slots to be available after event was pushed

Return values:
  • AM_EVENT_RC_OK – the event was pushed

  • AM_EVENT_RC_OK_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_EVENT_RC_ERR – the event was not pushed

enum am_event_rc am_event_push_back(struct am_queue *queue, const struct am_event *event)

Push event to the back of event queue.

Asserts if the event was not pushed.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the event queue

  • event – the event to push

Return values:
  • AM_EVENT_RC_OK – the event was pushed

  • AM_EVENT_RC_OK_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_EVENT_RC_ERR – the event was not pushed

enum am_event_rc am_event_push_front_x(struct am_queue *queue, const struct am_event *event, int margin)

Push event to the front of event queue with margin.

Checks if there are more free queue slots available than margin. If not, then does not push. Otherwise pushes the event to the front of the event queue.

Tries to free the event, if it was not pushed.

Statically allocated events (events for which am_event_is_static() returns true) are never freed.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the event queue

  • event – the event to push

  • margin – free event queue slots to be available after event was pushed

Return values:
  • AM_EVENT_RC_OK – the event was pushed

  • AM_EVENT_RC_OK_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_EVENT_RC_ERR – the event was not pushed

enum am_event_rc am_event_push_front(struct am_queue *queue, const struct am_event *event)

Push event to the front of event queue.

Asserts if the event was not pushed.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the event queue

  • event – the event to push

Return values:
  • AM_EVENT_RC_OK – the event was pushed

  • AM_EVENT_RC_OK_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_EVENT_RC_ERR – the event was not pushed

const struct am_event *am_event_pop_front(struct am_queue *queue)

Pop event from the front of event queue.

Thread safe, if critical section callbacks were configured.

Parameters:

queue – the event queue

Returns:

the popped event. Cannot be NULL.

bool am_event_defer_x(struct am_queue *queue, const struct am_event *event, int margin)

Defer event (eXtended version).

Checks if there are more free queue slots available than margin. If not, then does not defer. Otherwise defers the event by pushing it to the back of the event queue.

Tries to free event, if defer fails.

Statically allocated events (events for which am_event_is_static() returns true) are never freed.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the queue to store the deferred event

  • event – the event to defer

  • margin – free event queue slots to be available after event is deferred

Return values:
  • true – the event was deferred

  • false – the event was not deferred

void am_event_defer(struct am_queue *queue, const struct am_event *event)

Defer event.

Asserts if the event was not deferred.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – the queue to store the deferred event

  • event – the event to defer

typedef void (*am_event_recall_fn)(void *ctx, const struct am_event *event)

The type of a callback used to handle recalled events

bool am_event_recall(struct am_queue *queue, am_event_recall_fn cb, void *ctx)

Recall deferred event.

Thread safe, if critical section callbacks were configured.

Parameters:
  • queue – queue of deferred events

  • cb – the recalled event is provided to this callback

  • ctx – the callback context

Return values:
  • true – an event was recalled

  • false – no event was recalled

int am_event_flush_queue(struct am_queue *queue)

Flush all events from event queue.

Takes care of recycling the events by calling am_event_free(). The provided queue might be deferred events queue.

Thread safe, if critical section callbacks were configured.

Parameters:

queue – the queue to flush

Returns:

the number of events flushed

Timer

typedef void (*am_timer_post_fn)(void *owner, const struct am_event *event)

Expired timer events are posted using this callback. Posting is a one-to-one event delivery mechanism.

typedef void (*am_timer_publish_fn)(const struct am_event *event)

Expired timer events are published using this callback. Publishing is a one-to-many event delivery mechanism.

struct am_timer_state_cfg

Timer module state configuration.

Public Members

am_timer_post_fn post

either post or publish callback must be non-NULL Expired timer events are posted using this callback. Posting is a one-to-one event delivery mechanism.

am_timer_publish_fn publish

Expired timer events are published using this callback. Publishing is a one-to-many event delivery mechanism.

struct am_timer *(*update)(struct am_timer *timer)

Update the content of the given timer.

Optional, can be NULL.

Param timer:

the timer to update

Return:

the updated timer

void (*crit_enter)(void)

Enter critical section.

void (*crit_exit)(void)

Exit critical section.

struct am_timer

Timer.

void am_timer_state_ctor(const struct am_timer_state_cfg *cfg)

Timer state constructor.

Parameters:

cfg – timer state configuration The timer module makes an internal copy of the configuration.

void am_timer_ctor(struct am_timer *timer, int id, int domain, void *owner)

Timer constructor.

Parameters:
  • timer – the timer to construct

  • id – the timer event identifier

  • domain – tick domain the timer belongs to

  • owner – the timer’s owner that gets the posted event. Can be NULL, in which case the timer event is published.

struct am_timer *am_timer_allocate(int id, int size, int domain, void *owner)

Allocate and construct timer.

Cannot fail. Cannot be freed. Never garbage collected. The returned timer is fully constructed. No need to call am_timer_ctor() for it. Provides an alternative way to reserve memory for timers in addition to the static allocation in user code. Allocation of timer using this API is preferred as it improves cache locality of timer structures.

Parameters:
  • id – the timer event id

  • size – the timer size [bytes]

  • domain – the clock domain [0-AM_PAL_TICK_DOMAIN_MAX[

  • owner – the timer’s owner that gets the posted event. Can be NULL, in which case the timer event is published.

void am_timer_tick(int domain)

Tick timer.

Update all armed timers and fire expired timers. Must be called every tick.

Parameters:

domain – only tick timers in this tick domain

void am_timer_arm(struct am_timer *timer, int ticks, int interval)

Arm timer.

Sends timer event to owner in specified number of ticks. It is fine to arm an already armed timer.

The owner is set in am_timer_ctor() or am_timer_allocate() calls.

Parameters:
  • timer – the timer to arm

  • ticks – the timer event is to be sent in these many ticks

  • interval – the timer event is to be re-sent in these many ticks after the event is sent for the fist time. Can be 0, in which case the timer is one shot.

bool am_timer_disarm(struct am_timer *timer)

Disarm timer.

It is fine to disarm an already disarmed timer.

Parameters:

timer – the timer to disarm

Return values:
  • true – the timer was armed

  • false – the timer was not armed

bool am_timer_is_armed(const struct am_timer *timer)

Check if timer is armed.

Parameters:

timer – the timer to check

Return values:
  • true – the timer is armed

  • false – the timer is not armed

bool am_timer_domain_is_empty(int domain)

Check if timer domain has armed timers.

The function is to be called from a critical section. So, it can be called to check if there are any pending timers just before going to sleep mode.

Please read the article called “Use an MCU’s low-power modes in foreground/background systems” by Miro Samek for more information about the reasoning of the approach.

Parameters:

domain – the domain to check

Return values:
  • true – the timer domain is empty

  • false – the timer domain has armed timers

int am_timer_get_ticks(const struct am_timer *timer)

Get number of ticks till timer event is sent.

Parameters:

timer – the timer handler

Returns:

the timer event is sent in this number of ticks

int am_timer_get_interval(const struct am_timer *timer)

Get timer interval.

Parameters:

timer – the timer handler

Returns:

the timer event is sent with this interval [ticks]

Async

AM_ASYNC_STATE_INIT

Init state of async function

enum am_async_rc

Async function return codes

Values:

enumerator AM_ASYNC_RC_DONE

Async function is done

enumerator AM_ASYNC_RC_BUSY

Async function is busy

struct am_async

Async state

AM_ASYNC_BEGIN(me)

Mark the beginning of async function block.

Should be called at the beginning of async function.

Parameters:
  • me – pointer to the struct am_async managing the async state

AM_ASYNC_BREAK()

Mark the end of async function and return completion.

Reset the async state to the initial state and set return value to AM_ASYNC_RC_DONE, indicating that the async operation has completed.

AM_ASYNC_END()

Mark the end of async function block and handle any unexpected states.

Ensure proper handling for completed and unexpected states. Call AM_ASYNC_BREAK() internally to reset the async state.

AM_ASYNC_LABEL()

Set label in async function.

Store the current line number in the state field, enabling the async function to resume from this point.

AM_ASYNC_AWAIT(cond)

Await a condition before proceeding.

Check the provided condition “cond”. If the condition is not met (false) - return AM_ASYNC_RC_BUSY, allowing the caller to re-enter the function later.

Parameters:
  • cond – the condition to check for continuation

AM_ASYNC_YIELD()

Yield control back to the caller.

Allow the async function to yield, returning AM_ASYNC_RC_BUSY to signal that the operation is not yet complete. Control resumes after this point, when the function is called again.

AM_ASYNC_RC(me)

Return code of async operation.

Parameters:
  • me – the async instance pointer

void am_async_ctor(struct am_async *me)

Construct async state.

Set the async state to AM_ASYNC_STATE_INIT preparing it for use in async operation.

Parameters:

me – the async state to construct

HSM

enum am_hsm_evt_id

HSM events.

Values:

enumerator AM_EVT_HSM_EMPTY

Empty event. Should not cause any side effects in event handlers. The event handlers must always return the AM_HSM_SUPER() in response to this event.

enumerator AM_EVT_HSM_INIT

Init event. Run initial transition from a given state. Always follows the AM_EVT_HSM_ENTRY event.

enumerator AM_EVT_HSM_ENTRY

Entry event. Run entry action(s) for a given state. Always precedes the AM_EVT_HSM_INIT event. No state transition is allowed in response to this event.

enumerator AM_EVT_HSM_EXIT

Exit event. Run exit action(s) for a given state. No state transition is allowed in response to this event.

enum am_hsm_rc

HSM state handler return codes.

These return codes are not used directly in user code. Instead user code is expected to use as return values the macros listed in descriptions to each of the constants.

Values:

enumerator AM_HSM_RC_HANDLED

Returned by AM_HSM_HANDLED()

enumerator AM_HSM_RC_TRAN

Returned by AM_HSM_TRAN()

enumerator AM_HSM_RC_TRAN_REDISPATCH

Returned by AM_HSM_TRAN_REDISPATCH()

enumerator AM_HSM_RC_SUPER

Returned by AM_HSM_SUPER()

typedef enum am_hsm_rc (*am_hsm_state_fn)(struct am_hsm *hsm, const struct am_event *event)

HSM state (event handler) function type.

One should not assume that a state handler would be invoked only for processing event IDs enlisted in the case statement of internal switch statement. Event handlers should avoid using any code outside of the switch statement, especially code that has side effects.

Param hsm:

the HSM

Param event:

the event to handle

Return:

return code

typedef void (*am_hsm_spy_fn)(struct am_hsm *hsm, const struct am_event *event)

HSM spy callback type.

Used as one place to catch all events for the given HSM. Called on each user event BEFORE the event is processes by the HSM. Should only be used for debugging purposes. Set by am_hsm_set_spy(). Only supported if “hsm.c” file is compiled with AM_HSM_SPY defined.

Param hsm:

the handler of HSM to spy

Param event:

the event to spy

struct am_hsm_state

HSM state

AM_HSM_STATE_CTOR(...)

Get HSM state from HSM event handler and optionally HSM submachine instance.

AM_HSM_STATE_CTOR(s) is converted to

(struct am_hsm_state){.fn = s, .smi = 0}
AM_HSM_STATE_CTOR(s, i) is converted to
(struct am_hsm_state){.fn = s, .smi = i}

s is HSM event handler (mandatory)

i is HSM submachine instance (optional, default is 0)

Returns:

HSM state structure

HSM_HIERARCHY_DEPTH_MAX

HSM hierarchy maximum depth

struct am_hsm

HSM state.

AM_HSM_HANDLED()

Event processing is over. No state transition is triggered.

Used as a return value from the event handler that handled an event and wants to prevent the event propagation to superstate(s).

AM_HSM_TRAN(...)

Event processing is over. Transition is triggered.

It should never be returned for AM_EVT_HSM_ENTRY or AM_EVT_HSM_EXIT events. Conversely, the response to AM_EVT_HSM_INIT event can optionally use this macro as a return value to designate transition to the provided state. The target state in this case must be a substate of the current state.

s is the new state of type am_hsm_state_fn (mandatory)

i is HSM submachine instance (optional, default is 0)

AM_HSM_TRAN_REDISPATCH(...)

Event redispatch is requested. Transition is triggered.

It should never be returned for AM_EVT_HSM_ENTRY, AM_EVT_HSM_EXIT or AM_EVT_HSM_INIT events. Do not redispatch the same event more than once within same am_hsm_dispatch() call.

s is the new HSM state of type am_hsm_state_fn (mandatory)

i is the new HSM state submachine instance (optional, default is 0)

AM_HSM_SUPER(...)

Event processing is passed to superstate. No transition was triggered.

If no explicit superstate exists, then the top (super)state am_hsm_top() must be used.

s is the superstate of type am_hsm_state_fn (mandatory)

i is the superstate submachine instance (optional, default is 0)

void am_hsm_dispatch(struct am_hsm *hsm, const struct am_event *event)

Synchronous dispatch of event to a given HSM.

Does not free the event - this is caller’s responsibility.

Parameters:
  • hsm – the HSM

  • event – the event to dispatch

bool am_hsm_is_in(struct am_hsm *hsm, struct am_hsm_state state)

Test whether HSM is in a given state.

Note that an HSM is in all superstates of the active state. Use sparingly to test the active state of other state machine as it breaks encapsulation.

Parameters:
  • hsm – the HSM

  • state – the state to check

Return values:
  • false – not in the state in the hierarchical sense

  • true – in the state

bool am_hsm_state_is_eq(const struct am_hsm *hsm, struct am_hsm_state state)

Check if HSM’s active state equals to state (not in hierarchical sense).

If active state of hsm is S1, which is substate of S, then am_hsm_state_is_eq(hsm, AM_HSM_STATE_CTOR(S1)) is true, but am_hsm_state_is_eq(hsm, AM_HSM_STATE_CTOR(S)) is false.

Parameters:
  • hsm – the HSM

  • state – the state to compare against

Return values:
  • true – the active HSM state equals state

  • false – the active HSM state DOES NOT equal state

int am_hsm_get_instance(const struct am_hsm *hsm)

Get HSM submachine instance.

Always returns the submachine instance of the calling state function. Calling the function from a state that is not part of any submachine will always return 0.

Parameters:

hsm – the HSM

Returns:

the submachine instance

struct am_hsm_state am_hsm_get_state(const struct am_hsm *hsm)

Get HSM’s active state.

E.g., assume HSM is in state S11, which is a substate of S1, which is in turn a substate of S. In this case this function always returns S11.

Parameters:

hsm – the HSM

Returns:

the active state

void am_hsm_ctor(struct am_hsm *hsm, struct am_hsm_state state)

HSM constructor.

Parameters:
void am_hsm_dtor(struct am_hsm *hsm)

HSM destructor.

Exits all HSM states. Call am_hsm_ctor() to construct HSM again.

Parameters:

hsm – the HSM to destruct

void am_hsm_init(struct am_hsm *hsm, const struct am_event *init_event)

Perform HSM initial transition.

Call the initial state set by am_hsm_ctor() with provided optional initial event.

Parameters:
  • hsm – the HSM to init

  • init_event – the init event. Can be NULL.

void am_hsm_set_spy(struct am_hsm *hsm, am_hsm_spy_fn spy)

Set spy user callback as one place to catch all events for the given HSM.

Is only available if “hsm.c” file is compiled with AM_HSM_SPY defined. Should only be used for debugging purposes. Should only be called after calling am_hsm_ctor() and not during ongoing HSM event processing.

Parameters:
  • hsm – the HSM to spy

  • spy – the spy callback. Use NULL to unset.

enum am_hsm_rc am_hsm_top(struct am_hsm *hsm, const struct am_event *event)

Ultimate top state of any HSM.

Every HSM has the same explicit top state, which surrounds all other elements of the entire state machine. One should never target the top state in a state transition.

Has the same signature as am_hsm_state_fn

FSM

enum am_fsm_evt_id

FSM events.

Values:

enumerator AM_EVT_FSM_ENTRY

Entry event. Run entry action(s) for a given state. No state transition is allowed in response to this event.

enumerator AM_EVT_FSM_EXIT

Exit event. Run exit action(s) for a given state. No state transition is allowed in response to this event.

enum am_fsm_rc

FSM state handler return codes. These return codes are not used directly in user code. Instead user code is expected to use as return values the macros listed in descriptions to each of the constants.

Values:

enumerator AM_FSM_RC_HANDLED

Returned by AM_FSM_HANDLED()

enumerator AM_FSM_RC_TRAN

Returned by AM_FSM_TRAN()

enumerator AM_FSM_RC_TRAN_REDISPATCH

Returned by AM_FSM_TRAN_REDISPATCH()

typedef enum am_fsm_rc (*am_fsm_state_fn)(struct am_fsm *fsm, const struct am_event *event)

FSM state (event handler) function type.

Param fsm:

the FSM

Param event:

the event to handle

Return:

return code

typedef void (*am_fsm_spy_fn)(struct am_fsm *fsm, const struct am_event *event)

FSM spy callback type.

Used as one place to catch all events for the given FSM. Called on each user event BEFORE the event is processes by the FSM. Should only be used for debugging purposes. Set by am_fsm_set_spy(). Only supported if “fsm.c” is compiled with AM_FSM_SPY defined.

Param fsm:

the handler of FSM to spy

Param event:

the event to spy

AM_FSM_STATE_CTOR(s)

Get FSM state from FSM event handler.

Parameters:
  • s – FSM event handler

Returns:

FSM state

struct am_fsm

FSM state

AM_FSM_HANDLED()

Event processing is over. No transition is taken. Used as a default return value from FSM event handlers.

AM_FSM_TRAN(s)

Event processing is over. Transition is taken.

It should never be returned for AM_EVT_FSM_ENTRY or AM_EVT_FSM_EXIT events.

Parameters:
AM_FSM_TRAN_REDISPATCH(s)

Event redispatch is requested. Transition is taken.

It should never be returned for AM_EVT_FSM_ENTRY or AM_EVT_FSM_EXIT events. Do not redispatch the same event more than once within same am_fsm_dispatch() call.

Parameters:
void am_fsm_dispatch(struct am_fsm *fsm, const struct am_event *event)

Synchronous dispatch of event to a given FSM.

Parameters:
  • fsm – the FSM

  • event – the event to dispatch

bool am_fsm_is_in(const struct am_fsm *fsm, am_fsm_state_fn state)

Test whether FSM is in a given state.

Parameters:
  • fsm – the FSM

  • state – the state to check

Return values:
  • false – not in the state

  • true – in the state

am_fsm_state_fn am_fsm_get_state(const struct am_fsm *fsm)

Get FSM’s active state.

Parameters:

fsm – the FSM

Returns:

the active state

void am_fsm_ctor(struct am_fsm *fsm, am_fsm_state_fn state)

FSM constructor.

Parameters:
  • fsm – the FSM to construct

  • state – the initial state of the FSM object The initial state must return AM_FSM_TRAN(s)

void am_fsm_dtor(struct am_fsm *fsm)

FSM destructor.

Exits any FSM state. Call am_fsm_ctor() to construct FSM again.

Parameters:

fsm – the FSM to destruct

void am_fsm_init(struct am_fsm *fsm, const struct am_event *init_event)

Perform FSM initial transition.

Call the initial state set by am_fsm_ctor() with provided optional init event.

Parameters:
  • fsm – the FSM to init

  • init_event – the init event. Can be NULL.

void am_fsm_set_spy(struct am_fsm *fsm, am_fsm_spy_fn spy)

Set spy user callback as one place to catch all events for the given FSM.

It is only available if “fsm.c” is compiled with AM_FSM_SPY defined. Should only be used for debugging purposes. Should only be called after calling am_fsm_ctor() and not during ongoing FSM event processing.

Parameters:
  • fsm – the FSM to spy

  • spy – the spy callback. Use NULL to unset.

AO

struct am_ao

The active object.

struct am_ao_state_cfg

Active object library state configuration.

Public Members

void (*debug)(const struct am_ao *ao, const struct am_event *e)

Debug callback.

void (*on_idle)(void)

Callback to enter low power mode

The callback is called with critical section being entered (struct am_ao_state_cfg::crit_enter()) to allow for race condition free transition to low power mode(s). The ao_state_cfg::crit_exit() is called by the library after the callback is returned.

Please read the article called “Use an MCU’s low-power modes in foreground/background systems” by Miro Samek for more information about the reasoning of the approach.

void (*crit_enter)(void)

Enter critical section.

void (*crit_exit)(void)

Exit critical section.

AM_AO_NUM_MAX

The maximum number of active objects.

AM_AO_PRIO_INVALID

Invalid AO priority.

AM_AO_PRIO_MIN

The minimum AO priority level.

AM_AO_PRIO_MAX

The maximum AO priority level.

AM_AO_PRIO_IS_VALID(ao)

Checks if active object priority is valid.

struct am_ao_subscribe_list

The subscribe list for one event.

bool am_ao_publish_exclude_x(const struct am_event *event, const struct am_ao *ao, int margin)

Publish event to all subscribed active objects except one (eXtended version).

The event is delivered to event queues of all the active objects, which are subscribed to the event ID excluding the specified AO. The event is then handled asynchronously by the active objects.

Might be useful if the AO publishing the event does not want the library to route the same event back to this AO.

Use am_ao_subscribe() to subscribe an active object to an event ID. Use am_ao_unsubscribe() to unsubscribe it from the event ID or am_ao_unsubscribe_all() to unsubscribe it from all event IDs.

Guarantees availability of margin free slots in destination event queues after the event was delivered to subscribed active objects.

If any active object has full event queue and cannot accommodate the event, then the function skips the event delivery to the active object.

If your application is not prepared for loosing the event, then use am_ao_publish_exclude() function instead.

Internally the event is pushed to subscribed active object event queues using am_event_push_back() function.

Tries to free the event, if it was not delivered to any subscriber.

The library takes care of freeing the event once all subscribed active objects handled it. This is done asynchronously after this function returns.

Statically allocated events, i.e. events for which am_event_is_static() returns true, are never freed.

The function is fast, thread safe and usable from interrupt service routines (ISR).

Parameters:
  • event – the event to publish

  • ao – do not post the event to this active object even if it is subscribed to the event. If set to NULL, the the API behaves same way as am_ao_publish_x()

  • margin – free event queue slots to be available in each subscribed active object after the event is pushed to their event queues

Return values:
  • true – the event was delivered to all subscribed active objects except the active object given as the parameter

  • false – at least one delivery has failed

void am_ao_publish_exclude(const struct am_event *event, const struct am_ao *ao)

Publish event to all subscribed active objects except one.

Same as am_ao_publish_exclude_x() except this function crashes with assert if it fails delivering the event to at least one subscribed active object.

Parameters:
  • event – the event to publish

  • ao – do not post the event to this active object even if it is subscribed to the event. If set to NULL, the the API behaves same way as am_ao_publish()

bool am_ao_publish_x(const struct am_event *event, int margin)

Publish event to all subscribed active objects (eXtended version).

The event is delivered to event queues of all the active objects, which are subscribed to the event ID including the AO publishing the event. The event is then handled asynchronously by the active objects.

Use am_ao_subscribe() to subscribe an active object to an event ID. Use am_ao_unsubscribe() to unsubscribe it from the event ID or am_ao_unsubscribe_all() to unsubscribe it from all event IDs.

If any active object has full event queue and cannot accommodate the event, then the function skips the event delivery to the active object.

If your application is not prepared for loosing the event, then use am_ao_publish() function instead.

Internally the event is pushed to subscribed active object event queues using am_event_push_back() function.

Tries to free the event, if it was not delivered to any subscriber.

The library takes care of freeing the event once all subscribed active objects handled it. This is done asynchronously after this function returns.

Statically allocated events, i.e. events for which am_event_is_static() returns true, are never freed.

The function is fast, thread safe and usable from interrupt service routines (ISR).

Parameters:
  • event – the event to publish

  • margin – free event queue slots to be available in each subscribed active object after the event is pushed to their event queues

Return values:
  • true – the event was delivered to all subscribed active objects

  • false – at least one delivery has failed

void am_ao_publish(const struct am_event *event)

Publish event to all subscribed active objects.

Same as am_ao_publish_x() except this function crashes with assert if it fails delivering the event to at least one subscribed active object.

Parameters:

event – the event to publish

bool am_ao_post_fifo_x(struct am_ao *ao, const struct am_event *event, int margin)

Post event to the back of active object’s event queue (eXtended version).

The event is then handled asynchronously by the active object.

Guarantees availability of margin free slots in destination event queue after the event was delivered to the active object.

Tries to free the event, if it was not posted.

The library takes care of freeing the event once the active object handled the event. This is done asynchronously after this function returns.

Statically allocated events, i.e. events for which am_event_is_static() returns true are never freed.

The function is fast, thread safe and usable from interrupt service routines (ISR).

Parameters:
  • ao – the event is posted to this active object

  • event – the event to post

  • margin – free event queue slots to be available after event was posted

Return values:
  • true – the event was posted

  • false – the event was not posted

void am_ao_post_fifo(struct am_ao *ao, const struct am_event *event)

Post event to the back of active object’s event queue.

Same as am_ao_post_fifo_x() except this function crashes with assert if it fails delivering the event to the active object.

Parameters:
  • ao – the event is posted to this active object

  • event – the event to post

bool am_ao_post_lifo_x(struct am_ao *ao, const struct am_event *event, int margin)

Post event to the front of AO event queue (eXtended version).

The event is then handled asynchronously by the active object.

If active object’s event queue is full and margin is >0, then the function fails gracefully.

Tries to free the event, if it was not posted.

The library takes care of freeing the event once the active object handled the event. This is done asynchronously after this function returns.

Statically allocated events, i.e. events for which am_event_is_static() returns true, are never freed.

Parameters:
  • ao – the event is posted to this active object

  • event – the event to post

  • margin – free event queue slots to be available after event was posted

Return values:
  • true – the event was posted

  • false – the event was not posted

void am_ao_post_lifo(struct am_ao *ao, const struct am_event *event)

Post event to the front of active object’s event queue.

Same as am_ao_post_lifo_x() except this function crashes with assert if it fails delivering the event to the active object.

Parameters:
  • ao – the event is posted to this active object

  • event – the event to post

void am_ao_ctor(struct am_ao *ao, struct am_hsm_state state)

Active object constructor.

Parameters:
  • ao – the active object to construct

  • state – the initial state of the active object

void am_ao_start(struct am_ao *ao, int prio, const struct am_event *queue[], int queue_size, void *stack, int stack_size, const char *name, const struct am_event *init_event)

Start active object.

Start managing the active object as part of application.

The safest is to start active objects in the order of their priority, beginning from the lowest priority active objects because they tend to have the bigger event queues.

Parameters:
  • ao – the active object to start

  • prio – priority level [AM_AO_PRIO_MIN, AM_AO_PRIO_MAX]

  • queue – the active object’s event queue

  • queue_size – the event queue size [sizeof(struct am_event*)]

  • stack – active object stack

  • stack_size – the stack size [bytes]

  • name – human readable name of active object. Not copied. Must remain valid after the call. Can be NULL.

  • init_event – init event. Can be NULL. The event is not freed. The caller is responsible for freeing the event after the call.

void am_ao_stop(struct am_ao *ao)

Stop active object.

Can only be called by the active object itself. The active object is expected to release all allocated resources before calling this function.

Parameters:

ao – the active object to stop

void am_ao_state_ctor(const struct am_ao_state_cfg *cfg)

Active object library state constructor.

Parameters:

cfg – active object library configuration The active object module makes an internal copy of the configuration.

void am_ao_subscribe(const struct am_ao *ao, int event)

Subscribe active object to event ID.

The event ID must be smaller than the the number of elements in the array of active object subscribe lists provided to am_ao_init_subscribe_list().

Parameters:
  • ao – active object to subscribe

  • event – the event ID to subscribe to

void am_ao_unsubscribe(const struct am_ao *ao, int event)

Unsubscribe active object from event ID.

The event ID must be smaller than the the number of elements in the array of active object subscribe lists provided to am_ao_init_subscribe_list().

Parameters:
  • ao – active object to unsubscribe

  • event – the event ID to unsubscribe from

void am_ao_unsubscribe_all(const struct am_ao *ao)

Unsubscribe active object from all events.

Parameters:

ao – active object to unsubscribe

void am_ao_init_subscribe_list(struct am_ao_subscribe_list *sub, int nsub)

Initialize active object global subscribe list.

Optional. Only needed if active object pub/sub functionality is used. The pub/sub functionality is provided by am_ao_publish(), am_ao_publish_x(), am_ao_subscribe(), am_ao_unsubscribe() and am_ao_unsubscribe_all() APIs.

Parameters:
  • sub – the array of active object subscribe lists

  • nsub – the number of elements in sub array

bool am_ao_run_all(void)

Run all active objects.

Blocks for preemptive AO build and returns when all active objects were stopped.

What follows only applies to cooperative build of AO.

Executes initial transition of all newly started active objects.

Non blocking and returns after dispatching zero or one event.

The function is expected to be called repeatedly to dispatch events to active objects.

If zero events were dispatched (the function returned false), then the event processor is in idle state.

Return values:
  • true – dispatched one event

  • false – dispatched no events Call am_ao_get_cnt() to make sure there are still started active objects available.

bool am_ao_event_queue_is_empty(struct am_ao *ao)

Check if active object event queue is empty.

Used for debugging.

Parameters:

ao – check the event queue of this active object

Return values:
  • true – the queue is empty

  • false – the queue is not empty

void am_ao_log_event_queues(int num, void (*log)(const char *name, int i, int len, int cap, const struct am_event *event))

Log the content of the first num events in each event queue of every AO.

Used for debugging.

Parameters:
  • num – the number of events to log. Use -1 to log all events.

  • log – the logging callback

void am_ao_log_last_events(void (*log)(const char *name, int event))

Log last event of every active object.

Used for debugging.

Parameters:

log – the logging callback

void am_ao_wait_start_all(void)

Block until all active objects are ready to run.

Prevents using active objects before they are ready to process events.

To be run once at the start of regular user threads started with am_pal_task_create() API running blocking calls and using active objects for event posting/publishing.

int am_ao_get_cnt(void)

Get number of running active objects.

Returns:

the number of running active objects.

int am_ao_get_own_prio(void)

Get active object own priority level.

Returns:

the priority level

PAL

AM_PAL_TASK_NUM_MAX

Maximum number of PAL tasks

AM_PAL_TASK_ID_NONE

Invalid task ID

AM_PAL_TASK_ID_MAIN

Main task ID

AM_PAL_TICK_DOMAIN_DEFAULT

Default tick domain

AM_PAL_TICK_DOMAIN_MAX

total number of tick domains

void am_pal_ctor(void)

PAL constructor.

void am_pal_dtor(void)

PAL destructor.

void am_pal_crit_enter(void)

Enter critical section.

Non reentrant.

void am_pal_crit_exit(void)

Exit critical section.

Non reentrant.

int am_pal_mutex_create(void)

Create mutex.

Returns:

unique mutex ID

void am_pal_mutex_lock(int mutex)

Lock mutex.

Parameters:

mutex – mutex ID returned by am_pal_mutex_create()

void am_pal_mutex_unlock(int mutex)

Unlock mutex.

Parameters:

mutex – mutex ID returned by am_pal_mutex_create()

void am_pal_mutex_destroy(int mutex)

Destroy mutex.

Parameters:

mutex – mutex ID returned by am_pal_mutex_create()

int am_pal_task_create(const char *name, int priority, void *stack, int stack_size, void (*entry)(void *arg), void *arg)

Create task.

Parameters:
  • name – human readable task name. Not copied. Must remain valid after the call.

  • priority – task priority (>=0)

  • stack – task stack

  • stack_size – task stack size [bytes]

  • entry – task entry function

  • arg – task entry function argument. PAL does not use other than providing it as an argument to task entry function

Returns:

unique task ID

void am_pal_task_notify(int task)

Wake up PAL task.

Parameters:

task – task ID returned by am_pal_task_create()

void am_pal_task_wait(int task)

Block PAL task till am_pal_task_notify() is called.

Parameters:

task – task ID returned by am_pal_task_create()

int am_pal_task_get_own_id(void)

Return task own ID.

Returns:

task ID

uint32_t am_pal_time_get_ms(void)

Get current time in milliseconds.

Returns:

current time [ms]

uint32_t am_pal_time_get_tick(int domain)

Get current time in ticks.

Parameters:

domain – tick domain [0..AM_PAL_TICK_DOMAIN_MAX]

Returns:

current time [tick]

uint32_t am_pal_time_get_tick_from_ms(int domain, uint32_t ms)

Convert ms to ticks for the given tick domain.

Parameters:
  • domain – tick domain [0..AM_PAL_TICK_DOMAIN_MAX]

  • ms – milliseconds to convert

Returns:

time [tick]

uint32_t am_pal_time_get_ms_from_tick(int domain, uint32_t tick)

Convert ticks from the given tick domain to milliseconds.

Parameters:
  • domain – tick domain [0..AM_PAL_TICK_DOMAIN_MAX]

  • tick – ticks to convert

Returns:

time [ms]

void am_pal_sleep_ticks(int domain, int ticks)

Sleep for given number of ticks from the given tick domain.

Parameters:
  • domain – tick domain [0..AM_PAL_TICK_DOMAIN_MAX]

  • ticks – ticks to sleep. Sleep forever if ticks < 0.

void am_pal_sleep_till_ticks(int domain, uint32_t ticks)

Sleep till the given number of ticks from the given tick domain.

Parameters:
  • domain – tick domain [0..AM_PAL_TICK_DOMAIN_MAX]

  • ticks – sleep till this ticks value

void am_pal_sleep_ms(int ms)

Sleep for given number of milliseconds.

Parameters:

ms – milliseconds to sleep. Sleep forever if ms < 0.

void am_pal_sleep_till_ms(uint32_t ms)

Sleep till the given number of milliseconds.

Parameters:

ms – sleep till this milliseconds value

int am_pal_printf(const char *fmt, ...)

printf-like logging.

Parameters:

fmt – printf-like format string

Returns:

printf-like return value

void am_pal_flush(void)

Flush am_pal_printf() intermediate buffer.

void am_pal_on_idle(void)

Block current task with am_pal_task_wait() call.

Exists critical section before calling am_pal_task_wait() and reenters it after am_pal_task_wait() returns.

To be used as on_idle() callback for cooperative active objects library.