]> begriffs open source - freertos/blob - include/stream_buffer.h
Add SMP in the License Header (#402)
[freertos] / include / stream_buffer.h
1 /*
2  * FreeRTOS SMP Kernel V202110.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26
27 /*
28  * Stream buffers are used to send a continuous stream of data from one task or
29  * interrupt to another.  Their implementation is light weight, making them
30  * particularly suited for interrupt to task and core to core communication
31  * scenarios.
32  *
33  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
34  * implementation (so also the message buffer implementation, as message buffers
35  * are built on top of stream buffers) assumes there is only one task or
36  * interrupt that will write to the buffer (the writer), and only one task or
37  * interrupt that will read from the buffer (the reader).  It is safe for the
38  * writer and reader to be different tasks or interrupts, but, unlike other
39  * FreeRTOS objects, it is not safe to have multiple different writers or
40  * multiple different readers.  If there are to be multiple different writers
41  * then the application writer must place each call to a writing API function
42  * (such as xStreamBufferSend()) inside a critical section and set the send
43  * block time to 0.  Likewise, if there are to be multiple different readers
44  * then the application writer must place each call to a reading API function
45  * (such as xStreamBufferReceive()) inside a critical section section and set the
46  * receive block time to 0.
47  *
48  */
49
50 #ifndef STREAM_BUFFER_H
51 #define STREAM_BUFFER_H
52
53 #ifndef INC_FREERTOS_H
54     #error "include FreeRTOS.h must appear in source files before include stream_buffer.h"
55 #endif
56
57 /* *INDENT-OFF* */
58 #if defined( __cplusplus )
59     extern "C" {
60 #endif
61 /* *INDENT-ON* */
62
63 /**
64  * Type by which stream buffers are referenced.  For example, a call to
65  * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can
66  * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(),
67  * etc.
68  */
69 struct StreamBufferDef_t;
70 typedef struct StreamBufferDef_t * StreamBufferHandle_t;
71
72
73 /**
74  * message_buffer.h
75  *
76  * <pre>
77  * StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
78  * </pre>
79  *
80  * Creates a new stream buffer using dynamically allocated memory.  See
81  * xStreamBufferCreateStatic() for a version that uses statically allocated
82  * memory (memory that is allocated at compile time).
83  *
84  * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
85  * FreeRTOSConfig.h for xStreamBufferCreate() to be available.
86  *
87  * @param xBufferSizeBytes The total number of bytes the stream buffer will be
88  * able to hold at any one time.
89  *
90  * @param xTriggerLevelBytes The number of bytes that must be in the stream
91  * buffer before a task that is blocked on the stream buffer to wait for data is
92  * moved out of the blocked state.  For example, if a task is blocked on a read
93  * of an empty stream buffer that has a trigger level of 1 then the task will be
94  * unblocked when a single byte is written to the buffer or the task's block
95  * time expires.  As another example, if a task is blocked on a read of an empty
96  * stream buffer that has a trigger level of 10 then the task will not be
97  * unblocked until the stream buffer contains at least 10 bytes or the task's
98  * block time expires.  If a reading task's block time expires before the
99  * trigger level is reached then the task will still receive however many bytes
100  * are actually available.  Setting a trigger level of 0 will result in a
101  * trigger level of 1 being used.  It is not valid to specify a trigger level
102  * that is greater than the buffer size.
103  *
104  * @return If NULL is returned, then the stream buffer cannot be created
105  * because there is insufficient heap memory available for FreeRTOS to allocate
106  * the stream buffer data structures and storage area.  A non-NULL value being
107  * returned indicates that the stream buffer has been created successfully -
108  * the returned value should be stored as the handle to the created stream
109  * buffer.
110  *
111  * Example use:
112  * <pre>
113  *
114  * void vAFunction( void )
115  * {
116  * StreamBufferHandle_t xStreamBuffer;
117  * const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
118  *
119  *  // Create a stream buffer that can hold 100 bytes.  The memory used to hold
120  *  // both the stream buffer structure and the data in the stream buffer is
121  *  // allocated dynamically.
122  *  xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
123  *
124  *  if( xStreamBuffer == NULL )
125  *  {
126  *      // There was not enough heap memory space available to create the
127  *      // stream buffer.
128  *  }
129  *  else
130  *  {
131  *      // The stream buffer was created successfully and can now be used.
132  *  }
133  * }
134  * </pre>
135  * \defgroup xStreamBufferCreate xStreamBufferCreate
136  * \ingroup StreamBufferManagement
137  */
138 #define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes )    xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE )
139
140 /**
141  * stream_buffer.h
142  *
143  * <pre>
144  * StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
145  *                                              size_t xTriggerLevelBytes,
146  *                                              uint8_t *pucStreamBufferStorageArea,
147  *                                              StaticStreamBuffer_t *pxStaticStreamBuffer );
148  * </pre>
149  * Creates a new stream buffer using statically allocated memory.  See
150  * xStreamBufferCreate() for a version that uses dynamically allocated memory.
151  *
152  * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for
153  * xStreamBufferCreateStatic() to be available.
154  *
155  * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
156  * pucStreamBufferStorageArea parameter.
157  *
158  * @param xTriggerLevelBytes The number of bytes that must be in the stream
159  * buffer before a task that is blocked on the stream buffer to wait for data is
160  * moved out of the blocked state.  For example, if a task is blocked on a read
161  * of an empty stream buffer that has a trigger level of 1 then the task will be
162  * unblocked when a single byte is written to the buffer or the task's block
163  * time expires.  As another example, if a task is blocked on a read of an empty
164  * stream buffer that has a trigger level of 10 then the task will not be
165  * unblocked until the stream buffer contains at least 10 bytes or the task's
166  * block time expires.  If a reading task's block time expires before the
167  * trigger level is reached then the task will still receive however many bytes
168  * are actually available.  Setting a trigger level of 0 will result in a
169  * trigger level of 1 being used.  It is not valid to specify a trigger level
170  * that is greater than the buffer size.
171  *
172  * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at
173  * least xBufferSizeBytes + 1 big.  This is the array to which streams are
174  * copied when they are written to the stream buffer.
175  *
176  * @param pxStaticStreamBuffer Must point to a variable of type
177  * StaticStreamBuffer_t, which will be used to hold the stream buffer's data
178  * structure.
179  *
180  * @return If the stream buffer is created successfully then a handle to the
181  * created stream buffer is returned. If either pucStreamBufferStorageArea or
182  * pxStaticstreamBuffer are NULL then NULL is returned.
183  *
184  * Example use:
185  * <pre>
186  *
187  * // Used to dimension the array used to hold the streams.  The available space
188  * // will actually be one less than this, so 999.
189  #define STORAGE_SIZE_BYTES 1000
190  *
191  * // Defines the memory that will actually hold the streams within the stream
192  * // buffer.
193  * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
194  *
195  * // The variable used to hold the stream buffer structure.
196  * StaticStreamBuffer_t xStreamBufferStruct;
197  *
198  * void MyFunction( void )
199  * {
200  * StreamBufferHandle_t xStreamBuffer;
201  * const size_t xTriggerLevel = 1;
202  *
203  *  xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
204  *                                             xTriggerLevel,
205  *                                             ucBufferStorage,
206  *                                             &xStreamBufferStruct );
207  *
208  *  // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
209  *  // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
210  *  // reference the created stream buffer in other stream buffer API calls.
211  *
212  *  // Other code that uses the stream buffer can go here.
213  * }
214  *
215  * </pre>
216  * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic
217  * \ingroup StreamBufferManagement
218  */
219 #define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
220     xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
221
222 /**
223  * stream_buffer.h
224  *
225  * <pre>
226  * size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
227  *                        const void *pvTxData,
228  *                        size_t xDataLengthBytes,
229  *                        TickType_t xTicksToWait );
230  * </pre>
231  *
232  * Sends bytes to a stream buffer.  The bytes are copied into the stream buffer.
233  *
234  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
235  * implementation (so also the message buffer implementation, as message buffers
236  * are built on top of stream buffers) assumes there is only one task or
237  * interrupt that will write to the buffer (the writer), and only one task or
238  * interrupt that will read from the buffer (the reader).  It is safe for the
239  * writer and reader to be different tasks or interrupts, but, unlike other
240  * FreeRTOS objects, it is not safe to have multiple different writers or
241  * multiple different readers.  If there are to be multiple different writers
242  * then the application writer must place each call to a writing API function
243  * (such as xStreamBufferSend()) inside a critical section and set the send
244  * block time to 0.  Likewise, if there are to be multiple different readers
245  * then the application writer must place each call to a reading API function
246  * (such as xStreamBufferReceive()) inside a critical section and set the receive
247  * block time to 0.
248  *
249  * Use xStreamBufferSend() to write to a stream buffer from a task.  Use
250  * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
251  * service routine (ISR).
252  *
253  * @param xStreamBuffer The handle of the stream buffer to which a stream is
254  * being sent.
255  *
256  * @param pvTxData A pointer to the buffer that holds the bytes to be copied
257  * into the stream buffer.
258  *
259  * @param xDataLengthBytes   The maximum number of bytes to copy from pvTxData
260  * into the stream buffer.
261  *
262  * @param xTicksToWait The maximum amount of time the task should remain in the
263  * Blocked state to wait for enough space to become available in the stream
264  * buffer, should the stream buffer contain too little space to hold the
265  * another xDataLengthBytes bytes.  The block time is specified in tick periods,
266  * so the absolute time it represents is dependent on the tick frequency.  The
267  * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
268  * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will
269  * cause the task to wait indefinitely (without timing out), provided
270  * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  If a task times out
271  * before it can write all xDataLengthBytes into the buffer it will still write
272  * as many bytes as possible.  A task does not use any CPU time when it is in
273  * the blocked state.
274  *
275  * @return The number of bytes written to the stream buffer.  If a task times
276  * out before it can write all xDataLengthBytes into the buffer it will still
277  * write as many bytes as possible.
278  *
279  * Example use:
280  * <pre>
281  * void vAFunction( StreamBufferHandle_t xStreamBuffer )
282  * {
283  * size_t xBytesSent;
284  * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
285  * char *pcStringToSend = "String to send";
286  * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
287  *
288  *  // Send an array to the stream buffer, blocking for a maximum of 100ms to
289  *  // wait for enough space to be available in the stream buffer.
290  *  xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
291  *
292  *  if( xBytesSent != sizeof( ucArrayToSend ) )
293  *  {
294  *      // The call to xStreamBufferSend() times out before there was enough
295  *      // space in the buffer for the data to be written, but it did
296  *      // successfully write xBytesSent bytes.
297  *  }
298  *
299  *  // Send the string to the stream buffer.  Return immediately if there is not
300  *  // enough space in the buffer.
301  *  xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
302  *
303  *  if( xBytesSent != strlen( pcStringToSend ) )
304  *  {
305  *      // The entire string could not be added to the stream buffer because
306  *      // there was not enough free space in the buffer, but xBytesSent bytes
307  *      // were sent.  Could try again to send the remaining bytes.
308  *  }
309  * }
310  * </pre>
311  * \defgroup xStreamBufferSend xStreamBufferSend
312  * \ingroup StreamBufferManagement
313  */
314 size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
315                           const void * pvTxData,
316                           size_t xDataLengthBytes,
317                           TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
318
319 /**
320  * stream_buffer.h
321  *
322  * <pre>
323  * size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
324  *                               const void *pvTxData,
325  *                               size_t xDataLengthBytes,
326  *                               BaseType_t *pxHigherPriorityTaskWoken );
327  * </pre>
328  *
329  * Interrupt safe version of the API function that sends a stream of bytes to
330  * the stream buffer.
331  *
332  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
333  * implementation (so also the message buffer implementation, as message buffers
334  * are built on top of stream buffers) assumes there is only one task or
335  * interrupt that will write to the buffer (the writer), and only one task or
336  * interrupt that will read from the buffer (the reader).  It is safe for the
337  * writer and reader to be different tasks or interrupts, but, unlike other
338  * FreeRTOS objects, it is not safe to have multiple different writers or
339  * multiple different readers.  If there are to be multiple different writers
340  * then the application writer must place each call to a writing API function
341  * (such as xStreamBufferSend()) inside a critical section and set the send
342  * block time to 0.  Likewise, if there are to be multiple different readers
343  * then the application writer must place each call to a reading API function
344  * (such as xStreamBufferReceive()) inside a critical section and set the receive
345  * block time to 0.
346  *
347  * Use xStreamBufferSend() to write to a stream buffer from a task.  Use
348  * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt
349  * service routine (ISR).
350  *
351  * @param xStreamBuffer The handle of the stream buffer to which a stream is
352  * being sent.
353  *
354  * @param pvTxData A pointer to the data that is to be copied into the stream
355  * buffer.
356  *
357  * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData
358  * into the stream buffer.
359  *
360  * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will
361  * have a task blocked on it waiting for data.  Calling
362  * xStreamBufferSendFromISR() can make data available, and so cause a task that
363  * was waiting for data to leave the Blocked state.  If calling
364  * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the
365  * unblocked task has a priority higher than the currently executing task (the
366  * task that was interrupted), then, internally, xStreamBufferSendFromISR()
367  * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
368  * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a
369  * context switch should be performed before the interrupt is exited.  This will
370  * ensure that the interrupt returns directly to the highest priority Ready
371  * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
372  * is passed into the function.  See the example code below for an example.
373  *
374  * @return The number of bytes actually written to the stream buffer, which will
375  * be less than xDataLengthBytes if the stream buffer didn't have enough free
376  * space for all the bytes to be written.
377  *
378  * Example use:
379  * <pre>
380  * // A stream buffer that has already been created.
381  * StreamBufferHandle_t xStreamBuffer;
382  *
383  * void vAnInterruptServiceRoutine( void )
384  * {
385  * size_t xBytesSent;
386  * char *pcStringToSend = "String to send";
387  * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
388  *
389  *  // Attempt to send the string to the stream buffer.
390  *  xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
391  *                                         ( void * ) pcStringToSend,
392  *                                         strlen( pcStringToSend ),
393  *                                         &xHigherPriorityTaskWoken );
394  *
395  *  if( xBytesSent != strlen( pcStringToSend ) )
396  *  {
397  *      // There was not enough free space in the stream buffer for the entire
398  *      // string to be written, ut xBytesSent bytes were written.
399  *  }
400  *
401  *  // If xHigherPriorityTaskWoken was set to pdTRUE inside
402  *  // xStreamBufferSendFromISR() then a task that has a priority above the
403  *  // priority of the currently executing task was unblocked and a context
404  *  // switch should be performed to ensure the ISR returns to the unblocked
405  *  // task.  In most FreeRTOS ports this is done by simply passing
406  *  // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
407  *  // variables value, and perform the context switch if necessary.  Check the
408  *  // documentation for the port in use for port specific instructions.
409  *  taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
410  * }
411  * </pre>
412  * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR
413  * \ingroup StreamBufferManagement
414  */
415 size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
416                                  const void * pvTxData,
417                                  size_t xDataLengthBytes,
418                                  BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
419
420 /**
421  * stream_buffer.h
422  *
423  * <pre>
424  * size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
425  *                           void *pvRxData,
426  *                           size_t xBufferLengthBytes,
427  *                           TickType_t xTicksToWait );
428  * </pre>
429  *
430  * Receives bytes from a stream buffer.
431  *
432  * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
433  * implementation (so also the message buffer implementation, as message buffers
434  * are built on top of stream buffers) assumes there is only one task or
435  * interrupt that will write to the buffer (the writer), and only one task or
436  * interrupt that will read from the buffer (the reader).  It is safe for the
437  * writer and reader to be different tasks or interrupts, but, unlike other
438  * FreeRTOS objects, it is not safe to have multiple different writers or
439  * multiple different readers.  If there are to be multiple different writers
440  * then the application writer must place each call to a writing API function
441  * (such as xStreamBufferSend()) inside a critical section and set the send
442  * block time to 0.  Likewise, if there are to be multiple different readers
443  * then the application writer must place each call to a reading API function
444  * (such as xStreamBufferReceive()) inside a critical section and set the receive
445  * block time to 0.
446  *
447  * Use xStreamBufferReceive() to read from a stream buffer from a task.  Use
448  * xStreamBufferReceiveFromISR() to read from a stream buffer from an
449  * interrupt service routine (ISR).
450  *
451  * @param xStreamBuffer The handle of the stream buffer from which bytes are to
452  * be received.
453  *
454  * @param pvRxData A pointer to the buffer into which the received bytes will be
455  * copied.
456  *
457  * @param xBufferLengthBytes The length of the buffer pointed to by the
458  * pvRxData parameter.  This sets the maximum number of bytes to receive in one
459  * call.  xStreamBufferReceive will return as many bytes as possible up to a
460  * maximum set by xBufferLengthBytes.
461  *
462  * @param xTicksToWait The maximum amount of time the task should remain in the
463  * Blocked state to wait for data to become available if the stream buffer is
464  * empty.  xStreamBufferReceive() will return immediately if xTicksToWait is
465  * zero.  The block time is specified in tick periods, so the absolute time it
466  * represents is dependent on the tick frequency.  The macro pdMS_TO_TICKS() can
467  * be used to convert a time specified in milliseconds into a time specified in
468  * ticks.  Setting xTicksToWait to portMAX_DELAY will cause the task to wait
469  * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1
470  * in FreeRTOSConfig.h.  A task does not use any CPU time when it is in the
471  * Blocked state.
472  *
473  * @return The number of bytes actually read from the stream buffer, which will
474  * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed
475  * out before xBufferLengthBytes were available.
476  *
477  * Example use:
478  * <pre>
479  * void vAFunction( StreamBuffer_t xStreamBuffer )
480  * {
481  * uint8_t ucRxData[ 20 ];
482  * size_t xReceivedBytes;
483  * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
484  *
485  *  // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
486  *  // Wait in the Blocked state (so not using any CPU processing time) for a
487  *  // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
488  *  // available.
489  *  xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
490  *                                         ( void * ) ucRxData,
491  *                                         sizeof( ucRxData ),
492  *                                         xBlockTime );
493  *
494  *  if( xReceivedBytes > 0 )
495  *  {
496  *      // A ucRxData contains another xRecievedBytes bytes of data, which can
497  *      // be processed here....
498  *  }
499  * }
500  * </pre>
501  * \defgroup xStreamBufferReceive xStreamBufferReceive
502  * \ingroup StreamBufferManagement
503  */
504 size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
505                              void * pvRxData,
506                              size_t xBufferLengthBytes,
507                              TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
508
509 /**
510  * stream_buffer.h
511  *
512  * <pre>
513  * size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
514  *                                  void *pvRxData,
515  *                                  size_t xBufferLengthBytes,
516  *                                  BaseType_t *pxHigherPriorityTaskWoken );
517  * </pre>
518  *
519  * An interrupt safe version of the API function that receives bytes from a
520  * stream buffer.
521  *
522  * Use xStreamBufferReceive() to read bytes from a stream buffer from a task.
523  * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an
524  * interrupt service routine (ISR).
525  *
526  * @param xStreamBuffer The handle of the stream buffer from which a stream
527  * is being received.
528  *
529  * @param pvRxData A pointer to the buffer into which the received bytes are
530  * copied.
531  *
532  * @param xBufferLengthBytes The length of the buffer pointed to by the
533  * pvRxData parameter.  This sets the maximum number of bytes to receive in one
534  * call.  xStreamBufferReceive will return as many bytes as possible up to a
535  * maximum set by xBufferLengthBytes.
536  *
537  * @param pxHigherPriorityTaskWoken  It is possible that a stream buffer will
538  * have a task blocked on it waiting for space to become available.  Calling
539  * xStreamBufferReceiveFromISR() can make space available, and so cause a task
540  * that is waiting for space to leave the Blocked state.  If calling
541  * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and
542  * the unblocked task has a priority higher than the currently executing task
543  * (the task that was interrupted), then, internally,
544  * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
545  * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a
546  * context switch should be performed before the interrupt is exited.  That will
547  * ensure the interrupt returns directly to the highest priority Ready state
548  * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
549  * passed into the function.  See the code example below for an example.
550  *
551  * @return The number of bytes read from the stream buffer, if any.
552  *
553  * Example use:
554  * <pre>
555  * // A stream buffer that has already been created.
556  * StreamBuffer_t xStreamBuffer;
557  *
558  * void vAnInterruptServiceRoutine( void )
559  * {
560  * uint8_t ucRxData[ 20 ];
561  * size_t xReceivedBytes;
562  * BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
563  *
564  *  // Receive the next stream from the stream buffer.
565  *  xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
566  *                                                ( void * ) ucRxData,
567  *                                                sizeof( ucRxData ),
568  *                                                &xHigherPriorityTaskWoken );
569  *
570  *  if( xReceivedBytes > 0 )
571  *  {
572  *      // ucRxData contains xReceivedBytes read from the stream buffer.
573  *      // Process the stream here....
574  *  }
575  *
576  *  // If xHigherPriorityTaskWoken was set to pdTRUE inside
577  *  // xStreamBufferReceiveFromISR() then a task that has a priority above the
578  *  // priority of the currently executing task was unblocked and a context
579  *  // switch should be performed to ensure the ISR returns to the unblocked
580  *  // task.  In most FreeRTOS ports this is done by simply passing
581  *  // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
582  *  // variables value, and perform the context switch if necessary.  Check the
583  *  // documentation for the port in use for port specific instructions.
584  *  taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
585  * }
586  * </pre>
587  * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR
588  * \ingroup StreamBufferManagement
589  */
590 size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
591                                     void * pvRxData,
592                                     size_t xBufferLengthBytes,
593                                     BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
594
595 /**
596  * stream_buffer.h
597  *
598  * <pre>
599  * void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
600  * </pre>
601  *
602  * Deletes a stream buffer that was previously created using a call to
603  * xStreamBufferCreate() or xStreamBufferCreateStatic().  If the stream
604  * buffer was created using dynamic memory (that is, by xStreamBufferCreate()),
605  * then the allocated memory is freed.
606  *
607  * A stream buffer handle must not be used after the stream buffer has been
608  * deleted.
609  *
610  * @param xStreamBuffer The handle of the stream buffer to be deleted.
611  *
612  * \defgroup vStreamBufferDelete vStreamBufferDelete
613  * \ingroup StreamBufferManagement
614  */
615 void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
616
617 /**
618  * stream_buffer.h
619  *
620  * <pre>
621  * BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
622  * </pre>
623  *
624  * Queries a stream buffer to see if it is full.  A stream buffer is full if it
625  * does not have any free space, and therefore cannot accept any more data.
626  *
627  * @param xStreamBuffer The handle of the stream buffer being queried.
628  *
629  * @return If the stream buffer is full then pdTRUE is returned.  Otherwise
630  * pdFALSE is returned.
631  *
632  * \defgroup xStreamBufferIsFull xStreamBufferIsFull
633  * \ingroup StreamBufferManagement
634  */
635 BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
636
637 /**
638  * stream_buffer.h
639  *
640  * <pre>
641  * BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
642  * </pre>
643  *
644  * Queries a stream buffer to see if it is empty.  A stream buffer is empty if
645  * it does not contain any data.
646  *
647  * @param xStreamBuffer The handle of the stream buffer being queried.
648  *
649  * @return If the stream buffer is empty then pdTRUE is returned.  Otherwise
650  * pdFALSE is returned.
651  *
652  * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty
653  * \ingroup StreamBufferManagement
654  */
655 BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
656
657 /**
658  * stream_buffer.h
659  *
660  * <pre>
661  * BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
662  * </pre>
663  *
664  * Resets a stream buffer to its initial, empty, state.  Any data that was in
665  * the stream buffer is discarded.  A stream buffer can only be reset if there
666  * are no tasks blocked waiting to either send to or receive from the stream
667  * buffer.
668  *
669  * @param xStreamBuffer The handle of the stream buffer being reset.
670  *
671  * @return If the stream buffer is reset then pdPASS is returned.  If there was
672  * a task blocked waiting to send to or read from the stream buffer then the
673  * stream buffer is not reset and pdFAIL is returned.
674  *
675  * \defgroup xStreamBufferReset xStreamBufferReset
676  * \ingroup StreamBufferManagement
677  */
678 BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
679
680 /**
681  * stream_buffer.h
682  *
683  * <pre>
684  * size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
685  * </pre>
686  *
687  * Queries a stream buffer to see how much free space it contains, which is
688  * equal to the amount of data that can be sent to the stream buffer before it
689  * is full.
690  *
691  * @param xStreamBuffer The handle of the stream buffer being queried.
692  *
693  * @return The number of bytes that can be written to the stream buffer before
694  * the stream buffer would be full.
695  *
696  * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable
697  * \ingroup StreamBufferManagement
698  */
699 size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
700
701 /**
702  * stream_buffer.h
703  *
704  * <pre>
705  * size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
706  * </pre>
707  *
708  * Queries a stream buffer to see how much data it contains, which is equal to
709  * the number of bytes that can be read from the stream buffer before the stream
710  * buffer would be empty.
711  *
712  * @param xStreamBuffer The handle of the stream buffer being queried.
713  *
714  * @return The number of bytes that can be read from the stream buffer before
715  * the stream buffer would be empty.
716  *
717  * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable
718  * \ingroup StreamBufferManagement
719  */
720 size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
721
722 /**
723  * stream_buffer.h
724  *
725  * <pre>
726  * BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
727  * </pre>
728  *
729  * A stream buffer's trigger level is the number of bytes that must be in the
730  * stream buffer before a task that is blocked on the stream buffer to
731  * wait for data is moved out of the blocked state.  For example, if a task is
732  * blocked on a read of an empty stream buffer that has a trigger level of 1
733  * then the task will be unblocked when a single byte is written to the buffer
734  * or the task's block time expires.  As another example, if a task is blocked
735  * on a read of an empty stream buffer that has a trigger level of 10 then the
736  * task will not be unblocked until the stream buffer contains at least 10 bytes
737  * or the task's block time expires.  If a reading task's block time expires
738  * before the trigger level is reached then the task will still receive however
739  * many bytes are actually available.  Setting a trigger level of 0 will result
740  * in a trigger level of 1 being used.  It is not valid to specify a trigger
741  * level that is greater than the buffer size.
742  *
743  * A trigger level is set when the stream buffer is created, and can be modified
744  * using xStreamBufferSetTriggerLevel().
745  *
746  * @param xStreamBuffer The handle of the stream buffer being updated.
747  *
748  * @param xTriggerLevel The new trigger level for the stream buffer.
749  *
750  * @return If xTriggerLevel was less than or equal to the stream buffer's length
751  * then the trigger level will be updated and pdTRUE is returned.  Otherwise
752  * pdFALSE is returned.
753  *
754  * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel
755  * \ingroup StreamBufferManagement
756  */
757 BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
758                                          size_t xTriggerLevel ) PRIVILEGED_FUNCTION;
759
760 /**
761  * stream_buffer.h
762  *
763  * <pre>
764  * BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
765  * </pre>
766  *
767  * For advanced users only.
768  *
769  * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
770  * data is sent to a message buffer or stream buffer.  If there was a task that
771  * was blocked on the message or stream buffer waiting for data to arrive then
772  * the sbSEND_COMPLETED() macro sends a notification to the task to remove it
773  * from the Blocked state.  xStreamBufferSendCompletedFromISR() does the same
774  * thing.  It is provided to enable application writers to implement their own
775  * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
776  *
777  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
778  * additional information.
779  *
780  * @param xStreamBuffer The handle of the stream buffer to which data was
781  * written.
782  *
783  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
784  * initialised to pdFALSE before it is passed into
785  * xStreamBufferSendCompletedFromISR().  If calling
786  * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state,
787  * and the task has a priority above the priority of the currently running task,
788  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
789  * context switch should be performed before exiting the ISR.
790  *
791  * @return If a task was removed from the Blocked state then pdTRUE is returned.
792  * Otherwise pdFALSE is returned.
793  *
794  * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR
795  * \ingroup StreamBufferManagement
796  */
797 BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
798                                               BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
799
800 /**
801  * stream_buffer.h
802  *
803  * <pre>
804  * BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
805  * </pre>
806  *
807  * For advanced users only.
808  *
809  * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
810  * data is read out of a message buffer or stream buffer.  If there was a task
811  * that was blocked on the message or stream buffer waiting for data to arrive
812  * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
813  * remove it from the Blocked state.  xStreamBufferReceiveCompletedFromISR()
814  * does the same thing.  It is provided to enable application writers to
815  * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
816  * ANY OTHER TIME.
817  *
818  * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
819  * additional information.
820  *
821  * @param xStreamBuffer The handle of the stream buffer from which data was
822  * read.
823  *
824  * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
825  * initialised to pdFALSE before it is passed into
826  * xStreamBufferReceiveCompletedFromISR().  If calling
827  * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state,
828  * and the task has a priority above the priority of the currently running task,
829  * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
830  * context switch should be performed before exiting the ISR.
831  *
832  * @return If a task was removed from the Blocked state then pdTRUE is returned.
833  * Otherwise pdFALSE is returned.
834  *
835  * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR
836  * \ingroup StreamBufferManagement
837  */
838 BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
839                                                  BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
840
841 /* Functions below here are not part of the public API. */
842 StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes,
843                                                  size_t xTriggerLevelBytes,
844                                                  BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION;
845
846 StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
847                                                        size_t xTriggerLevelBytes,
848                                                        BaseType_t xIsMessageBuffer,
849                                                        uint8_t * const pucStreamBufferStorageArea,
850                                                        StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
851
852 size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
853
854 #if ( configUSE_TRACE_FACILITY == 1 )
855     void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer,
856                                              UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
857     UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
858     uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
859 #endif
860
861 /* *INDENT-OFF* */
862 #if defined( __cplusplus )
863     }
864 #endif
865 /* *INDENT-ON* */
866
867 #endif /* !defined( STREAM_BUFFER_H ) */