]> git.sur5r.net Git - freertos/blob - Source/include/queue.h
Update version number to V4.2.0.
[freertos] / Source / include / queue.h
1 /*\r
2         FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26         ***************************************************************************\r
27         See http://www.FreeRTOS.org for documentation, latest information, license \r
28         and contact details.  Please ensure to read the configuration and relevant \r
29         port sections of the online documentation.\r
30         ***************************************************************************\r
31 */\r
32 \r
33 #ifndef QUEUE_H\r
34 #define QUEUE_H\r
35 \r
36 typedef void * xQueueHandle;\r
37 \r
38 /**\r
39  * queue. h\r
40  * <pre>\r
41  xQueueHandle xQueueCreate( \r
42                               unsigned portBASE_TYPE uxQueueLength, \r
43                               unsigned portBASE_TYPE uxItemSize \r
44                           );\r
45  * </pre>\r
46  *\r
47  * Creates a new queue instance.  This allocates the storage required by the\r
48  * new queue and returns a handle for the queue.\r
49  *\r
50  * @param uxQueueLength The maximum number of items that the queue can contain.\r
51  *\r
52  * @param uxItemSize The number of bytes each item in the queue will require.  \r
53  * Items are queued by copy, not by reference, so this is the number of bytes\r
54  * that will be copied for each posted item.  Each item on the queue must be\r
55  * the same size.\r
56  *\r
57  * @return If the queue is successfully create then a handle to the newly \r
58  * created queue is returned.  If the queue cannot be created then 0 is\r
59  * returned.\r
60  * \r
61  * Example usage:\r
62    <pre>\r
63  struct AMessage\r
64  {\r
65     portCHAR ucMessageID;\r
66     portCHAR ucData[ 20 ];\r
67  };\r
68 \r
69  void vATask( void *pvParameters )\r
70  {\r
71  xQueueHandle xQueue1, xQueue2;\r
72 \r
73     // Create a queue capable of containing 10 unsigned long values.\r
74     xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
75     if( xQueue1 == 0 )\r
76     {\r
77         // Queue was not created and must not be used.\r
78     }\r
79 \r
80     // Create a queue capable of containing 10 pointers to AMessage structures.\r
81     // These should be passed by pointer as they contain a lot of data.\r
82     xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
83     if( xQueue2 == 0 )\r
84     {\r
85         // Queue was not created and must not be used.\r
86     }\r
87 \r
88     // ... Rest of task code.\r
89  }\r
90  </pre>\r
91  * \defgroup xQueueCreate xQueueCreate\r
92  * \ingroup QueueManagement\r
93  */\r
94 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );\r
95 \r
96 /**\r
97  * queue. h\r
98  * <pre>\r
99  portBASE_TYPE xQueueSend( \r
100                              xQueueHandle xQueue, \r
101                              const void * pvItemToQueue, \r
102                              portTickType xTicksToWait \r
103                          );\r
104  * </pre>\r
105  *\r
106  * Post an item on a queue.  The item is queued by copy, not by reference.\r
107  * This function must not be called from an interrupt service routine.\r
108  * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
109  *\r
110  * @param xQueue The handle to the queue on which the item is to be posted.\r
111  * \r
112  * @param pvItemToQueue A pointer to the item that is to be placed on the \r
113  * queue.  The size of the items the queue will hold was defined when the\r
114  * queue was created, so this many bytes will be copied from pvItemToQueue\r
115  * into the queue storage area.\r
116  *\r
117  * @param xTicksToWait The maximum amount of time the task should block\r
118  * waiting for space to become available on the queue, should it already\r
119  * be full.  The call will return immediately if this is set to 0.  The\r
120  * time is defined in tick periods so the constant portTICK_RATE_MS \r
121  * should be used to convert to real time if this is required.\r
122  *\r
123  * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
124  *\r
125  * Example usage:\r
126    <pre>\r
127  struct AMessage\r
128  {\r
129     portCHAR ucMessageID;\r
130     portCHAR ucData[ 20 ];\r
131  } xMessage;\r
132 \r
133  unsigned portLONG ulVar = 10UL;\r
134 \r
135  void vATask( void *pvParameters )\r
136  {\r
137  xQueueHandle xQueue1, xQueue2;\r
138  struct AMessage *pxMessage;\r
139 \r
140     // Create a queue capable of containing 10 unsigned long values.\r
141     xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
142 \r
143     // Create a queue capable of containing 10 pointers to AMessage structures.\r
144     // These should be passed by pointer as they contain a lot of data.\r
145     xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
146 \r
147     // ...\r
148 \r
149     if( xQueue1 != 0 )\r
150     {\r
151         // Send an unsigned long.  Wait for 10 ticks for space to become \r
152         // available if necessary.\r
153         if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
154         {\r
155             // Failed to post the message, even after 10 ticks.\r
156         }\r
157     }\r
158 \r
159     if( xQueue2 != 0 )\r
160     {\r
161         // Send a pointer to a struct AMessage object.  Don't block if the\r
162         // queue is already full.\r
163         pxMessage = & xMessage;\r
164         xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
165     }\r
166 \r
167         // ... Rest of task code.\r
168  }\r
169  </pre>\r
170  * \defgroup xQueueSend xQueueSend\r
171  * \ingroup QueueManagement\r
172  */\r
173 signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait );\r
174 \r
175 /**\r
176  * queue. h\r
177  * <pre>\r
178  portBASE_TYPE xQueueReceive( \r
179                                 xQueueHandle xQueue, \r
180                                 void *pvBuffer, \r
181                                 portTickType xTicksToWait \r
182                             );</pre>\r
183  *\r
184  * Receive an item from a queue.  The item is received by copy so a buffer of \r
185  * adequate size must be provided.  The number of bytes copied into the buffer\r
186  * was defined when the queue was created.\r
187  *\r
188  * This function must not be used in an interrupt service routine.  See\r
189  * xQueueReceiveFromISR for an alternative that can.\r
190  *\r
191  * @param pxQueue The handle to the queue from which the item is to be\r
192  * received.\r
193  *\r
194  * @param pvBuffer Pointer to the buffer into which the received item will\r
195  * be copied.\r
196  * \r
197  * @param xTicksToWait The maximum amount of time the task should block\r
198  * waiting for an item to receive should the queue be empty at the time\r
199  * of the call.    The time is defined in tick periods so the constant \r
200  * portTICK_RATE_MS should be used to convert to real time if this is required.\r
201  *\r
202  * @return pdTRUE if an item was successfully received from the queue,\r
203  * otherwise pdFALSE.\r
204  *\r
205  * Example usage:\r
206    <pre>\r
207  struct AMessage\r
208  {\r
209     portCHAR ucMessageID;\r
210     portCHAR ucData[ 20 ];\r
211  } xMessage;\r
212 \r
213  xQueueHandle xQueue;\r
214  \r
215  // Task to create a queue and post a value.\r
216  void vATask( void *pvParameters )\r
217  {\r
218  struct AMessage *pxMessage;\r
219 \r
220     // Create a queue capable of containing 10 pointers to AMessage structures.\r
221     // These should be passed by pointer as they contain a lot of data.\r
222     xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
223     if( xQueue == 0 )\r
224     {\r
225         // Failed to create the queue.\r
226     }\r
227 \r
228     // ...\r
229 \r
230     // Send a pointer to a struct AMessage object.  Don't block if the\r
231     // queue is already full.\r
232     pxMessage = & xMessage;\r
233     xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
234 \r
235         // ... Rest of task code.\r
236  }\r
237 \r
238  // Task to receive from the queue.\r
239  void vADifferentTask( void *pvParameters )\r
240  {\r
241  struct AMessage *pxRxedMessage;\r
242 \r
243     if( xQueue != 0 )\r
244     {\r
245         // Receive a message on the created queue.  Block for 10 ticks if a\r
246         // message is not immediately available.\r
247         if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
248         {\r
249             // pcRxedMessage now points to the struct AMessage variable posted\r
250             // by vATask.\r
251         }\r
252     }\r
253 \r
254         // ... Rest of task code.\r
255  }\r
256  </pre>\r
257  * \defgroup xQueueReceive xQueueReceive\r
258  * \ingroup QueueManagement\r
259  */\r
260 signed portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait );\r
261 \r
262 /**\r
263  * queue. h\r
264  * <pre>unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );</pre>\r
265  *\r
266  * Return the number of messages stored in a queue.\r
267  *\r
268  * @param xQueue A handle to the queue being queried.\r
269  * \r
270  * @return The number of messages available in the queue.\r
271  *\r
272  * \page uxQueueMessagesWaiting uxQueueMessagesWaiting\r
273  * \ingroup QueueManagement\r
274  */\r
275 unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );\r
276 \r
277 /**\r
278  * queue. h\r
279  * <pre>void vQueueDelete( xQueueHandle xQueue );</pre>\r
280  *\r
281  * Delete a queue - freeing all the memory allocated for storing of items\r
282  * placed on the queue.\r
283  * \r
284  * @param xQueue A handle to the queue to be deleted.\r
285  *\r
286  * \page vQueueDelete vQueueDelete\r
287  * \ingroup QueueManagement\r
288  */\r
289 void vQueueDelete( xQueueHandle xQueue );\r
290 \r
291 /**\r
292  * queue. h\r
293  * <pre>\r
294  portBASE_TYPE xQueueSendFromISR( \r
295                                     xQueueHandle pxQueue, \r
296                                     const void *pvItemToQueue, \r
297                                     portBASE_TYPE xTaskPreviouslyWoken \r
298                                 );\r
299  </pre>\r
300  *\r
301  * Post an item on a queue.  It is safe to use this function from within an\r
302  * interrupt service routine.\r
303  *\r
304  * Items are queued by copy not reference so it is preferable to only\r
305  * queue small items, especially when called from an ISR.  In most cases\r
306  * it would be preferable to store a pointer to the item being queued.\r
307  *\r
308  * @param xQueue The handle to the queue on which the item is to be posted.\r
309  * \r
310  * @param pvItemToQueue A pointer to the item that is to be placed on the \r
311  * queue.  The size of the items the queue will hold was defined when the\r
312  * queue was created, so this many bytes will be copied from pvItemToQueue\r
313  * into the queue storage area.\r
314  *\r
315  * @param cTaskPreviouslyWoken This is included so an ISR can post onto\r
316  * the same queue multiple times from a single interrupt.  The first call\r
317  * should always pass in pdFALSE.  Subsequent calls should pass in\r
318  * the value returned from the previous call.  See the file serial .c in the\r
319  * PC port for a good example of this mechanism.\r
320  *\r
321  * @return pdTRUE if a task was woken by posting onto the queue.  This is \r
322  * used by the ISR to determine if a context switch may be required following\r
323  * the ISR.\r
324  *\r
325  * Example usage for buffered IO (where the ISR can obtain more than one value\r
326  * per call):\r
327    <pre>\r
328  void vBufferISR( void )\r
329  {\r
330  portCHAR cIn;\r
331  portBASE_TYPE xTaskWokenByPost;\r
332 \r
333     // We have not woken a task at the start of the ISR.\r
334     cTaskWokenByPost = pdFALSE;\r
335 \r
336     // Loop until the buffer is empty.\r
337     do\r
338     {\r
339         // Obtain a byte from the buffer.\r
340         cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );                                            \r
341 \r
342         // Post the byte.  The first time round the loop cTaskWokenByPost\r
343         // will be pdFALSE.  If the queue send causes a task to wake we do\r
344         // not want the task to run until we have finished the ISR, so\r
345         // xQueueSendFromISR does not cause a context switch.  Also we \r
346         // don't want subsequent posts to wake any other tasks, so we store\r
347         // the return value back into cTaskWokenByPost so xQueueSendFromISR\r
348         // knows not to wake any task the next iteration of the loop.\r
349         xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost );\r
350 \r
351     } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
352 \r
353     // Now the buffer is empty we can switch context if necessary.\r
354     if( cTaskWokenByPost )\r
355     {\r
356         taskYIELD ();\r
357     }\r
358  }\r
359  </pre>\r
360  *\r
361  * \defgroup xQueueSendFromISR xQueueSendFromISR\r
362  * \ingroup QueueManagement\r
363  */\r
364 signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken );\r
365 \r
366 /**\r
367  * queue. h\r
368  * <pre>\r
369  portBASE_TYPE xQueueReceiveFromISR( \r
370                                        xQueueHandle pxQueue, \r
371                                        void *pvBuffer, \r
372                                        portBASE_TYPE *pxTaskWoken \r
373                                    ); \r
374  * </pre>\r
375  *\r
376  * Receive an item from a queue.  It is safe to use this function from within an\r
377  * interrupt service routine.\r
378  *\r
379  * @param pxQueue The handle to the queue from which the item is to be\r
380  * received.\r
381  *\r
382  * @param pvBuffer Pointer to the buffer into which the received item will\r
383  * be copied.\r
384  * \r
385  * @param pxTaskWoken A task may be blocked waiting for space to become\r
386  * available on the queue.  If xQueueReceiveFromISR causes such a task to\r
387  * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will\r
388  * remain unchanged.\r
389  *\r
390  * @return pdTRUE if an item was successfully received from the queue,\r
391  * otherwise pdFALSE.\r
392  *\r
393  * Example usage:\r
394    <pre>\r
395  \r
396  xQueueHandle xQueue;\r
397  \r
398  // Function to create a queue and post some values.\r
399  void vAFunction( void *pvParameters )\r
400  {\r
401  portCHAR cValueToPost;\r
402  const portTickType xBlockTime = ( portTickType )0xff;\r
403 \r
404     // Create a queue capable of containing 10 characters.\r
405     xQueue = xQueueCreate( 10, sizeof( portCHAR ) );\r
406     if( xQueue == 0 )\r
407     {\r
408         // Failed to create the queue.\r
409     }\r
410 \r
411     // ...\r
412 \r
413     // Post some characters that will be used within an ISR.  If the queue\r
414     // is full then this task will block for xBlockTime ticks.\r
415     cValueToPost = 'a';\r
416     xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
417     cValueToPost = 'b';\r
418     xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
419 \r
420     // ... keep posting characters ... this task may block when the queue\r
421     // becomes full.\r
422 \r
423     cValueToPost = 'c';\r
424     xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
425  }\r
426 \r
427  // ISR that outputs all the characters received on the queue. \r
428  void vISR_Routine( void )\r
429  {\r
430  portBASE_TYPE xTaskWokenByReceive = pdFALSE;\r
431  portCHAR cRxedChar;\r
432 \r
433     while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )\r
434     {\r
435         // A character was received.  Output the character now.\r
436         vOutputCharacter( cRxedChar );\r
437 \r
438         // If removing the character from the queue woke the task that was \r
439         // posting onto the queue cTaskWokenByReceive will have been set to\r
440         // pdTRUE.  No matter how many times this loop iterates only one\r
441         // task will be woken.\r
442     }\r
443 \r
444     if( cTaskWokenByPost != ( portCHAR ) pdFALSE;\r
445     {\r
446         taskYIELD ();\r
447     }\r
448  }\r
449  </pre>\r
450  * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
451  * \ingroup QueueManagement\r
452  */\r
453 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
454 \r
455 \r
456 /* \r
457  * The functions defined above are for passing data to and from tasks.  The \r
458  * functions below are the equivalents for passing data to and from \r
459  * co-rtoutines.\r
460  *\r
461  * These functions are called from the co-routine macro implementation and\r
462  * should not be called directly from application code.  Instead use the macro\r
463  * wrappers defined within croutine.h.\r
464  */\r
465 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
466 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
467 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );\r
468 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
469 \r
470 #endif\r
471 \r