1.. _pipes_v2:
2
3Pipes
4#####
5
6A :dfn:`pipe` is a kernel object that allows a thread to send a byte stream
7to another thread. Pipes can be used to synchronously transfer chunks of data
8in whole or in part.
9
10.. contents::
11    :local:
12    :depth: 2
13
14Concepts
15********
16
17The pipe can be configured with a ring buffer which holds data that has been
18sent but not yet received; alternatively, the pipe may have no ring buffer.
19
20Any number of pipes can be defined (limited only by available RAM). Each pipe is
21referenced by its memory address.
22
23A pipe has the following key property:
24
25* A **size** that indicates the size of the pipe's ring buffer. Note that a
26  size of zero defines a pipe with no ring buffer.
27
28A pipe must be initialized before it can be used. The pipe is initially empty.
29
30Data is synchronously **sent** either in whole or in part to a pipe by a
31thread. If the specified minimum number of bytes can not be immediately
32satisfied, then the operation will either fail immediately or attempt to send
33as many bytes as possible and then pend in the hope that the send can be
34completed later. Accepted data is either copied to the pipe's ring buffer
35or directly to the waiting reader(s).
36
37Data is synchronously **received** from a pipe by a thread. If the specified
38minimum number of bytes can not be immediately satisfied, then the operation
39will either fail immediately or attempt to receive as many bytes as possible
40and then pend in the hope that the receive can be completed later. Accepted
41data is either copied from the pipe's ring buffer or directly from the
42waiting sender(s).
43
44Data may also be **flushed** from a pipe by a thread. Flushing can be performed
45either on the entire pipe or on only its ring buffer. Flushing the entire pipe
46is equivalent to reading all the information in the ring buffer **and** waiting
47to be written into a giant temporary buffer which is then discarded. Flushing
48the ring buffer is equivalent to reading **only** the data in the ring buffer
49into a temporary buffer which is then discarded. Flushing the ring buffer does
50not guarantee that the ring buffer will stay empty; flushing it may allow a
51pended writer to fill the ring buffer.
52
53.. note::
54    Flushing does not in practice allocate or use additional buffers.
55
56.. note::
57    The kernel does allow for an ISR to flush a pipe from an ISR. It also
58    allows it to send/receive data to/from one provided it does not attempt
59    to wait for space/data.
60
61Implementation
62**************
63
64A pipe is defined using a variable of type :c:struct:`k_pipe` and an
65optional character buffer of type ``unsigned char``. It must then be
66initialized by calling :c:func:`k_pipe_init`.
67
68The following code defines and initializes an empty pipe that has a ring
69buffer capable of holding 100 bytes and is aligned to a 4-byte boundary.
70
71
72.. code-block:: c
73
74    unsigned char __aligned(4) my_ring_buffer[100];
75    struct k_pipe my_pipe;
76
77    k_pipe_init(&my_pipe, my_ring_buffer, sizeof(my_ring_buffer));
78
79Alternatively, a pipe can be defined and initialized at compile time by
80calling :c:macro:`K_PIPE_DEFINE`.
81
82The following code has the same effect as the code segment above. Observe
83that macro defines both the pipe and its ring buffer.
84
85.. code-block:: c
86
87    K_PIPE_DEFINE(my_pipe, 100, 4);
88
89Writing to a Pipe
90=================
91
92Data is added to a pipe by calling :c:func:`k_pipe_put`.
93
94The following code builds on the example above, and uses the pipe to pass
95data from a producing thread to one or more consuming threads. If the pipe's
96ring buffer fills up because the consumers can't keep up, the producing thread
97waits for a specified amount of time.
98
99.. code-block:: c
100
101    struct message_header {
102        ...
103    };
104
105    void producer_thread(void)
106    {
107        unsigned char *data;
108        size_t total_size;
109        size_t bytes_written;
110        int    rc;
111        ...
112
113        while (1) {
114            /* Craft message to send in the pipe */
115            data = ...;
116            total_size = ...;
117
118            /* send data to the consumers */
119            rc = k_pipe_put(&my_pipe, data, total_size, &bytes_written,
120                            sizeof(struct message_header), K_NO_WAIT);
121
122            if (rc < 0) {
123                /* Incomplete message header sent */
124                ...
125            } else if (bytes_written < total_size) {
126                /* Some of the data was sent */
127                ...
128            } else {
129                /* All data sent */
130                ...
131            }
132        }
133    }
134
135Reading from a Pipe
136===================
137
138Data is read from the pipe by calling :c:func:`k_pipe_get`.
139
140The following code builds on the example above, and uses the pipe to
141process data items generated by one or more producing threads.
142
143.. code-block:: c
144
145    void consumer_thread(void)
146    {
147        unsigned char buffer[120];
148        size_t   bytes_read;
149        struct message_header  *header = (struct message_header *)buffer;
150
151        while (1) {
152            rc = k_pipe_get(&my_pipe, buffer, sizeof(buffer), &bytes_read,
153                            sizeof(*header), K_MSEC(100));
154
155            if ((rc < 0) || (bytes_read < sizeof (*header))) {
156                /* Incomplete message header received */
157                ...
158            } else if (header->num_data_bytes + sizeof(*header) > bytes_read) {
159                /* Only some data was received */
160                ...
161            } else {
162                /* All data was received */
163                ...
164            }
165        }
166    }
167
168Use a pipe to send streams of data between threads.
169
170.. note::
171    A pipe can be used to transfer long streams of data if desired.  However
172    it is often preferable to send pointers to large data items to avoid
173    copying the data.
174
175Flushing a Pipe's Buffer
176========================
177
178Data is flushed from the pipe's ring buffer by calling
179:c:func:`k_pipe_buffer_flush`.
180
181The following code builds on the examples above, and flushes the pipe's
182buffer.
183
184.. code-block:: c
185
186    void monitor_thread(void)
187    {
188        while (1) {
189            ...
190            /* Pipe buffer contains stale data. Flush it. */
191            k_pipe_buffer_flush(&my_pipe);
192            ...
193        }
194    }
195
196Flushing a Pipe
197===============
198
199All data in the pipe is flushed by calling :c:func:`k_pipe_flush`.
200
201The following code builds on the examples above, and flushes all the
202data in the pipe.
203
204.. code-block:: c
205
206    void monitor_thread(void)
207    {
208        while (1) {
209            ...
210            /* Critical error detected. Flush the entire pipe to reset it. */
211            k_pipe_flush(&my_pipe);
212            ...
213        }
214    }
215
216
217Suggested uses
218**************
219
220Use a pipe to send streams of data between threads.
221
222.. note::
223    A pipe can be used to transfer long streams of data if desired. However it
224    is often preferable to send pointers to large data items to avoid copying
225    the data. Copying large data items will negatively impact interrupt latency
226    as a spinlock is held while copying that data.
227
228
229Configuration Options
230*********************
231
232Related configuration options:
233
234* :kconfig:option:`CONFIG_PIPES`
235
236API Reference
237*************
238
239.. doxygengroup:: pipe_apis
240