API

This part of the documentation covers all the Amast interfaces.

Common Macros And Constants

AM_ALIGNOF(type)

Type alignment.

Must be preceded by AM_ALIGNOF_DEFINE for the same type.

Parameters:
  • type – return the alignment of this type [bytes]

Returns:

the type alignment [bytes]

AM_ALIGNOF_DEFINE(type)

Use this macro before using AM_ALIGNOF() for the same type.

Parameters:
  • type – the type to define. Must be one word. For example, “struct foo” will not work, but foo_t will, where “typedef struct foo foo_t”.

AM_ALIGNOF_PTR(ptr)

Pointer alignment.

Parameters:
  • ptr – return the alignment of this pointer [bytes]

Returns:

the pointer alignment [bytes]

AM_ALIGN_MAX

The maximum compiler alignment [bytes].

AM_ALIGN_PTR_DOWN(ptr, align)

Align pointer to the smaller value, which has align alignment.

Parameters:
  • ptr – the pointer to align

  • align – the alignment [bytes]. Must be power of 2.

Returns:

the aligned pointer

AM_ALIGN_PTR_UP(ptr, align)

Align pointer to the bigger value, which has align alignment.

Parameters:
  • ptr – the pointer to align

  • align – the alignment [bytes]. Must be power of 2.

Returns:

the aligned pointer

AM_ALIGN_SIZE(size, align)

Return size + the byte difference between aligned and unaligned size.

For example,

AM_ALIGN_SIZE(3, 4) == 4

AM_ALIGN_SIZE(4, 4) == 4

AM_ALIGN_SIZE(5, 4) == 8

AM_ASSERT(x)

Assert macro.

AM_ASSERT_STATIC(cond)

Compile time assert

AM_CAST(TYPE, PTR)

Cast pointer to type.

Parameters:
  • TYPE – the type

  • PTR – the pointer

AM_COUNTOF(arr)

Returns number of elements in the array. Note two tricks:

  1. putting the array name in the index operator (‘[]’) instead of the 0. This is done in case the macro is mistakenly used in C++ code with an item that overloads operator[](). The compiler will complain instead of giving a bad result.

  2. if a pointer is mistakenly passed as the argument, the compiler will complain in some cases - specifically, if the pointer’s size isn’t evenly divisible by the size of the object the pointer points to. In that situation a divide-by-zero will cause the compiler to error out.

AM_CONTAINER_OF(ptr, type, member)

Taken from http://nullprogram.com/blog/2015/02/17/

AM_MAX(a, b)

Returns maximum element.

AM_MIN(a, b)

Returns minimum element.

AM_VCAST(TYPE, PTR)

Cast volatile pointer to type.

Parameters:
  • TYPE – the type

  • PTR – the volatile pointer

Common Types

enum am_rc

Return codes.

Values:

enumerator AM_RC_ERR

Common error

enumerator AM_RC_OK

Success.

enumerator AM_RC_ASYNC_BUSY

Async/await operation is ongoing. Event was handled.

enumerator AM_RC_ASYNC_DONE

Async/await operation is complete. Event was handled.

enumerator AM_RC_HANDLED

Event was handled.

enumerator AM_RC_TRAN

Event caused state transition.

enumerator AM_RC_TRAN_REDISPATCH

Event caused state transition and redispatch.

enumerator AM_RC_SUPER

Event propagation to superstate(s) was requested.

enumerator AM_RC_QUEUE_WAS_EMPTY

Tells that event queue was empty before the corresponding call. This allows to signal the event queue owner about new event available for processing.

struct am_blk

Memory block descriptor.

Public Members

void *ptr

memory pointer

int size

memory size [bytes]

Singly Linked List

Singly linked list API documentation.

The source code of the corresponding header file is in slist.h.

struct am_slist_item

Singly linked list 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)

Construct singly linked list.

Must be called before calling any other singly linked list API functions.

Singly linked list implementation.

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.

Initializes the list item as not being part to any list.

Parameters:

item – the 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.

Used by am_slist_find() API.

Param context:

the predicate context

Param item:

the item to analyze

Retval true:

the item was found

Retval false:

the 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 callback function.

The found item is not popped from the list.

Parameters:
  • list – the list

  • is_found – the predicate callback

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

