1 /*
2  * FreeRTOS Kernel V10.2.1
3  * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * http://www.FreeRTOS.org
23  * http://aws.amazon.com/freertos
24  *
25  * 1 tab == 4 spaces!
26  */
27 
28 #ifndef EVENT_GROUPS_H
29 #define EVENT_GROUPS_H
30 
31 #ifndef INC_FREERTOS_H
32 	#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
33 #endif
34 
35 /* FreeRTOS includes. */
36 #include "timers.h"
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 /**
43  * An event group is a collection of bits to which an application can assign a
44  * meaning.  For example, an application may create an event group to convey
45  * the status of various CAN bus related events in which bit 0 might mean "A CAN
46  * message has been received and is ready for processing", bit 1 might mean "The
47  * application has queued a message that is ready for sending onto the CAN
48  * network", and bit 2 might mean "It is time to send a SYNC message onto the
49  * CAN network" etc.  A task can then test the bit values to see which events
50  * are active, and optionally enter the Blocked state to wait for a specified
51  * bit or a group of specified bits to be active.  To continue the CAN bus
52  * example, a CAN controlling task can enter the Blocked state (and therefore
53  * not consume any processing time) until either bit 0, bit 1 or bit 2 are
54  * active, at which time the bit that was actually active would inform the task
55  * which action it had to take (process a received message, send a message, or
56  * send a SYNC).
57  *
58  * The event groups implementation contains intelligence to avoid race
59  * conditions that would otherwise occur were an application to use a simple
60  * variable for the same purpose.  This is particularly important with respect
61  * to when a bit within an event group is to be cleared, and when bits have to
62  * be set and then tested atomically - as is the case where event groups are
63  * used to create a synchronisation point between multiple tasks (a
64  * 'rendezvous').
65  *
66  */
67 
68 
69 
70 /**
71  * event_groups.h
72  *
73  * Type by which event groups are referenced.  For example, a call to
74  * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
75  * be used as a parameter to other event group functions.
76  *
77  * \defgroup EventGroupHandle_t EventGroupHandle_t
78  * \ingroup EventGroup
79  */
80 struct EventGroupDef_t;
81 //typedef struct EventGroupDef_t * EventGroupHandle_t;
82 typedef void * EventGroupHandle_t;
83 
84 /*
85  * The type that holds event bits always matches TickType_t - therefore the
86  * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
87  * 32 bits if set to 0.
88  *
89  * \defgroup EventBits_t EventBits_t
90  * \ingroup EventGroup
91  */
92 typedef TickType_t EventBits_t;
93 
94 /**
95  *
96  *
97  * Create a new event group.
98  *
99  * Internally, within the FreeRTOS implementation, event groups use a [small]
100  * block of memory, in which the event group's structure is stored.  If an event
101  * groups is created using xEventGropuCreate() then the required memory is
102  * automatically dynamically allocated inside the xEventGroupCreate() function.
103  * (see http://www.freertos.org/a00111.html).  If an event group is created
104  * using xEventGropuCreateStatic() then the application writer must instead
105  * provide the memory that will get used by the event group.
106  * xEventGroupCreateStatic() therefore allows an event group to be created
107  * without using any dynamic memory allocation.
108  *
109  * Although event groups are not related to ticks, for internal implementation
110  * reasons the number of bits available for use in an event group is dependent
111  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If
112  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
113  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has
114  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store
115  * event bits within an event group.
116  *
117  * @return If the event group was created then a handle to the event group is
118  * returned.  If there was insufficient FreeRTOS heap available to create the
119  * event group then NULL is returned.  See http://www.freertos.org/a00111.html
120  *
121  * Example usage:
122  * @code{c}
123  * 	// Declare a variable to hold the created event group.
124  * 	EventGroupHandle_t xCreatedEventGroup;
125  *
126  * 	// Attempt to create the event group.
127  * 	xCreatedEventGroup = xEventGroupCreate();
128  *
129  * 	// Was the event group created successfully?
130  * 	if( xCreatedEventGroup == NULL )
131  * 	{
132  * 		// The event group was not created because there was insufficient
133  * 		// FreeRTOS heap available.
134  * 	}
135  * 	else
136  * 	{
137  * 		// The event group was created.
138  * 	}
139  * @endcode
140  * \ingroup EventGroup
141  */
142 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
143 	EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
144 #endif
145 
146 /**
147  * Create a new event group.
148  *
149  * Internally, within the FreeRTOS implementation, event groups use a [small]
150  * block of memory, in which the event group's structure is stored.  If an event
151  * groups is created using xEventGropuCreate() then the required memory is
152  * automatically dynamically allocated inside the xEventGroupCreate() function.
153  * (see http://www.freertos.org/a00111.html).  If an event group is created
154  * using xEventGropuCreateStatic() then the application writer must instead
155  * provide the memory that will get used by the event group.
156  * xEventGroupCreateStatic() therefore allows an event group to be created
157  * without using any dynamic memory allocation.
158  *
159  * Although event groups are not related to ticks, for internal implementation
160  * reasons the number of bits available for use in an event group is dependent
161  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If
162  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
163  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has
164  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store
165  * event bits within an event group.
166  *
167  * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
168  * StaticEventGroup_t, which will be then be used to hold the event group's data
169  * structures, removing the need for the memory to be allocated dynamically.
170  *
171  * @return If the event group was created then a handle to the event group is
172  * returned.  If pxEventGroupBuffer was NULL then NULL is returned.
173  *
174  * Example usage:
175  * @code{c}
176  * 	// StaticEventGroup_t is a publicly accessible structure that has the same
177  * 	// size and alignment requirements as the real event group structure.  It is
178  * 	// provided as a mechanism for applications to know the size of the event
179  * 	// group (which is dependent on the architecture and configuration file
180  * 	// settings) without breaking the strict data hiding policy by exposing the
181  * 	// real event group internals.  This StaticEventGroup_t variable is passed
182  * 	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
183  * 	// the event group's data structures
184  * 	StaticEventGroup_t xEventGroupBuffer;
185  *
186  * 	// Create the event group without dynamically allocating any memory.
187  * 	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
188  * @endcode
189  */
190 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
191 	EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
192 #endif
193 
194 /**
195  * [Potentially] block to wait for one or more bits to be set within a
196  * previously created event group.
197  *
198  * This function cannot be called from an interrupt.
199  *
200  * @param xEventGroup The event group in which the bits are being tested.  The
201  * event group must have previously been created using a call to
202  * xEventGroupCreate().
203  *
204  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
205  * inside the event group.  For example, to wait for bit 0 and/or bit 2 set
206  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set
207  * uxBitsToWaitFor to 0x07.  Etc.
208  *
209  * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
210  * uxBitsToWaitFor that are set within the event group will be cleared before
211  * xEventGroupWaitBits() returns if the wait condition was met (if the function
212  * returns for a reason other than a timeout).  If xClearOnExit is set to
213  * pdFALSE then the bits set in the event group are not altered when the call to
214  * xEventGroupWaitBits() returns.
215  *
216  * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
217  * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
218  * are set or the specified block time expires.  If xWaitForAllBits is set to
219  * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
220  * in uxBitsToWaitFor is set or the specified block time expires.  The block
221  * time is specified by the xTicksToWait parameter.
222  *
223  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
224  * for one/all (depending on the xWaitForAllBits value) of the bits specified by
225  * uxBitsToWaitFor to become set.
226  *
227  * @return The value of the event group at the time either the bits being waited
228  * for became set, or the block time expired.  Test the return value to know
229  * which bits were set.  If xEventGroupWaitBits() returned because its timeout
230  * expired then not all the bits being waited for will be set.  If
231  * xEventGroupWaitBits() returned because the bits it was waiting for were set
232  * then the returned value is the event group value before any bits were
233  * automatically cleared in the case that xClearOnExit parameter was set to
234  * pdTRUE.
235  *
236  * Example usage:
237  * @code{c}
238  *    #define BIT_0	( 1 << 0 )
239  *    #define BIT_4	( 1 << 4 )
240  *
241  *    void aFunction( EventGroupHandle_t xEventGroup )
242  *    {
243  *    EventBits_t uxBits;
244  *    const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
245  *
246  * 		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
247  * 		// the event group.  Clear the bits before exiting.
248  * 		uxBits = xEventGroupWaitBits(
249  * 					xEventGroup,	// The event group being tested.
250  * 					BIT_0 | BIT_4,	// The bits within the event group to wait for.
251  * 					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
252  * 					pdFALSE,		// Don't wait for both bits, either bit will do.
253  * 					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
254  *
255  * 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
256  * 		{
257  * 			// xEventGroupWaitBits() returned because both bits were set.
258  * 		}
259  * 		else if( ( uxBits & BIT_0 ) != 0 )
260  * 		{
261  * 			// xEventGroupWaitBits() returned because just BIT_0 was set.
262  * 		}
263  * 		else if( ( uxBits & BIT_4 ) != 0 )
264  * 		{
265  * 			// xEventGroupWaitBits() returned because just BIT_4 was set.
266  * 		}
267  * 		else
268  * 		{
269  * 			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
270  * 			// without either BIT_0 or BIT_4 becoming set.
271  * 		}
272  *    }
273  * @endcode{c}
274  * \ingroup EventGroup
275  */
276 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
277 
278 /**
279  *
280  * Clear bits within an event group.  This function cannot be called from an
281  * interrupt.
282  *
283  * @param xEventGroup The event group in which the bits are to be cleared.
284  *
285  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
286  * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to
287  * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
288  *
289  * @return The value of the event group before the specified bits were cleared.
290  *
291  * Example usage:
292  * @code{c}
293  *    #define BIT_0	( 1 << 0 )
294  *    #define BIT_4	( 1 << 4 )
295  *
296  *    void aFunction( EventGroupHandle_t xEventGroup )
297  *    {
298  *    EventBits_t uxBits;
299  *
300  * 		// Clear bit 0 and bit 4 in xEventGroup.
301  * 		uxBits = xEventGroupClearBits(
302  * 								xEventGroup,	// The event group being updated.
303  * 								BIT_0 | BIT_4 );// The bits being cleared.
304  *
305  * 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
306  * 		{
307  * 			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
308  * 			// called.  Both will now be clear (not set).
309  * 		}
310  * 		else if( ( uxBits & BIT_0 ) != 0 )
311  * 		{
312  * 			// Bit 0 was set before xEventGroupClearBits() was called.  It will
313  * 			// now be clear.
314  * 		}
315  * 		else if( ( uxBits & BIT_4 ) != 0 )
316  * 		{
317  * 			// Bit 4 was set before xEventGroupClearBits() was called.  It will
318  * 			// now be clear.
319  * 		}
320  * 		else
321  * 		{
322  * 			// Neither bit 0 nor bit 4 were set in the first place.
323  * 		}
324  *    }
325  * @endcode
326  * \ingroup EventGroup
327  */
328 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
329 
330 /**
331  *
332  * A version of xEventGroupClearBits() that can be called from an interrupt.
333  *
334  * Setting bits in an event group is not a deterministic operation because there
335  * are an unknown number of tasks that may be waiting for the bit or bits being
336  * set.  FreeRTOS does not allow nondeterministic operations to be performed
337  * while interrupts are disabled, so protects event groups that are accessed
338  * from tasks by suspending the scheduler rather than disabling interrupts.  As
339  * a result event groups cannot be accessed directly from an interrupt service
340  * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the
341  * timer task to have the clear operation performed in the context of the timer
342  * task.
343  *
344  * @param xEventGroup The event group in which the bits are to be cleared.
345  *
346  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
347  * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3
348  * and bit 0 set uxBitsToClear to 0x09.
349  *
350  * @return If the request to execute the function was posted successfully then
351  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
352  * if the timer service queue was full.
353  *
354  * Example usage:
355  * @code{c}
356  *    #define BIT_0	( 1 << 0 )
357  *    #define BIT_4	( 1 << 4 )
358  *
359  *    // An event group which it is assumed has already been created by a call to
360  *    // xEventGroupCreate().
361  *    EventGroupHandle_t xEventGroup;
362  *
363  *    void anInterruptHandler( void )
364  *    {
365  * 		// Clear bit 0 and bit 4 in xEventGroup.
366  * 		xResult = xEventGroupClearBitsFromISR(
367  * 							xEventGroup,	 // The event group being updated.
368  * 							BIT_0 | BIT_4 ); // The bits being set.
369  *
370  * 		if( xResult == pdPASS )
371  * 		{
372  * 			// The message was posted successfully.
373  * 		}
374  *   }
375  * @endcode
376  * \ingroup EventGroup
377  */
378 #if( configUSE_TRACE_FACILITY == 1 )
379 	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
380 #else
381 	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
382 #endif
383 
384 /**
385  *
386  * Set bits within an event group.
387  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()
388  * is a version that can be called from an interrupt.
389  *
390  * Setting bits in an event group will automatically unblock tasks that are
391  * blocked waiting for the bits.
392  *
393  * @param xEventGroup The event group in which the bits are to be set.
394  *
395  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
396  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
397  * and bit 0 set uxBitsToSet to 0x09.
398  *
399  * @return The value of the event group at the time the call to
400  * xEventGroupSetBits() returns.  There are two reasons why the returned value
401  * might have the bits specified by the uxBitsToSet parameter cleared.  First,
402  * if setting a bit results in a task that was waiting for the bit leaving the
403  * blocked state then it is possible the bit will be cleared automatically
404  * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any
405  * unblocked (or otherwise Ready state) task that has a priority above that of
406  * the task that called xEventGroupSetBits() will execute and may change the
407  * event group value before the call to xEventGroupSetBits() returns.
408  *
409  * Example usage:
410  * @code{c}
411  *    #define BIT_0	( 1 << 0 )
412  *    #define BIT_4	( 1 << 4 )
413  *
414  *    void aFunction( EventGroupHandle_t xEventGroup )
415  *    {
416  *    EventBits_t uxBits;
417  *
418  * 		// Set bit 0 and bit 4 in xEventGroup.
419  * 		uxBits = xEventGroupSetBits(
420  * 							xEventGroup,	// The event group being updated.
421  * 							BIT_0 | BIT_4 );// The bits being set.
422  *
423  * 		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
424  * 		{
425  * 			// Both bit 0 and bit 4 remained set when the function returned.
426  * 		}
427  * 		else if( ( uxBits & BIT_0 ) != 0 )
428  * 		{
429  * 			// Bit 0 remained set when the function returned, but bit 4 was
430  * 			// cleared.  It might be that bit 4 was cleared automatically as a
431  * 			// task that was waiting for bit 4 was removed from the Blocked
432  * 			// state.
433  * 		}
434  * 		else if( ( uxBits & BIT_4 ) != 0 )
435  * 		{
436  * 			// Bit 4 remained set when the function returned, but bit 0 was
437  * 			// cleared.  It might be that bit 0 was cleared automatically as a
438  * 			// task that was waiting for bit 0 was removed from the Blocked
439  * 			// state.
440  * 		}
441  * 		else
442  * 		{
443  * 			// Neither bit 0 nor bit 4 remained set.  It might be that a task
444  * 			// was waiting for both of the bits to be set, and the bits were
445  * 			// cleared as the task left the Blocked state.
446  * 		}
447  *    }
448  * @endcode{c}
449  * \ingroup EventGroup
450  */
451 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
452 
453 /**
454  *
455  * A version of xEventGroupSetBits() that can be called from an interrupt.
456  *
457  * Setting bits in an event group is not a deterministic operation because there
458  * are an unknown number of tasks that may be waiting for the bit or bits being
459  * set.  FreeRTOS does not allow nondeterministic operations to be performed in
460  * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR()
461  * sends a message to the timer task to have the set operation performed in the
462  * context of the timer task - where a scheduler lock is used in place of a
463  * critical section.
464  *
465  * @param xEventGroup The event group in which the bits are to be set.
466  *
467  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
468  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
469  * and bit 0 set uxBitsToSet to 0x09.
470  *
471  * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
472  * will result in a message being sent to the timer daemon task.  If the
473  * priority of the timer daemon task is higher than the priority of the
474  * currently running task (the task the interrupt interrupted) then
475  * *pxHigherPriorityTaskWoken will be set to pdTRUE by
476  * xEventGroupSetBitsFromISR(), indicating that a context switch should be
477  * requested before the interrupt exits.  For that reason
478  * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the
479  * example code below.
480  *
481  * @return If the request to execute the function was posted successfully then
482  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
483  * if the timer service queue was full.
484  *
485  * Example usage:
486  * @code{c}
487  *    #define BIT_0	( 1 << 0 )
488  *    #define BIT_4	( 1 << 4 )
489  *
490  *    // An event group which it is assumed has already been created by a call to
491  *    // xEventGroupCreate().
492  *    EventGroupHandle_t xEventGroup;
493  *
494  *    void anInterruptHandler( void )
495  *    {
496  *    BaseType_t xHigherPriorityTaskWoken, xResult;
497  *
498  * 		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
499  * 		xHigherPriorityTaskWoken = pdFALSE;
500  *
501  * 		// Set bit 0 and bit 4 in xEventGroup.
502  * 		xResult = xEventGroupSetBitsFromISR(
503  * 							xEventGroup,	// The event group being updated.
504  * 							BIT_0 | BIT_4   // The bits being set.
505  * 							&xHigherPriorityTaskWoken );
506  *
507  * 		// Was the message posted successfully?
508  * 		if( xResult == pdPASS )
509  * 		{
510  * 			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
511  * 			// switch should be requested.  The macro used is port specific and
512  * 			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
513  * 			// refer to the documentation page for the port being used.
514  * 			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
515  * 		}
516  *   }
517  * @endcode
518  * \ingroup EventGroup
519  */
520 #if( configUSE_TRACE_FACILITY == 1 )
521 	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
522 #else
523 	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
524 #endif
525 
526 /**
527  *
528  * Atomically set bits within an event group, then wait for a combination of
529  * bits to be set within the same event group.  This functionality is typically
530  * used to synchronise multiple tasks, where each task has to wait for the other
531  * tasks to reach a synchronisation point before proceeding.
532  *
533  * This function cannot be used from an interrupt.
534  *
535  * The function will return before its block time expires if the bits specified
536  * by the uxBitsToWait parameter are set, or become set within that time.  In
537  * this case all the bits specified by uxBitsToWait will be automatically
538  * cleared before the function returns.
539  *
540  * @param xEventGroup The event group in which the bits are being tested.  The
541  * event group must have previously been created using a call to
542  * xEventGroupCreate().
543  *
544  * @param uxBitsToSet The bits to set in the event group before determining
545  * if, and possibly waiting for, all the bits specified by the uxBitsToWait
546  * parameter are set.
547  *
548  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
549  * inside the event group.  For example, to wait for bit 0 and bit 2 set
550  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set
551  * uxBitsToWaitFor to 0x07.  Etc.
552  *
553  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
554  * for all of the bits specified by uxBitsToWaitFor to become set.
555  *
556  * @return The value of the event group at the time either the bits being waited
557  * for became set, or the block time expired.  Test the return value to know
558  * which bits were set.  If xEventGroupSync() returned because its timeout
559  * expired then not all the bits being waited for will be set.  If
560  * xEventGroupSync() returned because all the bits it was waiting for were
561  * set then the returned value is the event group value before any bits were
562  * automatically cleared.
563  *
564  * Example usage:
565  * @code{c}
566  *  // Bits used by the three tasks.
567  *  #define TASK_0_BIT		( 1 << 0 )
568  *  #define TASK_1_BIT		( 1 << 1 )
569  *  #define TASK_2_BIT		( 1 << 2 )
570  *
571  *  #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
572  *
573  *  // Use an event group to synchronise three tasks.  It is assumed this event
574  *  // group has already been created elsewhere.
575  *  EventGroupHandle_t xEventBits;
576  *
577  *  void vTask0( void *pvParameters )
578  *  {
579  *  EventBits_t uxReturn;
580  *  TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
581  *
582  * 	 for( ;; )
583  * 	 {
584  * 		// Perform task functionality here.
585  *
586  * 		// Set bit 0 in the event flag to note this task has reached the
587  * 		// sync point.  The other two tasks will set the other two bits defined
588  * 		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
589  * 		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
590  * 		// for this to happen.
591  * 		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
592  *
593  * 		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
594  * 		{
595  * 			// All three tasks reached the synchronisation point before the call
596  * 			// to xEventGroupSync() timed out.
597  * 		}
598  * 	  }
599  *  }
600  *
601  *  void vTask1( void *pvParameters )
602  *  {
603  * 	 for( ;; )
604  * 	 {
605  * 		// Perform task functionality here.
606  *
607  * 		// Set bit 1 in the event flag to note this task has reached the
608  * 		// synchronisation point.  The other two tasks will set the other two
609  * 		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
610  * 		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
611  * 		// indefinitely for this to happen.
612  * 		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
613  *
614  * 		// xEventGroupSync() was called with an indefinite block time, so
615  * 		// this task will only reach here if the syncrhonisation was made by all
616  * 		// three tasks, so there is no need to test the return value.
617  * 	 }
618  *  }
619  *
620  *  void vTask2( void *pvParameters )
621  *  {
622  * 	 for( ;; )
623  * 	 {
624  * 		// Perform task functionality here.
625  *
626  * 		// Set bit 2 in the event flag to note this task has reached the
627  * 		// synchronisation point.  The other two tasks will set the other two
628  * 		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
629  * 		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
630  * 		// indefinitely for this to happen.
631  * 		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
632  *
633  * 		// xEventGroupSync() was called with an indefinite block time, so
634  * 		// this task will only reach here if the syncrhonisation was made by all
635  * 		// three tasks, so there is no need to test the return value.
636  * 		}
637  *  }
638  *
639  * @endcode
640  * \ingroup EventGroup
641  */
642 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
643 
644 
645 /**
646  *
647  * Returns the current value of the bits in an event group.  This function
648  * cannot be used from an interrupt.
649  *
650  * @param xEventGroup The event group being queried.
651  *
652  * @return The event group bits at the time xEventGroupGetBits() was called.
653  *
654  * \ingroup EventGroup
655  */
656 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
657 
658 /**
659  *
660  * A version of xEventGroupGetBits() that can be called from an ISR.
661  *
662  * @param xEventGroup The event group being queried.
663  *
664  * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
665  *
666  * \ingroup EventGroup
667  */
668 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
669 
670 /**
671  * Delete an event group that was previously created by a call to
672  * xEventGroupCreate().  Tasks that are blocked on the event group will be
673  * unblocked and obtain 0 as the event group's value.
674  *
675  * @param xEventGroup The event group being deleted.
676  */
677 void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
678 
679 /** @cond */
680 
681 /* For internal use only. */
682 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
683 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
684 
685 
686 #if (configUSE_TRACE_FACILITY == 1)
687 	UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
688 	void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
689 #endif
690 
691 /** @endcond */
692 
693 #ifdef __cplusplus
694 }
695 #endif
696 
697 #endif /* EVENT_GROUPS_H */
698