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