Returns:

the item, found by the predicate callback function or NULL, if nothing was found.

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 the list is empty

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 list is empty

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 is 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.

Takes O(n) to complete.

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 – return next list item after this one

Returns:

the 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. The handler is initialized after the list is appended. So this list becomes empty after it gets 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 was already 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

Bit API documentation.

The source code of the corresponding header file is in bit.h.

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

Return values:
  • true – the bit array is empty

  • false – the 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

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

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)

Clear a bit with index n to 1.

Parameters:
  • u64 – the bit array

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

Ring Buffer

Ring buffer API documentation.

The source code of the corresponding header file is in ringbuf.h.

struct am_ringbuf

Ring buffer descriptor.

Only exposed to allow ring buffer users to allocate (possibly static) memory for it.

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

Construct ring buffer.

Must be called before calling any other ring buffer API.

Ring buffer API implementation.

Parameters:
  • rb – the ring buffer

  • buf – the ring buffer’s memory

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

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

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.

  • size – the byte size of the memory pointed to by ptr is returned here. Can be 0.

Returns:

true if the ring buffer state was updated and false otherwise

bool 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 [bytes]. 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.

Returns:

true if the ring buffer state was updated and false otherwise

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 number of 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 number of 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

Onesize

Onesize memory allocator API documentation.

The source code of the corresponding header file is in onesize.h.

struct am_onesize

Onesize memory allocator descriptor.

struct am_onesize_cfg

Onesize configuration.

Public Members

struct am_blk pool

The memory pool.

int block_size

The maximum size of the memory block the allocator can allocate [bytes]. The allocation of memory blocks bigger that this size will fail.

int alignment

The alignment of allocated memory blocks [bytes].

void (*crit_enter)(void)

Enter critical section.

void (*crit_exit)(void)

Exit critical section.

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 from onesize configuration 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 configured 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.

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.

Parameters:
  • hnd – the allocator

  • ptr – memory block to free

void am_onesize_free_all(struct am_onesize *hnd)

Free 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_unsafe(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.

Not thread safe.

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)

Return 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 observed so far.

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

Parameters:

hnd – the allocator

Returns:

the minimum number of free memory blocks observed so far

int am_onesize_get_block_size(const struct am_onesize *hnd)

Return 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 memory blocks

Event

Event API documentation.

The source code of the corresponding header file is in event.h.

AM_EVT_EMPTY

Empty event.

User event handlers should take care of not causing any side effects when called with this event.

The event handlers must return the AM_HSM_SUPER() in response to this event in HSM library.

AM_EVT_INIT

Init event.

Run optional initial transition from a given state.

Always follows the AM_EVT_ENTRY event.

AM_EVT_ENTRY

Entry event.

Run entry action(s) for a given state.

No state transition is allowed in response to this event.

AM_EVT_EXIT

Exit event.

Run exit action(s) for a given state.

No state transition is allowed in response to this event.

AM_EVT_USER

The event IDs smaller than 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 – the event to check

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

  • false – the event does not have valid user event ID

struct am_event

Event descriptor.

struct am_event_queue

Event queue handler.

struct am_event_state_cfg

Event library state configuration.

Public Members

void (*crit_enter)(void)

Enter critical section. Must be not NULL.

void (*crit_exit)(void)

Exit critical section. Must be not NULL.

void am_event_state_ctor(const struct am_event_state_cfg *cfg)

Event library state constructor.

Must be called before calling any other event library APIs.

Thread unsafe.

Parameters:

cfg – event library state configuration. The event library makes an internal copy of the configuration. Can be NULL.

void am_event_queue_ctor(struct am_event_queue *queue, const struct am_event *events[], int nevents)

Construct event queue with a array of event pointers.

Parameters:
  • queue – the queue

  • events – the array of event pointers

  • nevents – the number of event pointers in events

void am_event_queue_dtor(struct am_event_queue *queue)

Destruct event queue.

Parameters:

queue – the queue

bool am_event_queue_is_valid(const struct am_event_queue *queue)

Check if constructor was called for event queue.

Thread safe.

Parameters:

queue – the event queue

Return values:
  • true – the queue is valid

  • false – the queue is invalid

bool am_event_queue_is_empty(const struct am_event_queue *queue)

