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