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