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