]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/include/event_groups.h
3ca5ac3f5fb464a2076adb31750857b23686904f
[freertos] / FreeRTOS / Source / include / event_groups.h
1 /*\r
2     FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS provides completely free yet professionally developed,    *\r
10      *    robust, strictly quality controlled, supported, and cross          *\r
11      *    platform software that has become a de facto standard.             *\r
12      *                                                                       *\r
13      *    Help yourself get started quickly and support the FreeRTOS         *\r
14      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
15      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
16      *                                                                       *\r
17      *    Thank you!                                                         *\r
18      *                                                                       *\r
19     ***************************************************************************\r
20 \r
21     This file is part of the FreeRTOS distribution.\r
22 \r
23     FreeRTOS is free software; you can redistribute it and/or modify it under\r
24     the terms of the GNU General Public License (version 2) as published by the\r
25     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
26 \r
27     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
28     >>! a combined work that includes FreeRTOS without being obliged to provide\r
29     >>! the source code for proprietary components outside of the FreeRTOS\r
30     >>! kernel.\r
31 \r
32     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
33     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
34     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
35     link: http://www.freertos.org/a00114.html\r
36 \r
37     1 tab == 4 spaces!\r
38 \r
39     ***************************************************************************\r
40      *                                                                       *\r
41      *    Having a problem?  Start by reading the FAQ "My application does   *\r
42      *    not run, what could be wrong?"                                     *\r
43      *                                                                       *\r
44      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
49     license and Real Time Engineers Ltd. contact details.\r
50 \r
51     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
52     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
53     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
54 \r
55     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
56     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
57     licenses offer ticketed support, indemnification and middleware.\r
58 \r
59     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
60     engineered and independently SIL3 certified version for use in safety and\r
61     mission critical applications that require provable dependability.\r
62 \r
63     1 tab == 4 spaces!\r
64 */\r
65 \r
66 #ifndef EVENT_GROUPS_H\r
67 #define EVENT_GROUPS_H\r
68 \r
69 #ifndef INC_FREERTOS_H\r
70         #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"\r
71 #endif\r
72 \r
73 #include "timers.h"\r
74 \r
75 #ifdef __cplusplus\r
76 extern "C" {\r
77 #endif\r
78 \r
79 /**\r
80  * An event group is a collection of bits to which an application can assign a\r
81  * meaning.  For example, an application may create an event group to convey\r
82  * the status of various CAN bus related events in which bit 0 might mean "A CAN\r
83  * message has been received and is ready for processing", bit 1 might mean "The\r
84  * application has queued a message that is ready for sending onto the CAN\r
85  * network", and bit 2 might mean "it is time to send a SYNC message onto the\r
86  * CAN network" etc.  A task can then test the bit values to see which events\r
87  * are active, and optionally enter the Blocked state to wait for a specified\r
88  * bit or a group of specified bits to be active.  To continue the CAN bus\r
89  * example, a CAN controlling task can enter the Blocked state (and therefore\r
90  * not consume any processing time) until either bit 0, bit 1 or bit 2 are\r
91  * active, at which time the bit that was actually active would inform the task\r
92  * which action it had to take (process a received message, send a message, or\r
93  * send a SYNC).\r
94  *\r
95  * The event groups implementation contains intelligence to avoid race\r
96  * conditions that would otherwise occur were an application to use a simple\r
97  * variable for the same purpose.  This is particularly important with respect\r
98  * to when a bit within an event group is to be cleared, and when bits have to\r
99  * be set and then tested atomically - as is the case where event groups are\r
100  * used to create a synchronisation point between multiple tasks (a\r
101  * 'rendezvous').\r
102  *\r
103  * \defgroup EventGroup\r
104  */\r
105 \r
106 \r
107 \r
108 /**\r
109  * event_groups.h\r
110  *\r
111  * Type by which event groups are referenced.  For example, a call to\r
112  * xEventGroupCreate() returns an xEventGroupHandle variable that can then\r
113  * be used as a parameter to other event group functions.\r
114  *\r
115  * \defgroup xEventGroupHandle xEventGroupHandle\r
116  * \ingroup EventGroup\r
117  */\r
118 typedef void * xEventGroupHandle;\r
119 \r
120 /**\r
121  * event_groups.h\r
122  *<pre>\r
123  xEventGroupHandle xEventGroupCreate( void );\r
124  </pre>\r
125  *\r
126  * Create a new event group.  This function cannot be called from an interrupt.\r
127  *\r
128  * Although event groups are not related to ticks, for internal implementation\r
129  * reasons the number of bits available for use in an event group is dependent\r
130  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If\r
131  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit\r
132  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has\r
133  * 24 usable bits (bit 0 to bit 23).  The xEventBitsType type is used to store\r
134  * event bits within an event group.\r
135  *\r
136  * @return If the event group was created then a handle to the event group is\r
137  * returned.  If there was insufficient FreeRTOS heap available to create the\r
138  * event group then NULL is returned.  See http://www.freertos.org/a00111.html\r
139  *\r
140  * Example usage:\r
141    <pre>\r
142         // Declare a variable to hold the created event group.\r
143         xEventGroupHandle xCreatedEventGroup;\r
144 \r
145         // Attempt to create the event group.\r
146         xCreatedEventGroup = xEventGroupCreate();\r
147 \r
148         // Was the event group created successfully?\r
149         if( xCreatedEventGroup == NULL )\r
150         {\r
151                 // The event group was not created because there was insufficient\r
152                 // FreeRTOS heap available.\r
153         }\r
154         else\r
155         {\r
156                 // The event group was created.\r
157         }\r
158    </pre>\r
159  * \defgroup xEventGroupCreate xEventGroupCreate\r
160  * \ingroup EventGroup\r
161  */\r
162 xEventGroupHandle xEventGroupCreate( void ) PRIVILEGED_FUNCTION;\r
163 \r
164 /**\r
165  * event_groups.h\r
166  *<pre>\r
167         xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup,\r
168                                                                                 xEventBitsType uxBitsToWaitFor,\r
169                                                                                 portBASE_TYPE xClearOnExit,\r
170                                                                                 portBASE_TYPE xWaitForAllBits,\r
171                                                                                 portTickType xTicksToWait );\r
172  </pre>\r
173  *\r
174  * [Potentially] block to wait for one or more bits to be set within a\r
175  * previously created event group.\r
176  *\r
177  * This function cannot be called from an interrupt.\r
178  *\r
179  * @param xEventGroup The event group in which the bits are being tested.  The\r
180  * event group must have previously been created using a call to\r
181  * xEventGroupCreate().\r
182  *\r
183  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test\r
184  * inside the event group.  For example, to wait for bit 0 and/or bit 2 set\r
185  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set\r
186  * uxBitsToWaitFor to 0x07.  Etc.\r
187  *\r
188  * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within\r
189  * uxBitsToWaitFor that are set within the event group will be cleared before\r
190  * xEventGroupWaitBits() returns.  If xClearOnExit is set to pdFALSE then the\r
191  * bits set in the event group are not altered when the call to\r
192  * xEventGroupWaitBits() returns.\r
193  *\r
194  * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then\r
195  * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor\r
196  * are set or the specified block time expires.  If xWaitForAllBits is set to\r
197  * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set\r
198  * in uxBitsToWaitFor is set or the specified block time expires.\r
199  *\r
200  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait\r
201  * for one/all (depending on the xWaitForAllBits value) of the bits specified by\r
202  * uxBitsToWaitFor to become set.\r
203  *\r
204  * @return The value of the event group at the time either the bits being waited\r
205  * for became set, or the block time expired.  Test the return value to know\r
206  * which bits were set.  If xEventGroupWaitBits() returned because its timeout\r
207  * expired then not all the bits being waited for will be set.  If\r
208  * xEventGroupWaitBits() returned because the bits it was waiting for were set\r
209  * then the returned value is the event group value before any bits were\r
210  * automatically cleared because the xClearOnExit parameter was set to pdTRUE.\r
211  *\r
212  * Example usage:\r
213    <pre>\r
214    #define BIT_0        ( 1 << 0 )\r
215    #define BIT_4        ( 1 << 4 )\r
216 \r
217    void aFunction( xEventGroupHandle xEventGroup )\r
218    {\r
219    xEventBitsType uxBits;\r
220    const portTickType xTicksToWait = 100 / portTICK_RATE_MS;\r
221 \r
222                 // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within\r
223                 // the event group.  Clear the bits before exiting.\r
224                 uxBits = xEventGroupWaitBits(\r
225                                         xEventGroup,    // The event group being tested.\r
226                                         BIT_0 | BIT_4,  // The bits within the event group to wait for.\r
227                                         pdTRUE,                 // BIT_0 and BIT_4 should be cleared before returning.\r
228                                         pdFALSE,                // Don't wait for both bits, either bit will do.\r
229                                         xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.\r
230 \r
231                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
232                 {\r
233                         // xEventGroupWaitBits() returned because both bits were set.\r
234                 }\r
235                 else if( ( uxBits & BIT_0 ) != 0 )\r
236                 {\r
237                         // xEventGroupWaitBits() returned because just BIT_0 was set.\r
238                 }\r
239                 else if( ( uxBits & BIT_4 ) != 0 )\r
240                 {\r
241                         // xEventGroupWaitBits() returned because just BIT_4 was set.\r
242                 }\r
243                 else\r
244                 {\r
245                         // xEventGroupWaitBits() returned because xTicksToWait ticks passed\r
246                         // without either BIT_0 or BIT_4 becoming set.\r
247                 }\r
248    }\r
249    </pre>\r
250  * \defgroup xEventGroupWaitBits xEventGroupWaitBits\r
251  * \ingroup EventGroup\r
252  */\r
253 xEventBitsType xEventGroupWaitBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToWaitFor, portBASE_TYPE xClearOnExit, portBASE_TYPE xWaitForAllBits, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
254 \r
255 /**\r
256  * event_groups.h\r
257  *<pre>\r
258         xEventBitsType xEventGroupClearBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToClear );\r
259  </pre>\r
260  *\r
261  * Clear bits within an event group.  This function cannot be called from an\r
262  * interrupt.\r
263  *\r
264  * @param xEventGroup The event group in which the bits are to be cleared.\r
265  *\r
266  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear\r
267  * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to\r
268  * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.\r
269  *\r
270  * @return The value of the event group before the specified bits were cleared.\r
271  *\r
272  * Example usage:\r
273    <pre>\r
274    #define BIT_0        ( 1 << 0 )\r
275    #define BIT_4        ( 1 << 4 )\r
276 \r
277    void aFunction( xEventGroupHandle xEventGroup )\r
278    {\r
279    xEventBitsType uxBits;\r
280 \r
281                 // Clear bit 0 and bit 4 in xEventGroup.\r
282                 uxBits = xEventGroupClearBits(\r
283                                                                 xEventGroup,    // The event group being updated.\r
284                                                                 BIT_0 | BIT_4 );// The bits being cleared.\r
285 \r
286                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
287                 {\r
288                         // Both bit 0 and bit 4 were set before the call to\r
289                         // xEventGroupClearBits() was called.  Both will now be clear (not\r
290                         // set).\r
291                 }\r
292                 else if( ( uxBits & BIT_0 ) != 0 )\r
293                 {\r
294                         // Bit 0 was set before xEventGroupClearBits() was called.  It will\r
295                         // now be clear.\r
296                 }\r
297                 else if( ( uxBits & BIT_4 ) != 0 )\r
298                 {\r
299                         // Bit 4 was set before xEventGroupClearBits() was called.  It will\r
300                         // now be clear.\r
301                 }\r
302                 else\r
303                 {\r
304                         // Neither bit 0 nor bit 4 were set in the first place.\r
305                 }\r
306    }\r
307    </pre>\r
308  * \defgroup xEventGroupClearBits xEventGroupClearBits\r
309  * \ingroup EventGroup\r
310  */\r
311 xEventBitsType xEventGroupClearBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToClear ) PRIVILEGED_FUNCTION;\r
312 \r
313 /**\r
314  * event_groups.h\r
315  *<pre>\r
316         xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet );\r
317  </pre>\r
318  *\r
319  * Set bits within an event group.\r
320  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()\r
321  * is a version that can be called from an interrupt.\r
322  *\r
323  * Setting bits in an event group will automatically unblock tasks that are\r
324  * blocked waiting for the bits.\r
325  *\r
326  * @param xEventGroup The event group in which the bits are to be set.\r
327  *\r
328  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
329  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3\r
330  * and bit 0 set uxBitsToSet to 0x09.\r
331  *\r
332  * @return The value of the event group at the time the call to\r
333  * xEventGroupSetBits() returns.  There are two reasons why the returned value\r
334  * might have the bits specified by the uxBitsToSet parameter cleared.  First,\r
335  * if setting a bit results in a task that was waiting for the bit leaving the\r
336  * blocked state then it is possible the bit will be cleared automatically\r
337  * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any\r
338  * unblocked (or otherwise Ready state) task that has a priority above that of\r
339  * the task that called xEventGroupSetBits() will execute and may change the\r
340  * event group value before the call to xEventGroupSetBits() returns.\r
341  *\r
342  * Example usage:\r
343    <pre>\r
344    #define BIT_0        ( 1 << 0 )\r
345    #define BIT_4        ( 1 << 4 )\r
346 \r
347    void aFunction( xEventGroupHandle xEventGroup )\r
348    {\r
349    xEventBitsType uxBits;\r
350 \r
351                 // Set bit 0 and bit 4 in xEventGroup.\r
352                 uxBits = xEventGroupSetBits(\r
353                                                         xEventGroup,    // The event group being updated.\r
354                                                         BIT_0 | BIT_4 );// The bits being set.\r
355 \r
356                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
357                 {\r
358                         // Both bit 0 and bit 4 remained set when the function returned.\r
359                 }\r
360                 else if( ( uxBits & BIT_0 ) != 0 )\r
361                 {\r
362                         // Bit 0 remained set when the function returned, but bit 4 was\r
363                         // cleared.  It might be that bit 4 was cleared automatically as a\r
364                         // task that was waiting for bit 4 was removed from the Blocked\r
365                         // state.\r
366                 }\r
367                 else if( ( uxBits & BIT_4 ) != 0 )\r
368                 {\r
369                         // Bit 4 remained set when the function returned, but bit 0 was\r
370                         // cleared.  It might be that bit 0 was cleared automatically as a\r
371                         // task that was waiting for bit 0 was removed from the Blocked\r
372                         // state.\r
373                 }\r
374                 else\r
375                 {\r
376                         // Neither bit 0 nor bit 4 remained set.  It might be that a task\r
377                         // was waiting for either or both of the bits to be set, and the\r
378                         // bits were cleared as the task left the Blocked state.\r
379                 }\r
380    }\r
381    </pre>\r
382  * \defgroup xEventGroupSetBits xEventGroupSetBits\r
383  * \ingroup EventGroup\r
384  */\r
385 xEventBitsType xEventGroupSetBits( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet ) PRIVILEGED_FUNCTION;\r
386 \r
387 /**\r
388  * event_groups.h\r
389  *<pre>\r
390         xEventBitsType xEventGroupSetBitsFromISR( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, portBASE_TYPE *pxHigherPriorityTaskWoken );\r
391  </pre>\r
392  *\r
393  * A version of xEventGroupSetBits() that can be called from an interrupt.\r
394  *\r
395  * Setting bits in an event group is not a deterministic operation because there\r
396  * are an unknown number of tasks that may be waiting for the bit or bits being\r
397  * set.  FreeRTOS does not allow nondeterministic operations to be performed in\r
398  * interrupts or from critical sections.  Therefore xEventGroupSetBitFromISR()\r
399  * sends a message to the timer task to have the set operation performed in the\r
400  * context of the timer task - where a scheduler lock is used in place of a\r
401  * critical section.\r
402  *\r
403  * @param xEventGroup The event group in which the bits are to be set.\r
404  *\r
405  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
406  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3\r
407  * and bit 0 set uxBitsToSet to 0x09.\r
408  *\r
409  * @ pxHigherPriorityTaskWoken As mentioned above, calling this function will\r
410  * result in a message being sent to the timer daemon task.  If the priority of\r
411  * the timer daemon task is higher than the priority of the currently running\r
412  * task (the task the interrupt interrupted) then *pxHigherPriorityTaskWoken\r
413  * will be set to pdTRUE by xEventGroupSetBitsFromISR(), indicating that a\r
414  * context switch should be requested before the interrupt exits.  For that\r
415  * reason *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the\r
416  * example code below.\r
417  *\r
418  * @return If the callback request was registered successfully then pdPASS is\r
419  * returned, otherwise pdFALSE is returned.  pdFALSE will be returned if the\r
420  * timer service queue was full.\r
421  *\r
422  * Example usage:\r
423    <pre>\r
424    #define BIT_0        ( 1 << 0 )\r
425    #define BIT_4        ( 1 << 4 )\r
426 \r
427    // An event group which it is assume has already been created by a call to\r
428    // xEventGroupCreate().\r
429    xEventGroupHandle xEventGroup;\r
430 \r
431    void anInterruptHandler( void )\r
432    {\r
433    portBASE_TYPE xHigherPriorityTaskWoken;\r
434 \r
435                 // xHigherPriorityTaskWoken must be initialised to pdFALSE;\r
436                 xHigherPriorityTaskWoken = pdFALSE;\r
437 \r
438                 // Set bit 0 and bit 4 in xEventGroup.\r
439                 uxBits = xEventGroupSetBitsFromISR(\r
440                                                         xEventGroup,    // The event group being updated.\r
441                                                         BIT_0 | BIT_4   // The bits being set.\r
442                                                         &xHigherPriorityTaskWoken );\r
443 \r
444                 // If xHigherPriorityTaskWoken is now set to pdTRUE then a context\r
445                 // switch should be requested.  The macro used is port specific and will\r
446                 // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to\r
447                 // the documentation page for the port being used.\r
448                 portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
449    }\r
450    </pre>\r
451  * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR\r
452  * \ingroup EventGroup\r
453  */\r
454 #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendCallbackFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( unsigned long ) uxBitsToSet, pxHigherPriorityTaskWoken )\r
455 \r
456 /**\r
457  * event_groups.h\r
458  *<pre>\r
459         xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup,\r
460                                                                         xEventBitsType uxBitsToSet,\r
461                                                                         xEventBitsType uxBitsToWaitFor,\r
462                                                                         portTickType xTicksToWait );\r
463  </pre>\r
464  *\r
465  * Atomically set bits within an event group, then wait for a combination of\r
466  * bits to be set within the same event group.  This functionality is typically\r
467  * used to synchronise multiple tasks, where each task has to wait for the other\r
468  * tasks to reach a synchronisation point before proceeding.\r
469  *\r
470  * This function cannot be used from an interrupt.\r
471  *\r
472  * The function will return before its block time expires if the bits specified\r
473  * by the uxBitsToWait parameter are set, or become set within that time.  In\r
474  * this case all the bits specified by uxBitsToWait will be automatically\r
475  * cleared before the function returns.\r
476  *\r
477  * @param xEventGroup The event group in which the bits are being tested.  The\r
478  * event group must have previously been created using a call to\r
479  * xEventGroupCreate().\r
480  *\r
481  * @param uxBitsToSet The bits to set in the event group before determining\r
482  * if, and possibly waiting for, all the bits specified by the uxBitsToWait\r
483  * parameter are set.\r
484  *\r
485  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test\r
486  * inside the event group.  For example, to wait for bit 0 and bit 2 set\r
487  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set\r
488  * uxBitsToWaitFor to 0x07.  Etc.\r
489  *\r
490  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait\r
491  * for all of the bits specified by uxBitsToWaitFor to become set.\r
492  *\r
493  * @return The value of the event group at the time either the bits being waited\r
494  * for became set, or the block time expired.  Test the return value to know\r
495  * which bits were set.  If xEventGroupSync() returned because its timeout\r
496  * expired then not all the bits being waited for will be set.  If\r
497  * xEventGroupSync() returned because all the bits it was waiting for were\r
498  * set then the returned value is the event group value before any bits were\r
499  * automatically cleared.\r
500  *\r
501  * Example usage:\r
502  <pre>\r
503  // Bits used by the three tasks.\r
504  #define TASK_0_BIT             ( 1 << 0 )\r
505  #define TASK_1_BIT             ( 1 << 1 )\r
506  #define TASK_2_BIT             ( 1 << 2 )\r
507 \r
508  #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )\r
509 \r
510  // Use an event group to synchronise three tasks.  It is assumed this event\r
511  // group has already been created elsewhere.\r
512  xEventGroupHandle xEventBits;\r
513 \r
514  void vTask0( void *pvParameters )\r
515  {\r
516  xEventBitsType uxReturn;\r
517  portTickType xTicksToWait = 100 / portTICK_RATE_MS;\r
518 \r
519          for( ;; )\r
520          {\r
521                 // Perform task functionality here.\r
522 \r
523                 // Set bit 0 in the event flag to note this task has reached the\r
524                 // sync point.  The other two tasks will set the other two bits defined\r
525                 // by ALL_SYNC_BITS.  All three tasks have reached the synchronisation\r
526                 // point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms\r
527                 // for this to happen.\r
528                 uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );\r
529 \r
530                 if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )\r
531                 {\r
532                         // All three tasks reached the synchronisation point before the call\r
533                         // to xEventGroupSync() timed out.\r
534                 }\r
535         }\r
536  }\r
537 \r
538  void vTask1( void *pvParameters )\r
539  {\r
540          for( ;; )\r
541          {\r
542                 // Perform task functionality here.\r
543 \r
544                 // Set bit 1 in the event flag to note this task has reached the\r
545                 // synchronisation point.  The other two tasks will set the other two\r
546                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the\r
547                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait\r
548                 // indefinitely for this to happen.\r
549                 xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
550 \r
551                 // xEventGroupSync() was called with an indefinite block time, so\r
552                 // this task will only reach here if the syncrhonisation was made by all\r
553                 // three tasks, so there is no need to test the return value.\r
554          }\r
555  }\r
556 \r
557  void vTask2( void *pvParameters )\r
558  {\r
559          for( ;; )\r
560          {\r
561                 // Perform task functionality here.\r
562 \r
563                 // Set bit 2 in the event flag to note this task has reached the\r
564                 // synchronisation point.  The other two tasks will set the other two\r
565                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the\r
566                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait\r
567                 // indefinitely for this to happen.\r
568                 xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
569 \r
570                 // xEventGroupSync() was called with an indefinite block time, so\r
571                 // this task will only reach here if the syncrhonisation was made by all\r
572                 // three tasks, so there is no need to test the return value.\r
573         }\r
574  }\r
575 \r
576  </pre>\r
577  * \defgroup xEventGroupSync xEventGroupSync\r
578  * \ingroup EventGroup\r
579  */\r
580 xEventBitsType xEventGroupSync( xEventGroupHandle xEventGroup, xEventBitsType uxBitsToSet, xEventBitsType uxBitsToWaitFor, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
581 \r
582 \r
583 /**\r
584  * event_groups.h\r
585  *<pre>\r
586         xEventBitsType xEventGroupGetBits( xEventGroupHandle xEventGroup );\r
587  </pre>\r
588  *\r
589  * Returns the current value of the bits in an event group.  This function\r
590  * cannot be used from an interrupt.\r
591  *\r
592  * @param xEventGroup The event group being queried.\r
593  *\r
594  * @return The event group bits at the time xEventGroupGetBits() was called.\r
595  *\r
596  * \defgroup xEventGroupGetBits xEventGroupGetBits\r
597  * \ingroup EventGroup\r
598  */\r
599 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )\r
600 \r
601 /**\r
602  * event_groups.h\r
603  *<pre>\r
604         void xEventGroupDelete( xEventGroupHandle xEventGroup );\r
605  </pre>\r
606  *\r
607  * Delete an event group that was previously created by a call to\r
608  * xEventGroupCreate().  Tasks that are blocked on the event group will be\r
609  * unblocked and obtain 0 as the event group's value.\r
610  *\r
611  * @param xEventGroup The event group being deleted.\r
612  */\r
613 void vEventGroupDelete( xEventGroupHandle xEventGroup );\r
614 \r
615 /* For internal use only. */\r
616 void vEventGroupSetBitsCallback( void *pvEventGroup, unsigned long ulBitsToSet );\r
617 \r
618 \r
619 #ifdef __cplusplus\r
620 }\r
621 #endif\r
622 \r
623 #endif /* EVENT_GROUPS_H */\r
624 \r
625 \r