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