]> begriffs open source - cmsis-freertos/blob - Source/include/event_groups.h
osEventFlagsSet in correctly handles status return from xEventGroupSetBitsFromISR
[cmsis-freertos] / Source / include / event_groups.h
1 /*
2  * FreeRTOS Kernel V10.0.1
3  * Copyright (C) 2017 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  * \defgroup EventGroup
67  */
68
69
70
71 /**
72  * event_groups.h
73  *
74  * Type by which event groups are referenced.  For example, a call to
75  * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
76  * be used as a parameter to other event group functions.
77  *
78  * \defgroup EventGroupHandle_t EventGroupHandle_t
79  * \ingroup EventGroup
80  */
81 typedef void * EventGroupHandle_t;
82
83 /*
84  * The type that holds event bits always matches TickType_t - therefore the
85  * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
86  * 32 bits if set to 0.
87  *
88  * \defgroup EventBits_t EventBits_t
89  * \ingroup EventGroup
90  */
91 typedef TickType_t EventBits_t;
92
93 /**
94  * event_groups.h
95  *<pre>
96  EventGroupHandle_t xEventGroupCreate( void );
97  </pre>
98  *
99  * Create a new event group.
100  *
101  * Internally, within the FreeRTOS implementation, event groups use a [small]
102  * block of memory, in which the event group's structure is stored.  If an event
103  * groups is created using xEventGropuCreate() then the required memory is
104  * automatically dynamically allocated inside the xEventGroupCreate() function.
105  * (see http://www.freertos.org/a00111.html).  If an event group is created
106  * using xEventGropuCreateStatic() then the application writer must instead
107  * provide the memory that will get used by the event group.
108  * xEventGroupCreateStatic() therefore allows an event group to be created
109  * without using any dynamic memory allocation.
110  *
111  * Although event groups are not related to ticks, for internal implementation
112  * reasons the number of bits available for use in an event group is dependent
113  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If
114  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
115  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has
116  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store
117  * event bits within an event group.
118  *
119  * @return If the event group was created then a handle to the event group is
120  * returned.  If there was insufficient FreeRTOS heap available to create the
121  * event group then NULL is returned.  See http://www.freertos.org/a00111.html
122  *
123  * Example usage:
124    <pre>
125         // Declare a variable to hold the created event group.
126         EventGroupHandle_t xCreatedEventGroup;
127
128         // Attempt to create the event group.
129         xCreatedEventGroup = xEventGroupCreate();
130
131         // Was the event group created successfully?
132         if( xCreatedEventGroup == NULL )
133         {
134                 // The event group was not created because there was insufficient
135                 // FreeRTOS heap available.
136         }
137         else
138         {
139                 // The event group was created.
140         }
141    </pre>
142  * \defgroup xEventGroupCreate xEventGroupCreate
143  * \ingroup EventGroup
144  */
145 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
146         EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
147 #endif
148
149 /**
150  * event_groups.h
151  *<pre>
152  EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
153  </pre>
154  *
155  * Create a new event group.
156  *
157  * Internally, within the FreeRTOS implementation, event groups use a [small]
158  * block of memory, in which the event group's structure is stored.  If an event
159  * groups is created using xEventGropuCreate() then the required memory is
160  * automatically dynamically allocated inside the xEventGroupCreate() function.
161  * (see http://www.freertos.org/a00111.html).  If an event group is created
162  * using xEventGropuCreateStatic() then the application writer must instead
163  * provide the memory that will get used by the event group.
164  * xEventGroupCreateStatic() therefore allows an event group to be created
165  * without using any dynamic memory allocation.
166  *
167  * Although event groups are not related to ticks, for internal implementation
168  * reasons the number of bits available for use in an event group is dependent
169  * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h.  If
170  * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
171  * 0 to bit 7).  If configUSE_16_BIT_TICKS is set to 0 then each event group has
172  * 24 usable bits (bit 0 to bit 23).  The EventBits_t type is used to store
173  * event bits within an event group.
174  *
175  * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
176  * StaticEventGroup_t, which will be then be used to hold the event group's data
177  * structures, removing the need for the memory to be allocated dynamically.
178  *
179  * @return If the event group was created then a handle to the event group is
180  * returned.  If pxEventGroupBuffer was NULL then NULL is returned.
181  *
182  * Example usage:
183    <pre>
184         // StaticEventGroup_t is a publicly accessible structure that has the same
185         // size and alignment requirements as the real event group structure.  It is
186         // provided as a mechanism for applications to know the size of the event
187         // group (which is dependent on the architecture and configuration file
188         // settings) without breaking the strict data hiding policy by exposing the
189         // real event group internals.  This StaticEventGroup_t variable is passed
190         // into the xSemaphoreCreateEventGroupStatic() function and is used to store
191         // the event group's data structures
192         StaticEventGroup_t xEventGroupBuffer;
193
194         // Create the event group without dynamically allocating any memory.
195         xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
196    </pre>
197  */
198 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
199         EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
200 #endif
201
202 /**
203  * event_groups.h
204  *<pre>
205         EventBits_t xEventGroupWaitBits(        EventGroupHandle_t xEventGroup,
206                                                                                 const EventBits_t uxBitsToWaitFor,
207                                                                                 const BaseType_t xClearOnExit,
208                                                                                 const BaseType_t xWaitForAllBits,
209                                                                                 const TickType_t xTicksToWait );
210  </pre>
211  *
212  * [Potentially] block to wait for one or more bits to be set within a
213  * previously created event group.
214  *
215  * This function cannot be called from an interrupt.
216  *
217  * @param xEventGroup The event group in which the bits are being tested.  The
218  * event group must have previously been created using a call to
219  * xEventGroupCreate().
220  *
221  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
222  * inside the event group.  For example, to wait for bit 0 and/or bit 2 set
223  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set
224  * uxBitsToWaitFor to 0x07.  Etc.
225  *
226  * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
227  * uxBitsToWaitFor that are set within the event group will be cleared before
228  * xEventGroupWaitBits() returns if the wait condition was met (if the function
229  * returns for a reason other than a timeout).  If xClearOnExit is set to
230  * pdFALSE then the bits set in the event group are not altered when the call to
231  * xEventGroupWaitBits() returns.
232  *
233  * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
234  * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
235  * are set or the specified block time expires.  If xWaitForAllBits is set to
236  * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
237  * in uxBitsToWaitFor is set or the specified block time expires.  The block
238  * time is specified by the xTicksToWait parameter.
239  *
240  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
241  * for one/all (depending on the xWaitForAllBits value) of the bits specified by
242  * uxBitsToWaitFor to become set.
243  *
244  * @return The value of the event group at the time either the bits being waited
245  * for became set, or the block time expired.  Test the return value to know
246  * which bits were set.  If xEventGroupWaitBits() returned because its timeout
247  * expired then not all the bits being waited for will be set.  If
248  * xEventGroupWaitBits() returned because the bits it was waiting for were set
249  * then the returned value is the event group value before any bits were
250  * automatically cleared in the case that xClearOnExit parameter was set to
251  * pdTRUE.
252  *
253  * Example usage:
254    <pre>
255    #define BIT_0        ( 1 << 0 )
256    #define BIT_4        ( 1 << 4 )
257
258    void aFunction( EventGroupHandle_t xEventGroup )
259    {
260    EventBits_t uxBits;
261    const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
262
263                 // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
264                 // the event group.  Clear the bits before exiting.
265                 uxBits = xEventGroupWaitBits(
266                                         xEventGroup,    // The event group being tested.
267                                         BIT_0 | BIT_4,  // The bits within the event group to wait for.
268                                         pdTRUE,                 // BIT_0 and BIT_4 should be cleared before returning.
269                                         pdFALSE,                // Don't wait for both bits, either bit will do.
270                                         xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
271
272                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
273                 {
274                         // xEventGroupWaitBits() returned because both bits were set.
275                 }
276                 else if( ( uxBits & BIT_0 ) != 0 )
277                 {
278                         // xEventGroupWaitBits() returned because just BIT_0 was set.
279                 }
280                 else if( ( uxBits & BIT_4 ) != 0 )
281                 {
282                         // xEventGroupWaitBits() returned because just BIT_4 was set.
283                 }
284                 else
285                 {
286                         // xEventGroupWaitBits() returned because xTicksToWait ticks passed
287                         // without either BIT_0 or BIT_4 becoming set.
288                 }
289    }
290    </pre>
291  * \defgroup xEventGroupWaitBits xEventGroupWaitBits
292  * \ingroup EventGroup
293  */
294 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
295
296 /**
297  * event_groups.h
298  *<pre>
299         EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
300  </pre>
301  *
302  * Clear bits within an event group.  This function cannot be called from an
303  * interrupt.
304  *
305  * @param xEventGroup The event group in which the bits are to be cleared.
306  *
307  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
308  * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to
309  * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
310  *
311  * @return The value of the event group before the specified bits were cleared.
312  *
313  * Example usage:
314    <pre>
315    #define BIT_0        ( 1 << 0 )
316    #define BIT_4        ( 1 << 4 )
317
318    void aFunction( EventGroupHandle_t xEventGroup )
319    {
320    EventBits_t uxBits;
321
322                 // Clear bit 0 and bit 4 in xEventGroup.
323                 uxBits = xEventGroupClearBits(
324                                                                 xEventGroup,    // The event group being updated.
325                                                                 BIT_0 | BIT_4 );// The bits being cleared.
326
327                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
328                 {
329                         // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
330                         // called.  Both will now be clear (not set).
331                 }
332                 else if( ( uxBits & BIT_0 ) != 0 )
333                 {
334                         // Bit 0 was set before xEventGroupClearBits() was called.  It will
335                         // now be clear.
336                 }
337                 else if( ( uxBits & BIT_4 ) != 0 )
338                 {
339                         // Bit 4 was set before xEventGroupClearBits() was called.  It will
340                         // now be clear.
341                 }
342                 else
343                 {
344                         // Neither bit 0 nor bit 4 were set in the first place.
345                 }
346    }
347    </pre>
348  * \defgroup xEventGroupClearBits xEventGroupClearBits
349  * \ingroup EventGroup
350  */
351 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
352
353 /**
354  * event_groups.h
355  *<pre>
356         BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
357  </pre>
358  *
359  * A version of xEventGroupClearBits() that can be called from an interrupt.
360  *
361  * Setting bits in an event group is not a deterministic operation because there
362  * are an unknown number of tasks that may be waiting for the bit or bits being
363  * set.  FreeRTOS does not allow nondeterministic operations to be performed
364  * while interrupts are disabled, so protects event groups that are accessed
365  * from tasks by suspending the scheduler rather than disabling interrupts.  As
366  * a result event groups cannot be accessed directly from an interrupt service
367  * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the
368  * timer task to have the clear operation performed in the context of the timer
369  * task.
370  *
371  * @param xEventGroup The event group in which the bits are to be cleared.
372  *
373  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
374  * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3
375  * and bit 0 set uxBitsToClear to 0x09.
376  *
377  * @return If the request to execute the function was posted successfully then
378  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
379  * if the timer service queue was full.
380  *
381  * Example usage:
382    <pre>
383    #define BIT_0        ( 1 << 0 )
384    #define BIT_4        ( 1 << 4 )
385
386    // An event group which it is assumed has already been created by a call to
387    // xEventGroupCreate().
388    EventGroupHandle_t xEventGroup;
389
390    void anInterruptHandler( void )
391    {
392                 // Clear bit 0 and bit 4 in xEventGroup.
393                 xResult = xEventGroupClearBitsFromISR(
394                                                         xEventGroup,     // The event group being updated.
395                                                         BIT_0 | BIT_4 ); // The bits being set.
396
397                 if( xResult == pdPASS )
398                 {
399                         // The message was posted successfully.
400                 }
401   }
402    </pre>
403  * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
404  * \ingroup EventGroup
405  */
406 #if( configUSE_TRACE_FACILITY == 1 )
407         BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
408 #else
409         #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
410 #endif
411
412 /**
413  * event_groups.h
414  *<pre>
415         EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
416  </pre>
417  *
418  * Set bits within an event group.
419  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()
420  * is a version that can be called from an interrupt.
421  *
422  * Setting bits in an event group will automatically unblock tasks that are
423  * blocked waiting for the bits.
424  *
425  * @param xEventGroup The event group in which the bits are to be set.
426  *
427  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
428  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
429  * and bit 0 set uxBitsToSet to 0x09.
430  *
431  * @return The value of the event group at the time the call to
432  * xEventGroupSetBits() returns.  There are two reasons why the returned value
433  * might have the bits specified by the uxBitsToSet parameter cleared.  First,
434  * if setting a bit results in a task that was waiting for the bit leaving the
435  * blocked state then it is possible the bit will be cleared automatically
436  * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any
437  * unblocked (or otherwise Ready state) task that has a priority above that of
438  * the task that called xEventGroupSetBits() will execute and may change the
439  * event group value before the call to xEventGroupSetBits() returns.
440  *
441  * Example usage:
442    <pre>
443    #define BIT_0        ( 1 << 0 )
444    #define BIT_4        ( 1 << 4 )
445
446    void aFunction( EventGroupHandle_t xEventGroup )
447    {
448    EventBits_t uxBits;
449
450                 // Set bit 0 and bit 4 in xEventGroup.
451                 uxBits = xEventGroupSetBits(
452                                                         xEventGroup,    // The event group being updated.
453                                                         BIT_0 | BIT_4 );// The bits being set.
454
455                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
456                 {
457                         // Both bit 0 and bit 4 remained set when the function returned.
458                 }
459                 else if( ( uxBits & BIT_0 ) != 0 )
460                 {
461                         // Bit 0 remained set when the function returned, but bit 4 was
462                         // cleared.  It might be that bit 4 was cleared automatically as a
463                         // task that was waiting for bit 4 was removed from the Blocked
464                         // state.
465                 }
466                 else if( ( uxBits & BIT_4 ) != 0 )
467                 {
468                         // Bit 4 remained set when the function returned, but bit 0 was
469                         // cleared.  It might be that bit 0 was cleared automatically as a
470                         // task that was waiting for bit 0 was removed from the Blocked
471                         // state.
472                 }
473                 else
474                 {
475                         // Neither bit 0 nor bit 4 remained set.  It might be that a task
476                         // was waiting for both of the bits to be set, and the bits were
477                         // cleared as the task left the Blocked state.
478                 }
479    }
480    </pre>
481  * \defgroup xEventGroupSetBits xEventGroupSetBits
482  * \ingroup EventGroup
483  */
484 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
485
486 /**
487  * event_groups.h
488  *<pre>
489         BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
490  </pre>
491  *
492  * A version of xEventGroupSetBits() that can be called from an interrupt.
493  *
494  * Setting bits in an event group is not a deterministic operation because there
495  * are an unknown number of tasks that may be waiting for the bit or bits being
496  * set.  FreeRTOS does not allow nondeterministic operations to be performed in
497  * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR()
498  * sends a message to the timer task to have the set operation performed in the
499  * context of the timer task - where a scheduler lock is used in place of a
500  * critical section.
501  *
502  * @param xEventGroup The event group in which the bits are to be set.
503  *
504  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
505  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
506  * and bit 0 set uxBitsToSet to 0x09.
507  *
508  * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
509  * will result in a message being sent to the timer daemon task.  If the
510  * priority of the timer daemon task is higher than the priority of the
511  * currently running task (the task the interrupt interrupted) then
512  * *pxHigherPriorityTaskWoken will be set to pdTRUE by
513  * xEventGroupSetBitsFromISR(), indicating that a context switch should be
514  * requested before the interrupt exits.  For that reason
515  * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the
516  * example code below.
517  *
518  * @return If the request to execute the function was posted successfully then
519  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
520  * if the timer service queue was full.
521  *
522  * Example usage:
523    <pre>
524    #define BIT_0        ( 1 << 0 )
525    #define BIT_4        ( 1 << 4 )
526
527    // An event group which it is assumed has already been created by a call to
528    // xEventGroupCreate().
529    EventGroupHandle_t xEventGroup;
530
531    void anInterruptHandler( void )
532    {
533    BaseType_t xHigherPriorityTaskWoken, xResult;
534
535                 // xHigherPriorityTaskWoken must be initialised to pdFALSE.
536                 xHigherPriorityTaskWoken = pdFALSE;
537
538                 // Set bit 0 and bit 4 in xEventGroup.
539                 xResult = xEventGroupSetBitsFromISR(
540                                                         xEventGroup,    // The event group being updated.
541                                                         BIT_0 | BIT_4   // The bits being set.
542                                                         &xHigherPriorityTaskWoken );
543
544                 // Was the message posted successfully?
545                 if( xResult == pdPASS )
546                 {
547                         // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
548                         // switch should be requested.  The macro used is port specific and
549                         // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
550                         // refer to the documentation page for the port being used.
551                         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
552                 }
553   }
554    </pre>
555  * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
556  * \ingroup EventGroup
557  */
558 #if( configUSE_TRACE_FACILITY == 1 )
559         BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
560 #else
561         #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
562 #endif
563
564 /**
565  * event_groups.h
566  *<pre>
567         EventBits_t xEventGroupSync(    EventGroupHandle_t xEventGroup,
568                                                                         const EventBits_t uxBitsToSet,
569                                                                         const EventBits_t uxBitsToWaitFor,
570                                                                         TickType_t xTicksToWait );
571  </pre>
572  *
573  * Atomically set bits within an event group, then wait for a combination of
574  * bits to be set within the same event group.  This functionality is typically
575  * used to synchronise multiple tasks, where each task has to wait for the other
576  * tasks to reach a synchronisation point before proceeding.
577  *
578  * This function cannot be used from an interrupt.
579  *
580  * The function will return before its block time expires if the bits specified
581  * by the uxBitsToWait parameter are set, or become set within that time.  In
582  * this case all the bits specified by uxBitsToWait will be automatically
583  * cleared before the function returns.
584  *
585  * @param xEventGroup The event group in which the bits are being tested.  The
586  * event group must have previously been created using a call to
587  * xEventGroupCreate().
588  *
589  * @param uxBitsToSet The bits to set in the event group before determining
590  * if, and possibly waiting for, all the bits specified by the uxBitsToWait
591  * parameter are set.
592  *
593  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
594  * inside the event group.  For example, to wait for bit 0 and bit 2 set
595  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set
596  * uxBitsToWaitFor to 0x07.  Etc.
597  *
598  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
599  * for all of the bits specified by uxBitsToWaitFor to become set.
600  *
601  * @return The value of the event group at the time either the bits being waited
602  * for became set, or the block time expired.  Test the return value to know
603  * which bits were set.  If xEventGroupSync() returned because its timeout
604  * expired then not all the bits being waited for will be set.  If
605  * xEventGroupSync() returned because all the bits it was waiting for were
606  * set then the returned value is the event group value before any bits were
607  * automatically cleared.
608  *
609  * Example usage:
610  <pre>
611  // Bits used by the three tasks.
612  #define TASK_0_BIT             ( 1 << 0 )
613  #define TASK_1_BIT             ( 1 << 1 )
614  #define TASK_2_BIT             ( 1 << 2 )
615
616  #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
617
618  // Use an event group to synchronise three tasks.  It is assumed this event
619  // group has already been created elsewhere.
620  EventGroupHandle_t xEventBits;
621
622  void vTask0( void *pvParameters )
623  {
624  EventBits_t uxReturn;
625  TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
626
627          for( ;; )
628          {
629                 // Perform task functionality here.
630
631                 // Set bit 0 in the event flag to note this task has reached the
632                 // sync point.  The other two tasks will set the other two bits defined
633                 // by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
634                 // point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
635                 // for this to happen.
636                 uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
637
638                 if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
639                 {
640                         // All three tasks reached the synchronisation point before the call
641                         // to xEventGroupSync() timed out.
642                 }
643         }
644  }
645
646  void vTask1( void *pvParameters )
647  {
648          for( ;; )
649          {
650                 // Perform task functionality here.
651
652                 // Set bit 1 in the event flag to note this task has reached the
653                 // synchronisation point.  The other two tasks will set the other two
654                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
655                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
656                 // indefinitely for this to happen.
657                 xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
658
659                 // xEventGroupSync() was called with an indefinite block time, so
660                 // this task will only reach here if the syncrhonisation was made by all
661                 // three tasks, so there is no need to test the return value.
662          }
663  }
664
665  void vTask2( void *pvParameters )
666  {
667          for( ;; )
668          {
669                 // Perform task functionality here.
670
671                 // Set bit 2 in the event flag to note this task has reached the
672                 // synchronisation point.  The other two tasks will set the other two
673                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
674                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
675                 // indefinitely for this to happen.
676                 xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
677
678                 // xEventGroupSync() was called with an indefinite block time, so
679                 // this task will only reach here if the syncrhonisation was made by all
680                 // three tasks, so there is no need to test the return value.
681         }
682  }
683
684  </pre>
685  * \defgroup xEventGroupSync xEventGroupSync
686  * \ingroup EventGroup
687  */
688 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
689
690
691 /**
692  * event_groups.h
693  *<pre>
694         EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
695  </pre>
696  *
697  * Returns the current value of the bits in an event group.  This function
698  * cannot be used from an interrupt.
699  *
700  * @param xEventGroup The event group being queried.
701  *
702  * @return The event group bits at the time xEventGroupGetBits() was called.
703  *
704  * \defgroup xEventGroupGetBits xEventGroupGetBits
705  * \ingroup EventGroup
706  */
707 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
708
709 /**
710  * event_groups.h
711  *<pre>
712         EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
713  </pre>
714  *
715  * A version of xEventGroupGetBits() that can be called from an ISR.
716  *
717  * @param xEventGroup The event group being queried.
718  *
719  * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
720  *
721  * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
722  * \ingroup EventGroup
723  */
724 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
725
726 /**
727  * event_groups.h
728  *<pre>
729         void xEventGroupDelete( EventGroupHandle_t xEventGroup );
730  </pre>
731  *
732  * Delete an event group that was previously created by a call to
733  * xEventGroupCreate().  Tasks that are blocked on the event group will be
734  * unblocked and obtain 0 as the event group's value.
735  *
736  * @param xEventGroup The event group being deleted.
737  */
738 void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
739
740 /* For internal use only. */
741 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
742 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
743
744
745 #if (configUSE_TRACE_FACILITY == 1)
746         UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
747         void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
748 #endif
749
750 #ifdef __cplusplus
751 }
752 #endif
753
754 #endif /* EVENT_GROUPS_H */
755
756