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