zephyr/doc/kernel/microkernel/microkernel_fifos.rst
Rodrigo Caballero 4d8b60adca Doc: Change the Microkernel Objects to the Microkernel Services section.
Moves the Microkernel Object documentation to a new Microkernel Services
section within the Kernel Primer. Labels, cross-references, figures,
headings and filenames were updated to reflect the new structure. 

Change-Id: Ia2a91410a94caa8a97bb8211db5afc84b5dc0974
Signed-off-by: Rodrigo Caballero <rodrigo.caballero.abraham@intel.com>
2016-02-05 20:15:19 -05:00

188 lines
6.6 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.. _microkernel_fifos:
Microkernel FIFOs
#################
Definition
**********
The FIFO is defined in :file:`include/microkernel/fifo.h` as a simple
first-in, first-out queue that handle small amounts of fixed size data.
FIFO objects have a buffer that stores a number of data transmits, and
are the most efficient way to pass small amounts of data between tasks.
FIFO objects are suitable for asynchronously transferring small amounts
of data, such as parameters, between tasks.
Function
********
FIFO objects store data in a statically allocated buffer defined within
the projects MDEF file. The depth of the FIFO object buffer is only
limited by the available memory on the platform. Individual FIFO data
objects can be at most 40 bytes in size, and are stored in an ordered
first-come, first-serve basis, not by priority.
FIFO objects are asynchronous. When using a FIFO object, the sender can
add data even if the receiver is not ready yet. This only applies if
there is sufficient space on the buffer to store the sender's data.
FIFO objects are anonymous. The kernel object does not store the sender
or receiver identity. If the sender identification is required, it is
up to the caller to store that information in the data placed into the
FIFO. The receiving task can then check it. Alternatively, mailboxes
can be used to specify the sender and receiver identities.
FIFO objects read and write actions are always fixed-size block-based.
The width of each FIFO object block is specified in the project file.
If a task calls :c:func:`task_fifo_get()` and the call succeeds, then
the fixed number of bytes is copied from the FIFO object into the
addresses of the destination pointer.
Usage
*****
Defining a FIFO in MDEF File
============================
The following parameters must be defined:
*name*
This specifies a unique name for the FIFO.
*depth*
This specifies the maximum number of data items
that can exist at any one time.
*width*
This specifies the size (in bytes) of each data item.
Add an entry for a FIFO in the project .MDEF file using the
following syntax:
.. code-block:: console
FIFO %name %depth %width
For example, the file :file:`projName.mdef` defines a FIFO
that holds up to 10 items that are each 12 bytes long as follows:
.. code-block:: console
% FIFO NAME DEPTH WIDTH
% =============================
FIFO SIGNAL_FIFO 10 12
Defining FIFO within the Code
=============================
In addition to defining FIFOs in MDEF file, it is also possible to
define FIFOs inside code. The macro ``DEFINE_FIFO(fifo_name)``
can be used for this purpose.
For example, the following code can be used to define a global FIFO
``PRIV_FIFO``.
.. code-block:: c
DEFINE_FIFO(PRIV_FIFO, depth, width);
The FIFO ``PRIV_FIFO`` can be used in the same style as those FIFOs
defined in MDEF file.
It is possible to utilize this FIFO in another source file, simply
add:
.. code-block:: c
extern const kfifo_t PRIV_FIFO;
to that file. The FIFO ``PRIV_FIFO`` can be then used there.
Example: Writing to a FIFO
==========================
This code uses a FIFO to pass data items from a producing task to
one or more consuming tasks. If the FIFO fills up because the consumers
can't keep up, throw away all existing data so newer data can be saved.
.. code-block:: c
void producer_task(void)
{
struct data_item_t data;
while (1) {
/* create data item to send (e.g. measurement, timestamp, ...) */
data = ...
/* send data to consumers */
while (task_fifo_put(SIGNAL_FIFO, &data) != RC_OK) {
/* FIFO is full */
task_fifo_purge(SIGNAL_FIFO);
}
/* data item was successfully added to FIFO */
}
}
Example: Reading from a FIFO
============================
This code uses a FIFO to process data items from generated by
one or more producing tasks.
.. code-block:: c
void consumer_task(void)
{
struct data_item_t data;
while (1) {
/* get a data item */
task_fifo_get_wait(SIGNAL_FIFO, &data);
/* process data item */
...
}
}
APIs
****
The following APIs for a microkernel FIFO are provided by microkernel.h.
+----------------------------------------+-----------------------------------+
| Call | Description |
+========================================+===================================+
| :c:func:`task_fifo_put()` | Write item to a FIFO, or fail and |
| | continue if it is full. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_put_wait()` | Write item to a FIFO, or wait |
| | for room to write if it is full. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_put_wait_timeout()` | Write item to a FIFO, or wait for |
| | a specified time period if it |
| | is full. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_get()` | Read item from a FIFO, or fail |
| | and continue if it is empty. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_get_wait()` | Read item from a FIFO, or wait |
| | for an item if it is empty. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_get_wait_timeout()` | Read item from a FIFO, or wait |
| | for an item for a specified time |
| | period if it is empty. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_purge()` | Discard all items in a FIFO and |
| | unblock any tasks waiting to read |
| | or write an item. |
+----------------------------------------+-----------------------------------+
| :c:func:`task_fifo_size_get()` | Read the number of items |
| | currently in a FIFO. |
+----------------------------------------+-----------------------------------+