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