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