2.2. chan — Abstract channel communication

Threads often communicate over channels. The producer thread or isr writes data to a channel and the consumer reads it. The may be multiple producers writing to a single channel, but only one consumer is allowed.

In the first example, thread 0 and thread 1 communicates over a channel. thread 0 writes data to the channel and thread 1 read the written data.

+------------+             +------------+
|  thread 0  |  channel 0  |  thread 1  |
|            +=============+            |
|  producer  |             |  consumer  |
+------------+             +------------+

In the socond example, isr 0 and thread 2 communicates over a channel. isr 0 writes data to the channel and thread 2 read the written data.

+------------+             +------------+
|   isr 0    |  channel 1  |  thread 2  |
|            +=============+            |
|  producer  |             |  consumer  |
+------------+             +------------+

Source code: src/sync/chan.h, src/sync/chan.c

Test coverage: src/sync/chan.c


Defines

CHAN_CONTROL_LOG_BEGIN
CHAN_CONTROL_LOG_END

End of a log entry.

CHAN_CONTROL_PRINTF_BEGIN

Beginning of printf output.

CHAN_CONTROL_PRINTF_END

End of printf output.

CHAN_CONTROL_NON_BLOCKING_READ

Non-blocking read operation. A channel should return -EAGAIN when a read would block the channel.

CHAN_CONTROL_BLOCKING_READ

Blocking read operation.

Typedefs

typedef ssize_t (*chan_read_fn_t)(void *self_p, void *buf_p, size_t size)

Channel read function callback type.

Return
Number of read bytes or negative error code.
Parameters
  • self_p: Channel to read from.
  • buf_p: Buffer to read into.
  • size: Number of bytes to read.

typedef ssize_t (*chan_write_fn_t)(void *self_p, const void *buf_p, size_t size)

Channel write function callback type.

Return
Number of written bytes or negative error code.
Parameters
  • self_p: Channel to write to.
  • buf_p: Buffer to write.
  • size: Number of bytes to write.

typedef int (*chan_control_fn_t)(void *self_p, int operation)

Channel control function callback type.

Return
Operation specific.
Parameters
  • self_p: Channel to control.
  • operation: Control operation.

typedef int (*chan_write_filter_fn_t)(void *self_p, const void *buf_p, size_t size)

Channel write filter function callback type.

Return
true(1) if the buffer shall be written to the channel, otherwise false(0).
Parameters
  • self_p: Channel to write to.
  • buf_p: Buffer to write.
  • size: Number of bytes in buffer.

typedef size_t (*chan_size_fn_t)(void *self_p)

Channel size function callback type.

Return
Number of bytes available.
Parameters
  • self_p: Channel to get the size of.

Functions

int chan_module_init(void)

Initialize the channel module. This function must be called before calling any other function in this module.

The module will only be initialized once even if this function is called multiple times.

Return
zero(0) or negative error code.

int chan_init(struct chan_t *self_p, chan_read_fn_t read, chan_write_fn_t write, chan_size_fn_t size)

Initialize given channel with given callbacks. A channel must be initialized before it can be used.

Return
zero(0) or negative error code.
Parameters
  • self_p: Channel to initialize.
  • read: Read function callback. This function must implement the channel read functionality, and will be called when the user reads data from the channel.
  • write: Write function callback. This function must implement the channel write functionality, and will be called when the user writes data to the channel.
  • size: Size function callback. This function must return the size of the channel. It should return zero(0) if there is no data available in the channel, and otherwise a positive integer.

int chan_set_write_cb(struct chan_t *self_p, chan_write_fn_t write_cb)

Set the write function callback.

Return
zero(0) or negative error code.
Parameters
  • self_p: Initialized driver object.
  • write_cb: Write function to set.

int chan_set_write_isr_cb(struct chan_t *self_p, chan_write_fn_t write_isr_cb)

Set the write isr function callback.

Return
zero(0) or negative error code.
Parameters
  • self_p: Initialized driver object.
  • write_isr_cb: Write isr function to set.

int chan_set_write_filter_cb(struct chan_t *self_p, chan_write_filter_fn_t write_filter_cb)

Set the write filter callback function. The write filter function is called when data is written to the channel, and its return value determines if the data shall be written to the underlying channel implementation, or discarded.

Return
zero(0) or negative error code.
Parameters
  • self_p: Initialized driver object.
  • write_filter_cb: filter Write filter function to set.

int chan_set_write_filter_isr_cb(struct chan_t *self_p, chan_write_filter_fn_t write_filter_isr_cb)

Set the write isr filter callback function. The write filter function is called when data is written to the channel, and its return value determines is the data shall be written to the underlying channel implementation, or discarded.

Return
zero(0) or negative error code.
Parameters
  • self_p: Initialized driver object.
  • write_filter_isr_cb: filter Write filter function to set.

int chan_set_control_cb(struct chan_t *self_p, chan_control_fn_t control_cb)

Set control function callback.

Return
zero(0) or negative error code.
Parameters
  • self_p: Initialized driver object.
  • control: Control function to set.

ssize_t chan_read(void *self_p, void *buf_p, size_t size)

Read data from given channel. The behaviour of this function depends on the channel implementation. Often, the calling thread will be blocked until all data has been read or an error occurs.

Return
Number of read bytes or negative error code.
Parameters
  • self_p: Channel to read from.
  • buf_p: Buffer to read into.
  • size: Number of bytes to read.

ssize_t chan_write(void *self_p, const void *buf_p, size_t size)