Check if event queue is empty.

Thread safe.

Parameters:

queue – the event queue

Return values:
  • true – queue is empty

  • false – queue is not empty

int am_event_queue_get_nbusy_unsafe(const struct am_event_queue *queue)

Return how many items are in event queue.

Thread unsafe.

Parameters:

queue – the event queue

Returns:

number of queued events

int am_event_queue_get_nfree_min(const struct am_event_queue *queue)

Get minimum number of free slots ever observed in event queue.

Could be used to assess the usage of the event queue.

Thread safe.

Parameters:

queue – the event queue

Returns:

the minimum number of slots observed so far

int am_event_queue_get_capacity(const struct am_event_queue *queue)

Return event queue capacity.

Thread usafe.

Parameters:

queue – the event queue

Returns:

the event queue capacity in number of items (slots)

const struct am_event *am_event_queue_pop_front(struct am_event_queue *queue)

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

Takes O(1) to complete.

Thread safe.

Parameters:

queue – the event queue

Returns:

The popped item or NULL, if event queue was empty.

enum am_rc am_event_queue_push_back_x(struct am_event_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 (the events for which am_event_is_static() returns true) are never freed.

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – the event queue

  • event – the event to push

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

Return values:
  • AM_RC_OK – the event was pushed

  • AM_RC_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_RC_ERR – the event was not pushed

enum am_rc am_event_queue_push_back(struct am_event_queue *queue, const struct am_event *event)

Push event to the back of event queue.

Asserts, if the event was not pushed.

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – the event queue

  • event – the event to push

Return values:
  • AM_RC_OK – the event was pushed

  • AM_RC_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

enum am_rc am_event_queue_push_back_unsafe(struct am_event_queue *queue, const struct am_event *event)

Push event to the back of event queue without using critical section (unsafe).

Asserts, if the event was not pushed.

Thread unsafe.

So far the only use of this function was as a part of the implementation of am_timer_publish_fn callback in timer library.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – the event queue

  • event – the event to push

Return values:
  • AM_RC_OK – the event was pushed

  • AM_RC_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

enum am_rc am_event_queue_push_front_x(struct am_event_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 (the events for which am_event_is_static() returns true) are never freed.

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – the event queue

  • event – the event to push

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

Return values:
  • AM_RC_OK – the event was pushed

  • AM_RC_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

  • AM_RC_ERR – the event was not pushed

enum am_rc am_event_queue_push_front(struct am_event_queue *queue, const struct am_event *event)

Push event to the front of event queue.

Asserts, if the event was not pushed.

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – the event queue

  • event – the event to push

Return values:
  • AM_RC_OK – the event was pushed

  • AM_RC_QUEUE_WAS_EMPTY – the event was pushed, queue was empty

enum am_rc am_event_queue_pop_front_with_cb(struct am_event_queue *queue, am_event_handle_fn cb, void *ctx)

Pop event from the front of event queue.

Pops event from the front of event queue and calls the provided callback with the event.

Tries to free the popped event after the callback call.

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

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • queue – queue of events

  • cb – the popped event is provided to this callback. If set to NULL, then event is popped and immediately recycled. Therefore cb set to NULL can be used, when the queue of events needs to be fully or partially emptied to make space for newer events.

  • ctx – the callback context

Return values:
  • AM_RC_OK – the event was popped

  • AM_RC_ERR – the event was not popped

int am_event_queue_flush(struct am_event_queue *queue)

Flush all events from event queue.

Takes care of recycling the events by calling am_event_free().

Thread safe.

Parameters:

queue – the event queue to flush

Returns:

the number of events flushed

void am_event_pool_add(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.

Thread unsafe.

Must be called before using any event allocation APIs.

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_pool_get_nfree(int index)

Get number of free memory blocks.

Thread safe.

Use sparingly as the return value could be volatile due to multitasking.

Parameters:

index – memory pool index

Returns:

the number of free blocks available now in the memory pool

int am_event_pool_get_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.

Parameters:

index – memory pool index

Returns:

the minimum number of memory blocks observed so far in the memory pool

int am_event_pool_get_nblocks(int index)

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

Thread safe.

Parameters:

index – the pool index

Returns:

the number of memory blocks

int am_event_pool_get_num(void)

The number of registered pools.

Thread safe.

Returns:

the number of pools

void am_event_pool_log_unsafe(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.

Thread usafe.

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

  • cb – the logging callback

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_pool_add() 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.

There are limitations to what application code can do with the event returned by this function. Please consult the Event Ownership Diagram to understand the limitations.

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_pool_add() function.

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

Thread safe.

There are limitations to what application code can do with the event returned by this function. Please consult the Event Ownership Diagram to understand the limitations.

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.

The event is either static or allocated earlier with am_event_allocate(), am_event_dup() or am_event_dup_x() API calls.

Decrements event reference counter by one and frees the event, if the reference counter drops to zero.

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

Thread safe.

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 by am_event_pool_add() 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.

There are limitations to what application code can do with the event returned by this function. Please consult the Event Ownership Diagram to understand the limitations.

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 by am_event_pool_add() function.

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

Thread safe.

There are limitations to what application code can do with the event returned by this function. Please consult the Event Ownership Diagram to understand the limitations.

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.

Used as a parameter to am_event_pool_log_unsafe() API.

Param pool_index:

pool index

Param event_index:

event_index within the pool

Param event:

event to log

Param size:

the event size [bytes]

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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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 - the events for which am_event_is_static() returns true.

Thread safe.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:

event – the event

int am_event_get_ref_cnt(const struct am_event *event)

Return event reference counter.

Thread safe.

Use sparingly as the return value could be volatile due to multitasking.

Parameters:

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

Returns:

the event reference counter

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

The type of a callback used to handle popped events.

Used as a parameter to am_event_queue_pop_front_with_cb() API.

Param ctx:

the callback context

Param event:

the popped event

Timer

Timer API documentation.

The source code of the corresponding header file is in timer.h.

struct am_timer

Timer state.

struct am_timer_event

Timer event.

struct am_timer_event_x

Time event with context.

void am_timer_ctor(struct am_timer *timer)

Timer state constructor.

Parameters:

timer – the timer state

static inline struct am_timer_event am_timer_event_ctor(uint16_t id)

Timer event constructor.

Parameters:

id – the event ID

Returns:

the constructed event

static inline struct am_timer_event_x am_timer_event_ctor_x(uint16_t id, void *ctx)

Extended timer event constructor.

Parameters:
  • id – the event ID

  • ctx – the event context

Returns:

the constructed event

void am_timer_register_cbs(struct am_timer *timer, void (*crit_enter)(void), void (*crit_exit)(void))

Register callbacks with timer state.

Parameters:
  • timer – the timer state

  • crit_enter – enter critical section

  • crit_exit – exit critical section

void am_timer_tick_iterator_init(struct am_timer *timer)

Initialize tick iterator.

Must be called exactly once every ticks and must precede am_timer_tick_iterator_next() calls.

Parameters:

timer – timer state

struct am_timer_event *am_timer_tick_iterator_next(struct am_timer *timer)

Iterate tick to next timer event.

Must follow am_timer_tick_iterator_init() call. Must be called every tick until it retuns a non-null value.

Parameters:

timer – tick timer events in this timer state

Returns:

Fired timer event or NULL.

void am_timer_arm(struct am_timer *timer, struct am_timer_event *event, uint32_t ticks, uint32_t interval)

Arm timer event.

It is fine to arm an already armed timer event. The timer event is re-armed in this case.

Parameters:
  • timer – the timer event to arm

  • event – the timer event

  • ticks – the timer event is to be sent in these many ticks. The valid range is [0, 2^32[

  • interval – the timer event is to be re-sent in these many ticks after the event is sent for the fist time. The valid range [0, 2^31[. Note that the range is two times smaller than the range of the ticks. Can be 0, in which case the timer event is one shot.

bool am_timer_disarm(struct am_timer *timer, struct am_timer_event *event)

Disarm timer event.

It is fine to disarm an already disarmed timer event.

Parameters:
  • timer – the timer state

  • event – the timer event

Return values:
  • true – the timer event was armed

  • false – the timer event was not armed

bool am_timer_is_armed(const struct am_timer *timer, const struct am_timer_event *event)

Check if timer event is armed.

Parameters:
  • timer – the timer state

  • event – the timer event

Return values:
  • true – the timer event is armed

  • false – the timer event is not armed

bool am_timer_is_empty_unsafe(const struct am_timer *timer)

Check if timer state has armed timer events.

The function is to be called from a critical section.

Can be used to check if there are any pending timer events just before going to sleep mode while in critical section. As it does not enter critical section internally there is no risk of recursive critical section entry.

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 why critical section is not used in the function implementation.

Parameters:

timer – the timer state

Return values:
  • true – the timer state has no armed timer events

  • false – the timer state has armed timer events

uint32_t am_timer_get_ticks(const struct am_timer *timer, const struct am_timer_event *event)

Get number of ticks till timer event is sent.

Parameters:
  • timer – the timer handler

  • event – the timer event

Returns:

the timer event will be sent in this number of ticks

Async

Async API documentation.

The source code of the corresponding header file is in async.h.

AM_ASYNC_STATE_INIT

Init value of async function/block state.

Only used by implementation. Not to be used directly by user code.

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/block.

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

AM_ASYNC_END()

Mark the end of async function/block.

Should be called at the end of async function/block.

AM_ASYNC_AWAIT(cond)

Await a condition before proceeding.

Checks the provided condition cond. Returns, if the condition is not met (false) and on next invocation of the function the condition is evaluated again.

Continues the function execution once the cond evaluates to true.

Parameters:
  • cond – the condition to check for continuation

AM_ASYNC_CALL(func)

Chain an async function call and evaluate its return value.

Returns, if the async function call returns AM_RC_ASYNC_BUSY,

The function call is evaluated again on next invocation, if AM_RC_ASYNC_BUSY is returned. Otherwise the execution continues on next invocation without the function call.

Parameters:
  • func – the function to check the return value of

AM_ASYNC_YIELD()

Yield control back to caller.

Allows the async function/block to yield.

Control resumes after this point, when the function is called again.

static inline bool am_async_is_busy(const struct am_async *me)

Check if async operation is in progress.

Parameters:

me – the async state

Returns:

true the async operation is in progress

Returns:

false the async operation is not in progress

static inline void am_async_ctor(struct am_async *me)

Construct async state.

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

Parameters:

me – the async state to construct

HSM

Hierarchical State Machine (HSM) API documentation.

The source code of the corresponding header file is in hsm.h.

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

HSM state (event handler) function type.

Do not assume that a state handler is invoked only for processing event IDs enlisted in case statements of internal switch statement.

Event handlers should avoid using any code outside of the switch statement, especially the code, which has side effects.

Param hsm:

the HSM

Param event:

the event to handle

Retval AM_RC_SUPER:

- event is to be propagated to superstate

Retval AM_RC_ASYNC_BUSY:

- event was handled (no propagation to superstate)

Retval AM_RC_ASYNC_DONE:

- event was handled (no propagation to superstate)

Retval AM_RC_HANDLED:

- event was handled (no propagation to superstate)

Retval AM_RC_TRAN:

- event caused state transition

Retval AM_RC_TRAN_REDISPATCH:

- event caused state transition and redispatch

struct am_hsm_state

HSM state.

AM_HSM_STATE_CTOR(...)

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

Examples:

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 the HSM event handler (mandatory)

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

Returns:

constructed HSM state structure

AM_HSM_HIERARCHY_DEPTH_MAX

HSM hierarchy maximum depth.

Deep HSM hierarchy increases state switch execution time overhead.

struct am_hsm

HSM descriptor.

None of the fields of the descriptor are to be accessed directly by user code. The only purpose of exposing it is to allow user code to reserve memory for it.

AM_HSM_HANDLED()

Event processing is over. No state transition is triggered.

Used as a return value from the event handler, which 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 in response to AM_EVT_ENTRY or AM_EVT_EXIT events.

Conversely, the response to AM_EVT_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.

Examples:

AM_HSM_TRAN(s) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = 0},
 ((struct am_hsm *)me)->smi = 0), AM_RC_TRAN

AM_HSM_TRAN(s, i) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = i},
 ((struct am_hsm *)me)->smi = i), AM_RC_TRAN

Below are the parameters to the macro:

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(...)

Same event redispatch is requested. Transition is triggered.

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

Examples:

AM_HSM_TRAN_REDISPATCH(s) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = 0},
 ((struct am_hsm *)me)->smi = 0), AM_RC_TRAN_REDISPATCH

AM_HSM_TRAN_REDISPATCH(s, i) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = i},
 ((struct am_hsm *)me)->smi = i), AM_RC_TRAN_REDISPATCH

