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