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