Below are the parameters to the macro:

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 superstate am_hsm_top() must be used.

Examples:

AM_HSM_SUPER(s) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = 0},
 ((struct am_hsm *)me)->smi) = 0, AM_RC_SUPER

AM_HSM_SUPER(s, i) is converted to

(((struct am_hsm *)me)->state = (struct am_hsm_state){.fn = s, .smi = i},
 ((struct am_hsm *)me)->smi = i), AM_RC_SUPER

Below are the parameters to the macro:

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.

Do not free the event in user event handlers - 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)

Check whether HSM is in a given state.

Note that an HSM is simultaneously in all superstates of current active state.

Use sparingly to check states of other state machine(s) 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.

Returns the submachine instance of the calling event handler state function.

Calling the function from an event handler state that is not part of any submachine returns 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 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 current state and all its superstates till am_hsm_top().

The HSM is not usable after this call. 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.

Calls the initial state event handler set by am_hsm_ctor() with the provided optional initial event and performs the initial transition including all recursive initial transitions, if any.

Parameters:
  • hsm – the HSM to init

  • init_event – the initial event. Can be NULL.

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

Ultimate top superstate of any HSM.

Every HSM has the same explicit top superstate, which surrounds all other elements of the entire state machine.

Users should never target the top superstate in a state transition.