Write data to given channel. The behaviour of this function depends on the channel implementation. Some channel implementations blocks until the receiver has read the data, and some returns immediately.

Return
Number of written bytes or negative error code.
Parameters
  • self_p: Channel to write to.
  • buf_p: Buffer to write.
  • size: Number of bytes to write.

int chan_getc(void *self_p)

Read a character from given channel. The behaviour of this function depends on the channel implementation. Often, the calling thread will be blocked until the character has been read or an error occurs.

Return
The read character as an unsigned char casted to an int, or negative error code.
Parameters
  • self_p: Channel to read from.

int chan_putc(void *self_p, int character)

Write given character to given channel. The behaviour of this function depends on the channel implementation. Some channel implementations blocks until the receiver has read the character, and some returns immediately.

Return
zero(0) or negative error code.
Parameters
  • self_p: Channel to write to.
  • character: Character to write as un unsigned char casted to an int.

size_t chan_size(void *self_p)

Get the number of bytes available to read from given channel.

Return
Number of bytes available.
Parameters
  • self_p: Channel to get the size of.

int chan_control(void *self_p, int operation)

Control given channel.

Return
Operation specific.
Parameters
  • self_p: Channel to control.
  • operation: Operation to perform.

ssize_t chan_write_isr(void *self_p, const void *buf_p, size_t size)

Write data to given channel from interrupt context or with the system lock taken. The behaviour of this function depends on the channel implementation. Some channel implementations blocks until the receiver has read the data, and some returns immediately.

Return
Number of written bytes or negative error code.
Parameters
  • self_p: Channel to write to.
  • buf_p: Buffer to write.
  • size: Number of bytes to write.

int chan_is_polled_isr(struct chan_t *self_p)

Check if a channel is polled. May only be called from isr or with the system lock taken (see sys_lock()).

Return
true(1) or false(0).
Parameters
  • self_p: Channel to check.

int chan_list_init(struct chan_list_t *self_p, struct chan_list_elem_t *elements_p, size_t number_of_elements)

Initialize an empty list of channels. A list is used to wait for data on multiple channel at the same time. When there is data on at least one channel, the poll function returns and the application can read from the channel with data.

Return
zero(0) or negative error code.
Parameters
  • self_p: List to initialize.
  • elements_p: Array of elements to store added channels in.
  • number_of_elements: Number of elements in the element array.

int chan_list_destroy(struct chan_list_t *self_p)

Destroy an initialized list of channels.

Return
zero(0) or negative error code.
Parameters
  • self_p: List to destroy.

int chan_list_add(struct chan_list_t *self_p, void *chan_p)

Add given channel to list of channels.

Return
zero(0) or negative error code.
Parameters
  • self_p: List of channels.
  • chan_p: Channel to add.

int chan_list_remove(struct chan_list_t *self_p, void *chan_p)

Remove given channel from list of channels.

Return
zero(0) or negative error code.
Parameters
  • self_p: List of channels.
  • chan_p: Channel to remove.

void *chan_list_poll(struct chan_list_t *self_p, const struct time_t *timeout_p)

Poll given list of channels for events. Blocks until at least one of the channels in the list has data ready to be read or an timeout occurs.

Return
Channel with data or NULL on timeout.
Parameters
  • self_p: List of channels to poll.
  • timeout_p: Time to wait for data on any channel before a timeout occurs. Set to NULL to wait forever.

void *chan_poll(void *chan_p, const struct time_t *timeout_p)

Poll given channel for events. Blocks until the channel has data ready to be read or an timeout occurs.

Return
The channel or NULL on timeout.
Parameters
  • chan_p: Channel to poll.
  • timeout_p: Time to wait for data on the channel before a timeout occurs. Set to NULL to wait forever.

void *chan_null(void)

Get a reference to the null channel. This channel will ignore all written data but return that it was successfully written.

Return
The null channel.

ssize_t chan_read_null(void *self_p, void *buf_p, size_t size)

Null channel read function callback. Pass to chan_init() if no read function callback is needed for the channel.

Return
Always returns -1.
Parameters
  • self_p: Channel to read from.
  • buf_p: Buffer to read into.
  • size: Number of bytes to read.

ssize_t chan_write_null(void *self_p, const void *buf_p, size_t size)

Null channel write function callback. Pass to chan_init() if no write function callback is needed for the channel.

Return
Always returns size.
Parameters
  • self_p: Channel to write to.
  • buf_p: Buffer to write.
  • size: Number of bytes to write.

size_t chan_size_null(void *self_p)

Null channel size function callback. Pass to chan_init() if no size function callback is needed for the channel.

Return
Always returns zero(0).
Parameters
  • self_p: Channel to get the size of.

int chan_control_null(void *self_p, int operation)

Null channel control function callback. Will silently ignore the control request.

Return
Always returns zero(0).
Parameters
  • self_p: Channel to control.
  • operation: Operation to perform.

struct chan_list_elem_t

Public Members

struct chan_t *chan_p
struct chan_list_t

Public Members

struct chan_list_elem_t *elements_p
size_t number_of_elements
size_t len
struct chan_t
#include <chan.h>

Channel datastructure.

Public Members

chan_read_fn_t read
chan_write_fn_t write
chan_size_fn_t size
chan_control_fn_t control
chan_write_filter_fn_t write_filter_cb
chan_write_fn_t write_isr
chan_write_filter_fn_t write_filter_isr_cb
struct thrd_t *reader_p
struct chan_list_t *list_p