zephyr/doc/kernel/microkernel/microkernel_pipes.rst

217 lines
7.1 KiB
ReStructuredText
Raw Normal View History

.. _microkernel_pipes:
Pipes
#####
Definition
**********
Microkernel pipes are defined in :file:`kernel/microkernel/k_pipe.c`.
Pipes allow any task to put any amount of data in or out. Pipes are
conceptually similar to FIFO objects in that they communicate
anonymously in a time-ordered, first-in, first-out manner, to exchange
data between tasks. Like FIFO objects, pipes can have a buffer, but
un-buffered operation is also possible. The main difference between
FIFO objects and pipes is that pipes handle variable-sized data.
Function
********
Pipes accept and send variable-sized data, and can be configured to work
with or without a buffer. Buffered pipes are time-ordered. The incoming
data is stored on a first-come, first-serve basis in the buffer; it is
not sorted by priority.
Pipes have no size limit. The size of the data transfer and the size of
the buffer have no limit except for the available memory. Pipes allow
senders or receivers to perform partial read and partial write
operations.
Pipes support both synchronous and asynchronous operations. If a pipe is
unbuffered, the sender can asynchronously put data into the pipe, or
wait for the data to be received, and the receiver can attempt to
remove data from the pipe, or wait on the data to be available.
Buffered pipes are synchronous by design.
Pipes are anonymous. The pipe transfer does not identify the sender or
receiver. Alternatively, mailboxes can be used to specify the sender
and receiver identities.
Usage
*****
Defining a Pipe
===============
The following parameters must be defined:
*name*
This specifies a unique name for the pipe.
*buffer_size*
This specifies the size (in bytes) of the pipe's internal buffer.
If no internal buffer is to be used specify zero.
Public Pipe
-----------
Define the pipe in the application's .MDEF file using the following syntax:
.. code-block:: console
PIPE name buffer_size
For example, the file :file:`projName.mdef` defines a pipe with a 1 KB internal
buffer as follows:
.. code-block:: console
% PIPE NAME BUFFERSIZE
% ===============================
PIPE DATA_PIPE 1024
A public pipe can be referenced from any source file that includes
the file :file:`zephyr.h`.
Private Pipe
------------
Define the pipe in a source file using the following syntax:
.. code-block:: c
DEFINE_PIPE(name, size);
For example, the following code defines a private pipe named ``PRIV_PIPE``.
.. code-block:: c
DEFINE_PIPE(PRIV_PIPE, 1024);
To utilize this pipe from a different source file use the following syntax:
.. code-block:: c
extern const kpipe_t PRIV_PIPE;
Example: Writing Fixed-Size Data Items to a Pipe
================================================
This code uses a pipe to send a series of fixed-size data items
to a consuming task.
.. code-block:: c
void producer_task(void)
{
struct item_type data_item;
int amount_written;
while (1) {
/* generate a data item to send */
data_item = ... ;
/* write the entire data item to the pipe */
task_pipe_put_wait(DATA_PIPE, &data_item, sizeof(data_item),
&amount_written, _ALL_N);
}
}
Example: Reading Fixed-Size Data Items from a Pipe
==================================================
This code uses a pipe to receive a series of fixed-size data items
from a producing task. To improve performance, the consuming task
waits until 20 data items are available then reads them as a group,
rather than reading them individually.
.. code-block:: c
void consumer_task(void)
{
struct item_type data_items[20];
int amount_read;
int i;
while (1) {
/* read 20 complete data items at once */
task_pipe_get_wait(DATA_PIPE, &data_items, sizeof(data_items),
&amount_read, _ALL_N);
/* process the data items one at a time */
for (i = 0; i < 20; i++) {
... = data_items[i];
...
}
}
}
Example: Reading a Stream of Data Bytes from a Pipe
===================================================
This code uses a pipe to process a stream of data bytes from a
producing task. The pipe is read in a non-blocking manner to allow
the consuming task to perform other work when there are no
unprocessed data bytes in the pipe.
.. code-block:: c
void consumer_task(void)
{
char data_area[20];
int amount_read;
int i;
while (1) {
/* consume any data bytes currently in the pipe */
while (task_pipe_get(DATA_PIPE, &data_area, sizeof(data_area),
&amount_read, _1_TO_N) == RC_OK) {
/* now have from 1 to 20 data bytes */
for (i = 0; i < amount_read; i++) {
... = data_area[i];
...
}
}
/* do other processing */
...
}
}
APIs
****
The following Pipe APIs are provided by :file:`microkernel.h`.
+----------------------------------------+------------------------------------+
| Call | Description |
+========================================+====================================+
| :c:func:`task_pipe_put()` | Writes data to a pipe, or fails & |
| | continues if unable to write data. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_put_wait()` | Writes data to a pipe, or waits |
| | if unable to write data. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_put_wait_timeout()` | Writes data to a pipe, or waits |
| | for a specified time period if |
| | unable to write data. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_block_put()` | Writes data to a pipe from a |
| | memory pool block. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_get()` | Reads data from a pipe, or fails |
| | and continues if data isn't there. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_get_wait()` | Reads data from a pipe, or waits |
| | for data if data isn't there. |
+----------------------------------------+------------------------------------+
| :c:func:`task_pipe_get_wait_timeout()` | Reads data from a pipe, or waits |
| | for data for a specified time |
| | period if data isn't there. |
+----------------------------------------+------------------------------------+