Has the same signature as am_hsm_state_fn.

FSM

Finite State Machine (FSM) API documentation.

The source code of the corresponding header file is in fsm.h.

typedef enum am_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

Retval AM_RC_ASYNC_BUSY:

- event was handled (no propagation to superstate)

Retval AM_RC_ASYNC_DONE:

- event was handled (no propagation to superstate)

Retval AM_RC_HANDLED:

- event was handled (no propagation to superstate)

Retval AM_RC_TRAN:

- event caused state transition

Retval AM_RC_TRAN_REDISPATCH:

- event caused state transition and redispatch

AM_FSM_STATE_CTOR(s)

Construct FSM state from FSM event handler.

Parameters:
  • s – the FSM event handler

Returns:

constructed FSM state structure

struct am_fsm

FSM descriptor.

None of the fields of the descriptor are to be accessed directly by user code. The only purpose of exposing it is to allow user code to reserve memory for it.

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 in response to AM_EVT_ENTRY or AM_EVT_EXIT events.

AM_FSM_TRAN(s) is converted to

(((struct am_fsm *)me)->state = (am_fsm_state_fn)(s), AM_RC_TRAN)
Parameters:
AM_FSM_TRAN_REDISPATCH(s)

Same event redispatch is requested. Transition is taken.

It should never be returned for AM_EVT_ENTRY or AM_EVT_EXIT events.

