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