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