Do not redispatch the same event more than once within same am_fsm_dispatch() call.

AM_FSM_TRAN_REDISPATCH(s) is converted to

(((struct am_fsm *)me)->state = (am_fsm_state_fn)(s), AM_RC_TRAN_REDISPATCH)
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)

Check whether FSM is in a given state.

Use sparingly to check states of other state machine(s) as it breaks encapsulation.

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.

Finite State Machine (FSM) API implementation.

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 current state.

The FSM is not usable after this call. Call am_fsm_ctor() to construct the 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.

Calls the initial state set by am_fsm_ctor() with the provided optional init event and performs the initial transition.

Parameters:
  • fsm – the FSM to init

  • init_event – the init event. Can be NULL.

AO

Active Object (AO) API documentation.

The source code of the corresponding header file is in ao.h.

struct am_ao

The active object.

typedef void (*am_ao_fn)(struct am_ao *ao, const struct am_event *event)

Active object event handler

struct am_ao_state_cfg

Active object library state configuration.

Public Members

void (*on_idle)(void)

Callback to enter low power mode.

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

Do not post or publish events from this callback.

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)

Callback to enter critical section.

void (*crit_exit)(void)

Callback to exit critical section.

struct am_ao_prio

AO priorities.

Public Members

unsigned ao

Define the priority of active object. Used by AO library. Valid range [0, AM_TASK_NUM_MAX[. Must be unique for different active objects. Used by both cooperative and preemptive ports of active objects.

unsigned task

Define the priority of the task, which runs active object. Used by PAL library. Valid range [0, AM_TASK_NUM_MAX[. More than one active object may have same task priority. Only used by preemptive port of active objects.

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(prio)

Check if active object priority is valid.

Parameters:
  • prio – the active object priority

Return values:
  • true – the priority is valid

  • false – the priority is invalid.

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 the given one (eXtended version).

The event is delivered to event queues of all the active objects, which are subscribed to the event 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.

Application might observe changed order of events after the publishing. This change of order might happen, if the publishing is from low-priority active object, which then will get immediately preempted by higher-priority subscribers. This might or might not matter to your application.

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

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

If any active object 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_queue_push_back() function.

Tries to free the event synchronously, 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. the 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).

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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 API behaves same way as am_ao_publish_x()

  • margin – the number of 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 ao

  • false – at least one delivery of the event 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 the given 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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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 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 including the AO publishing the event. The event is then handled asynchronously by the active objects.

Application might observe changed order of events after the publishing. This change of order might happen, if the publishing is from low-priority active object, which then will get immediately preempted by higher-priority subscribers. This might or might not matter to your application.

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

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

If any active object 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_queue_push_back() function.

Tries to free the event synchronously, 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. the 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).

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

Parameters:
  • event – the event to publish

  • margin – the number of 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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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 synchronously, 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).

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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

  • event – the event to post

  • margin – the number of 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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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 synchronously, 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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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

  • event – the event to post

  • margin – the number of 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.

There are limitations to what application code can do with the event after calling this function. Please consult the Event Ownership Diagram to understand the limitations.

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

  • event – the event to post

void am_ao_ctor(struct am_ao *ao, am_ao_fn init_handler, am_ao_fn event_handler, void *ctx)

Active object constructor.

Parameters:
  • ao – the active object to construct

  • init_handler – the init event handler The init event handler is run once on the start of the active object, when the event queue is already initialized. The init event handler can post events to itself. The event queues of other active objects are not guaranteed to be initialized when the init event handler is called. Therefore the init event handler is not allowed to post/publish events to other active objects.

  • event_handler – the event handler

  • ctx – the event handler context

void am_ao_start(struct am_ao *ao, struct am_ao_prio 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.

Starts 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 bigger event queues.

Parameters:
  • ao – the active object to start

  • prio – priority

  • 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 library makes an internal copy of the configuration. Can be NULL.

void am_ao_state_dtor(void)

Active object library state destructor.

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 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 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_publish_exclude(), am_ao_publish_exclude_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 library build and returns when all active objects were stopped.

What follows only applies to cooperative library 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 no 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 running 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_crash_dump_event_queues_unsafe(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.

Only suitable for crash handlers to log the state of event queues of all AOs.

Not thread safe.

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 (non-AO) user tasks created with am_task_create() API. These regular user tasks are typically used to execute blocking calls and post/publish events to active objects.

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

The source code of the corresponding header file is in pal.h.

Platform Abstraction Layer (PAL) API documentation.

Defines

AM_TASK_NUM_MAX

Maximum number of PAL tasks.

AM_TASK_ID_NONE

Invalid task ID.

AM_TASK_ID_MAIN

Main task ID.

AM_TASK_FLAG_DETACH

Mark task as non-joinable

AM_TICK_DOMAIN_DEFAULT

Default tick domain.

Functions

void *am_pal_ctor(void *arg)

PAL constructor.

Parameters:

arg – platform specific handler. Can be NULL.

Returns:

Platform specific handler. Can be NULL.

void am_pal_dtor(void)

PAL destructor.

void am_crit_enter(void)

Enter critical section.

Not nestable.

void am_crit_exit(void)

Exit critical section.

Not nestable.

int am_mutex_create(void)

Create mutex.

Returns:

unique mutex ID

void am_mutex_lock(int mutex)

Lock mutex.

If the mutex is locked by another task, the calling task waits until the mutex becomes available.

A task is not permitted to lock a mutex it has already locked.

May not be called from ISRs.

Parameters:

mutex – the mutex ID returned by am_mutex_create()

void am_mutex_unlock(int mutex)

Unlock mutex.

The mutex must already be locked with am_mutex_lock() by the calling task.

The mutex cannot be claimed by another task until it has been unlocked by the calling task.

Mutexes may not be unlocked in ISRs.

Parameters:

mutex – the mutex ID returned by am_mutex_create()

void am_mutex_destroy(int mutex)

Destroy mutex.

Parameters:

mutex – the mutex ID returned by am_mutex_create()

int am_task_create(const char *name, int prio, void *stack, int stack_size, void (*entry)(void *arg), unsigned flags, void *arg)

Initialize a task, then schedules it for execution.

The new task may be scheduled for immediate execution. The kernel scheduler may preempt the current task to allow the new task to execute.

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

  • prio – task priority [0, AM_TASK_NUM_MAX[.

  • stack – task stack

  • stack_size – task stack size [bytes]

  • entry – task entry function

  • flags – task flags (bit combination of AM_TASK_FLAG_… constants)

  • 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_task_notify(int task)

Wake up PAL task.

Parameters:

task – task ID returned by am_task_create()

void am_task_wait(int task)

Block PAL task till am_task_notify() is called.

Parameters:

task – the task ID returned by am_task_create()

int am_task_get_own_id(void)

Return task own ID.

Returns:

task ID

void am_task_startup_gate_wait(void)

Block until all tasks are ready to run.

Prevents using tasks before they are ready to run. To be run once at the start of tasks created with am_task_create() API.

void am_task_startup_gate_close(void)

Lock all tasks until am_task_startup_gate_open() is called.

Only used at boot-up to synchronize tasks execution.

void am_task_startup_gate_open(void)

Unlock all tasks.

All tasks blocked on am_task_startup_gate_wait() are unblocked.

void am_task_run_all(void)

Run all PAL tasks

uint32_t am_time_get_ms(void)

Get current time in milliseconds.

Returns:

current time [ms]

uint32_t am_time_get_tick(int domain)

Get current time in ticks.

Parameters:

domain – tick domain

Returns:

current time [tick]

uint32_t am_time_get_tick_from_ms(int domain, uint32_t ms)

Convert ms to ticks for the given tick domain.

Parameters:
  • domain – tick domain [0, INT_MAX[

  • ms – milliseconds to convert

Returns:

time [tick]

uint32_t am_time_get_ms_from_tick(int domain, uint32_t tick)

Convert ticks from the given tick domain to milliseconds.

Parameters:
  • domain – tick domain

  • tick – ticks to convert

Returns:

time [ms]

void am_sleep_ticks(int domain, uint32_t ticks)

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

Parameters:
  • domain – tick domain

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

void am_sleep_till_ticks(int domain, uint32_t ticks)

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

Parameters:
  • domain – tick domain

  • ticks – sleep till this ticks value

void am_sleep_ms(uint32_t ms)

Sleep for given number of milliseconds.

Parameters:

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

void am_sleep_till_ms(uint32_t ms)

Sleep till the given number of milliseconds.

Parameters:

ms – sleep till this milliseconds value

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

printf-like logging.

Thread safe.

Parameters:

fmt – printf-like format string

Returns:

printf-like return value

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

printf-like logging.

Thread unsafe.

Parameters:

fmt – printf-like format string

Returns:

printf-like return value

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

printf-like logging + flushing.

Thread safe.

Parameters:

fmt – printf-like format string

Returns:

printf-like return value

int am_vprintf(const char *fmt, va_list args)

vprintf-like logging.

Thread safe.

Parameters:
  • fmt – printf-like format string

  • args – va_list argument returned by standard va_start() call

Returns:

vprintf-like return value

int am_vprintff(const char *fmt, va_list args)

vprintf-like logging + flushing.

Thread safe.

Parameters:
  • fmt – printf-like format string

  • args – va_list argument returned by standard va_start() call

Returns:

vprintf-like return value

void am_pal_flush(void)

Flush am_printf() intermediate buffer.

void am_on_idle(void)

Block current task with am_task_wait() call.

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

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

int am_get_cpu_count(void)

Return the number of CPU cores.