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