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