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