]> begriffs open source - freertos/blob - FreeRTOS/Source/include/event_groups.h
Update definition of StaticTimer_t so its size is correct on MSP403X large memory...
[freertos] / FreeRTOS / Source / include / event_groups.h
1 /*\r
2  * FreeRTOS Kernel V10.0.1\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.\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  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 #ifndef EVENT_GROUPS_H\r
29 #define EVENT_GROUPS_H\r
30 \r
31 #ifndef INC_FREERTOS_H\r
32         #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"\r
33 #endif\r
34 \r
35 /* FreeRTOS includes. */\r
36 #include "timers.h"\r
37 \r
38 #ifdef __cplusplus\r
39 extern "C" {\r
40 #endif\r
41 \r
42 /**\r
43  * An event group is a collection of bits to which an application can assign a\r
44  * meaning.  For example, an application may create an event group to convey\r
45  * the status of various CAN bus related events in which bit 0 might mean "A CAN\r
46  * message has been received and is ready for processing", bit 1 might mean "The\r
47  * application has queued a message that is ready for sending onto the CAN\r
48  * network", and bit 2 might mean "It is time to send a SYNC message onto the\r
49  * CAN network" etc.  A task can then test the bit values to see which events\r
50  * are active, and optionally enter the Blocked state to wait for a specified\r
51  * bit or a group of specified bits to be active.  To continue the CAN bus\r
52  * example, a CAN controlling task can enter the Blocked state (and therefore\r
53  * not consume any processing time) until either bit 0, bit 1 or bit 2 are\r
54  * active, at which time the bit that was actually active would inform the task\r
55  * which action it had to take (process a received message, send a message, or\r
56  * send a SYNC).\r
57  *\r
58  * The event groups implementation contains intelligence to avoid race\r
59  * conditions that would otherwise occur were an application to use a simple\r
60  * variable for the same purpose.  This is particularly important with respect\r
61  * to when a bit within an event group is to be cleared, and when bits have to\r
62  * be set and then tested atomically - as is the case where event groups are\r
63  * used to create a synchronisation point between multiple tasks (a\r
64  * 'rendezvous').\r
65  *\r
66  * \defgroup EventGroup\r
67  */\r
68 \r
69 \r
70 \r
71 /**\r
72  * event_groups.h\r
73  *\r
74  * Type by which event groups are referenced.  For example, a call to\r
75  * xEventGroupCreate() returns an EventGroupHandle_t variable that can then\r
76  * be used as a parameter to other event group functions.\r
77  *\r
78  * \defgroup EventGroupHandle_t EventGroupHandle_t\r
79  * \ingroup EventGroup\r
80  */\r
81 typedef void * 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, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
295 \r
296 /**\r
297  * event_groups.h\r
298  *<pre>\r
299         EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );\r
300  </pre>\r
301  *\r
302  * Clear bits within an event group.  This function cannot be called from an\r
303  * interrupt.\r
304  *\r
305  * @param xEventGroup The event group in which the bits are to be cleared.\r
306  *\r
307  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear\r
308  * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to\r
309  * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.\r
310  *\r
311  * @return The value of the event group before the specified bits were cleared.\r
312  *\r
313  * Example usage:\r
314    <pre>\r
315    #define BIT_0        ( 1 << 0 )\r
316    #define BIT_4        ( 1 << 4 )\r
317 \r
318    void aFunction( EventGroupHandle_t xEventGroup )\r
319    {\r
320    EventBits_t uxBits;\r
321 \r
322                 // Clear bit 0 and bit 4 in xEventGroup.\r
323                 uxBits = xEventGroupClearBits(\r
324                                                                 xEventGroup,    // The event group being updated.\r
325                                                                 BIT_0 | BIT_4 );// The bits being cleared.\r
326 \r
327                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
328                 {\r
329                         // Both bit 0 and bit 4 were set before xEventGroupClearBits() was\r
330                         // called.  Both will now be clear (not set).\r
331                 }\r
332                 else if( ( uxBits & BIT_0 ) != 0 )\r
333                 {\r
334                         // Bit 0 was set before xEventGroupClearBits() was called.  It will\r
335                         // now be clear.\r
336                 }\r
337                 else if( ( uxBits & BIT_4 ) != 0 )\r
338                 {\r
339                         // Bit 4 was set before xEventGroupClearBits() was called.  It will\r
340                         // now be clear.\r
341                 }\r
342                 else\r
343                 {\r
344                         // Neither bit 0 nor bit 4 were set in the first place.\r
345                 }\r
346    }\r
347    </pre>\r
348  * \defgroup xEventGroupClearBits xEventGroupClearBits\r
349  * \ingroup EventGroup\r
350  */\r
351 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;\r
352 \r
353 /**\r
354  * event_groups.h\r
355  *<pre>\r
356         BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );\r
357  </pre>\r
358  *\r
359  * A version of xEventGroupClearBits() that can be called from an interrupt.\r
360  *\r
361  * Setting bits in an event group is not a deterministic operation because there\r
362  * are an unknown number of tasks that may be waiting for the bit or bits being\r
363  * set.  FreeRTOS does not allow nondeterministic operations to be performed\r
364  * while interrupts are disabled, so protects event groups that are accessed\r
365  * from tasks by suspending the scheduler rather than disabling interrupts.  As\r
366  * a result event groups cannot be accessed directly from an interrupt service\r
367  * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the\r
368  * timer task to have the clear operation performed in the context of the timer\r
369  * task.\r
370  *\r
371  * @param xEventGroup The event group in which the bits are to be cleared.\r
372  *\r
373  * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.\r
374  * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3\r
375  * and bit 0 set uxBitsToClear to 0x09.\r
376  *\r
377  * @return If the request to execute the function was posted successfully then\r
378  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned\r
379  * if the timer service queue was full.\r
380  *\r
381  * Example usage:\r
382    <pre>\r
383    #define BIT_0        ( 1 << 0 )\r
384    #define BIT_4        ( 1 << 4 )\r
385 \r
386    // An event group which it is assumed has already been created by a call to\r
387    // xEventGroupCreate().\r
388    EventGroupHandle_t xEventGroup;\r
389 \r
390    void anInterruptHandler( void )\r
391    {\r
392                 // Clear bit 0 and bit 4 in xEventGroup.\r
393                 xResult = xEventGroupClearBitsFromISR(\r
394                                                         xEventGroup,     // The event group being updated.\r
395                                                         BIT_0 | BIT_4 ); // The bits being set.\r
396 \r
397                 if( xResult == pdPASS )\r
398                 {\r
399                         // The message was posted successfully.\r
400                 }\r
401   }\r
402    </pre>\r
403  * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR\r
404  * \ingroup EventGroup\r
405  */\r
406 #if( configUSE_TRACE_FACILITY == 1 )\r
407         BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;\r
408 #else\r
409         #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )\r
410 #endif\r
411 \r
412 /**\r
413  * event_groups.h\r
414  *<pre>\r
415         EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );\r
416  </pre>\r
417  *\r
418  * Set bits within an event group.\r
419  * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()\r
420  * is a version that can be called from an interrupt.\r
421  *\r
422  * Setting bits in an event group will automatically unblock tasks that are\r
423  * blocked waiting for the bits.\r
424  *\r
425  * @param xEventGroup The event group in which the bits are to be set.\r
426  *\r
427  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
428  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3\r
429  * and bit 0 set uxBitsToSet to 0x09.\r
430  *\r
431  * @return The value of the event group at the time the call to\r
432  * xEventGroupSetBits() returns.  There are two reasons why the returned value\r
433  * might have the bits specified by the uxBitsToSet parameter cleared.  First,\r
434  * if setting a bit results in a task that was waiting for the bit leaving the\r
435  * blocked state then it is possible the bit will be cleared automatically\r
436  * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any\r
437  * unblocked (or otherwise Ready state) task that has a priority above that of\r
438  * the task that called xEventGroupSetBits() will execute and may change the\r
439  * event group value before the call to xEventGroupSetBits() returns.\r
440  *\r
441  * Example usage:\r
442    <pre>\r
443    #define BIT_0        ( 1 << 0 )\r
444    #define BIT_4        ( 1 << 4 )\r
445 \r
446    void aFunction( EventGroupHandle_t xEventGroup )\r
447    {\r
448    EventBits_t uxBits;\r
449 \r
450                 // Set bit 0 and bit 4 in xEventGroup.\r
451                 uxBits = xEventGroupSetBits(\r
452                                                         xEventGroup,    // The event group being updated.\r
453                                                         BIT_0 | BIT_4 );// The bits being set.\r
454 \r
455                 if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )\r
456                 {\r
457                         // Both bit 0 and bit 4 remained set when the function returned.\r
458                 }\r
459                 else if( ( uxBits & BIT_0 ) != 0 )\r
460                 {\r
461                         // Bit 0 remained set when the function returned, but bit 4 was\r
462                         // cleared.  It might be that bit 4 was cleared automatically as a\r
463                         // task that was waiting for bit 4 was removed from the Blocked\r
464                         // state.\r
465                 }\r
466                 else if( ( uxBits & BIT_4 ) != 0 )\r
467                 {\r
468                         // Bit 4 remained set when the function returned, but bit 0 was\r
469                         // cleared.  It might be that bit 0 was cleared automatically as a\r
470                         // task that was waiting for bit 0 was removed from the Blocked\r
471                         // state.\r
472                 }\r
473                 else\r
474                 {\r
475                         // Neither bit 0 nor bit 4 remained set.  It might be that a task\r
476                         // was waiting for both of the bits to be set, and the bits were\r
477                         // cleared as the task left the Blocked state.\r
478                 }\r
479    }\r
480    </pre>\r
481  * \defgroup xEventGroupSetBits xEventGroupSetBits\r
482  * \ingroup EventGroup\r
483  */\r
484 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;\r
485 \r
486 /**\r
487  * event_groups.h\r
488  *<pre>\r
489         BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );\r
490  </pre>\r
491  *\r
492  * A version of xEventGroupSetBits() that can be called from an interrupt.\r
493  *\r
494  * Setting bits in an event group is not a deterministic operation because there\r
495  * are an unknown number of tasks that may be waiting for the bit or bits being\r
496  * set.  FreeRTOS does not allow nondeterministic operations to be performed in\r
497  * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR()\r
498  * sends a message to the timer task to have the set operation performed in the\r
499  * context of the timer task - where a scheduler lock is used in place of a\r
500  * critical section.\r
501  *\r
502  * @param xEventGroup The event group in which the bits are to be set.\r
503  *\r
504  * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.\r
505  * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3\r
506  * and bit 0 set uxBitsToSet to 0x09.\r
507  *\r
508  * @param pxHigherPriorityTaskWoken As mentioned above, calling this function\r
509  * will result in a message being sent to the timer daemon task.  If the\r
510  * priority of the timer daemon task is higher than the priority of the\r
511  * currently running task (the task the interrupt interrupted) then\r
512  * *pxHigherPriorityTaskWoken will be set to pdTRUE by\r
513  * xEventGroupSetBitsFromISR(), indicating that a context switch should be\r
514  * requested before the interrupt exits.  For that reason\r
515  * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the\r
516  * example code below.\r
517  *\r
518  * @return If the request to execute the function was posted successfully then\r
519  * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned\r
520  * if the timer service queue was full.\r
521  *\r
522  * Example usage:\r
523    <pre>\r
524    #define BIT_0        ( 1 << 0 )\r
525    #define BIT_4        ( 1 << 4 )\r
526 \r
527    // An event group which it is assumed has already been created by a call to\r
528    // xEventGroupCreate().\r
529    EventGroupHandle_t xEventGroup;\r
530 \r
531    void anInterruptHandler( void )\r
532    {\r
533    BaseType_t xHigherPriorityTaskWoken, xResult;\r
534 \r
535                 // xHigherPriorityTaskWoken must be initialised to pdFALSE.\r
536                 xHigherPriorityTaskWoken = pdFALSE;\r
537 \r
538                 // Set bit 0 and bit 4 in xEventGroup.\r
539                 xResult = xEventGroupSetBitsFromISR(\r
540                                                         xEventGroup,    // The event group being updated.\r
541                                                         BIT_0 | BIT_4   // The bits being set.\r
542                                                         &xHigherPriorityTaskWoken );\r
543 \r
544                 // Was the message posted successfully?\r
545                 if( xResult == pdPASS )\r
546                 {\r
547                         // If xHigherPriorityTaskWoken is now set to pdTRUE then a context\r
548                         // switch should be requested.  The macro used is port specific and\r
549                         // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -\r
550                         // refer to the documentation page for the port being used.\r
551                         portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
552                 }\r
553   }\r
554    </pre>\r
555  * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR\r
556  * \ingroup EventGroup\r
557  */\r
558 #if( configUSE_TRACE_FACILITY == 1 )\r
559         BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;\r
560 #else\r
561         #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )\r
562 #endif\r
563 \r
564 /**\r
565  * event_groups.h\r
566  *<pre>\r
567         EventBits_t xEventGroupSync(    EventGroupHandle_t xEventGroup,\r
568                                                                         const EventBits_t uxBitsToSet,\r
569                                                                         const EventBits_t uxBitsToWaitFor,\r
570                                                                         TickType_t xTicksToWait );\r
571  </pre>\r
572  *\r
573  * Atomically set bits within an event group, then wait for a combination of\r
574  * bits to be set within the same event group.  This functionality is typically\r
575  * used to synchronise multiple tasks, where each task has to wait for the other\r
576  * tasks to reach a synchronisation point before proceeding.\r
577  *\r
578  * This function cannot be used from an interrupt.\r
579  *\r
580  * The function will return before its block time expires if the bits specified\r
581  * by the uxBitsToWait parameter are set, or become set within that time.  In\r
582  * this case all the bits specified by uxBitsToWait will be automatically\r
583  * cleared before the function returns.\r
584  *\r
585  * @param xEventGroup The event group in which the bits are being tested.  The\r
586  * event group must have previously been created using a call to\r
587  * xEventGroupCreate().\r
588  *\r
589  * @param uxBitsToSet The bits to set in the event group before determining\r
590  * if, and possibly waiting for, all the bits specified by the uxBitsToWait\r
591  * parameter are set.\r
592  *\r
593  * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test\r
594  * inside the event group.  For example, to wait for bit 0 and bit 2 set\r
595  * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set\r
596  * uxBitsToWaitFor to 0x07.  Etc.\r
597  *\r
598  * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait\r
599  * for all of the bits specified by uxBitsToWaitFor to become set.\r
600  *\r
601  * @return The value of the event group at the time either the bits being waited\r
602  * for became set, or the block time expired.  Test the return value to know\r
603  * which bits were set.  If xEventGroupSync() returned because its timeout\r
604  * expired then not all the bits being waited for will be set.  If\r
605  * xEventGroupSync() returned because all the bits it was waiting for were\r
606  * set then the returned value is the event group value before any bits were\r
607  * automatically cleared.\r
608  *\r
609  * Example usage:\r
610  <pre>\r
611  // Bits used by the three tasks.\r
612  #define TASK_0_BIT             ( 1 << 0 )\r
613  #define TASK_1_BIT             ( 1 << 1 )\r
614  #define TASK_2_BIT             ( 1 << 2 )\r
615 \r
616  #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )\r
617 \r
618  // Use an event group to synchronise three tasks.  It is assumed this event\r
619  // group has already been created elsewhere.\r
620  EventGroupHandle_t xEventBits;\r
621 \r
622  void vTask0( void *pvParameters )\r
623  {\r
624  EventBits_t uxReturn;\r
625  TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;\r
626 \r
627          for( ;; )\r
628          {\r
629                 // Perform task functionality here.\r
630 \r
631                 // Set bit 0 in the event flag to note this task has reached the\r
632                 // sync point.  The other two tasks will set the other two bits defined\r
633                 // by ALL_SYNC_BITS.  All three tasks have reached the synchronisation\r
634                 // point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms\r
635                 // for this to happen.\r
636                 uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );\r
637 \r
638                 if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )\r
639                 {\r
640                         // All three tasks reached the synchronisation point before the call\r
641                         // to xEventGroupSync() timed out.\r
642                 }\r
643         }\r
644  }\r
645 \r
646  void vTask1( void *pvParameters )\r
647  {\r
648          for( ;; )\r
649          {\r
650                 // Perform task functionality here.\r
651 \r
652                 // Set bit 1 in the event flag to note this task has reached the\r
653                 // synchronisation point.  The other two tasks will set the other two\r
654                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the\r
655                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait\r
656                 // indefinitely for this to happen.\r
657                 xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
658 \r
659                 // xEventGroupSync() was called with an indefinite block time, so\r
660                 // this task will only reach here if the syncrhonisation was made by all\r
661                 // three tasks, so there is no need to test the return value.\r
662          }\r
663  }\r
664 \r
665  void vTask2( void *pvParameters )\r
666  {\r
667          for( ;; )\r
668          {\r
669                 // Perform task functionality here.\r
670 \r
671                 // Set bit 2 in the event flag to note this task has reached the\r
672                 // synchronisation point.  The other two tasks will set the other two\r
673                 // bits defined by ALL_SYNC_BITS.  All three tasks have reached the\r
674                 // synchronisation point when all the ALL_SYNC_BITS are set.  Wait\r
675                 // indefinitely for this to happen.\r
676                 xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );\r
677 \r
678                 // xEventGroupSync() was called with an indefinite block time, so\r
679                 // this task will only reach here if the syncrhonisation was made by all\r
680                 // three tasks, so there is no need to test the return value.\r
681         }\r
682  }\r
683 \r
684  </pre>\r
685  * \defgroup xEventGroupSync xEventGroupSync\r
686  * \ingroup EventGroup\r
687  */\r
688 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;\r
689 \r
690 \r
691 /**\r
692  * event_groups.h\r
693  *<pre>\r
694         EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );\r
695  </pre>\r
696  *\r
697  * Returns the current value of the bits in an event group.  This function\r
698  * cannot be used from an interrupt.\r
699  *\r
700  * @param xEventGroup The event group being queried.\r
701  *\r
702  * @return The event group bits at the time xEventGroupGetBits() was called.\r
703  *\r
704  * \defgroup xEventGroupGetBits xEventGroupGetBits\r
705  * \ingroup EventGroup\r
706  */\r
707 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )\r
708 \r
709 /**\r
710  * event_groups.h\r
711  *<pre>\r
712         EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );\r
713  </pre>\r
714  *\r
715  * A version of xEventGroupGetBits() that can be called from an ISR.\r
716  *\r
717  * @param xEventGroup The event group being queried.\r
718  *\r
719  * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.\r
720  *\r
721  * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR\r
722  * \ingroup EventGroup\r
723  */\r
724 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;\r
725 \r
726 /**\r
727  * event_groups.h\r
728  *<pre>\r
729         void xEventGroupDelete( EventGroupHandle_t xEventGroup );\r
730  </pre>\r
731  *\r
732  * Delete an event group that was previously created by a call to\r
733  * xEventGroupCreate().  Tasks that are blocked on the event group will be\r
734  * unblocked and obtain 0 as the event group's value.\r
735  *\r
736  * @param xEventGroup The event group being deleted.\r
737  */\r
738 void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;\r
739 \r
740 /* For internal use only. */\r
741 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;\r
742 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;\r
743 \r
744 \r
745 #if (configUSE_TRACE_FACILITY == 1)\r
746         UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;\r
747         void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;\r
748 #endif\r
749 \r
750 #ifdef __cplusplus\r
751 }\r
752 #endif\r
753 \r
754 #endif /* EVENT_GROUPS_H */\r
755 \r
756 \r