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