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