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