1 /* 2 * FreeRTOS Kernel V11.1.0 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 ( configUSE_TRACE_FACILITY == 1 ) 456 BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, 457 const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; 458 #else 459 #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \ 460 xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL ) 461 #endif 462 463 /** 464 * event_groups.h 465 * @code{c} 466 * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); 467 * @endcode 468 * 469 * Set bits within an event group. 470 * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() 471 * is a version that can be called from an interrupt. 472 * 473 * Setting bits in an event group will automatically unblock tasks that are 474 * blocked waiting for the bits. 475 * 476 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSetBits() 477 * to be available. 478 * 479 * @param xEventGroup The event group in which the bits are to be set. 480 * 481 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. 482 * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 483 * and bit 0 set uxBitsToSet to 0x09. 484 * 485 * @return The value of the event group at the time the call to 486 * xEventGroupSetBits() returns. There are two reasons why the returned value 487 * might have the bits specified by the uxBitsToSet parameter cleared. First, 488 * if setting a bit results in a task that was waiting for the bit leaving the 489 * blocked state then it is possible the bit will be cleared automatically 490 * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any 491 * unblocked (or otherwise Ready state) task that has a priority above that of 492 * the task that called xEventGroupSetBits() will execute and may change the 493 * event group value before the call to xEventGroupSetBits() returns. 494 * 495 * Example usage: 496 * @code{c} 497 * #define BIT_0 ( 1 << 0 ) 498 * #define BIT_4 ( 1 << 4 ) 499 * 500 * void aFunction( EventGroupHandle_t xEventGroup ) 501 * { 502 * EventBits_t uxBits; 503 * 504 * // Set bit 0 and bit 4 in xEventGroup. 505 * uxBits = xEventGroupSetBits( 506 * xEventGroup, // The event group being updated. 507 * BIT_0 | BIT_4 );// The bits being set. 508 * 509 * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) ) 510 * { 511 * // Both bit 0 and bit 4 remained set when the function returned. 512 * } 513 * else if( ( uxBits & BIT_0 ) != 0 ) 514 * { 515 * // Bit 0 remained set when the function returned, but bit 4 was 516 * // cleared. It might be that bit 4 was cleared automatically as a 517 * // task that was waiting for bit 4 was removed from the Blocked 518 * // state. 519 * } 520 * else if( ( uxBits & BIT_4 ) != 0 ) 521 * { 522 * // Bit 4 remained set when the function returned, but bit 0 was 523 * // cleared. It might be that bit 0 was cleared automatically as a 524 * // task that was waiting for bit 0 was removed from the Blocked 525 * // state. 526 * } 527 * else 528 * { 529 * // Neither bit 0 nor bit 4 remained set. It might be that a task 530 * // was waiting for both of the bits to be set, and the bits were 531 * // cleared as the task left the Blocked state. 532 * } 533 * } 534 * @endcode 535 * \defgroup xEventGroupSetBits xEventGroupSetBits 536 * \ingroup EventGroup 537 */ 538 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, 539 const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; 540 541 /** 542 * event_groups.h 543 * @code{c} 544 * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); 545 * @endcode 546 * 547 * A version of xEventGroupSetBits() that can be called from an interrupt. 548 * 549 * Setting bits in an event group is not a deterministic operation because there 550 * are an unknown number of tasks that may be waiting for the bit or bits being 551 * set. FreeRTOS does not allow nondeterministic operations to be performed in 552 * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() 553 * sends a message to the timer task to have the set operation performed in the 554 * context of the timer task - where a scheduler lock is used in place of a 555 * critical section. 556 * 557 * @param xEventGroup The event group in which the bits are to be set. 558 * 559 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. 560 * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 561 * and bit 0 set uxBitsToSet to 0x09. 562 * 563 * @param pxHigherPriorityTaskWoken As mentioned above, calling this function 564 * will result in a message being sent to the timer daemon task. If the 565 * priority of the timer daemon task is higher than the priority of the 566 * currently running task (the task the interrupt interrupted) then 567 * *pxHigherPriorityTaskWoken will be set to pdTRUE by 568 * xEventGroupSetBitsFromISR(), indicating that a context switch should be 569 * requested before the interrupt exits. For that reason 570 * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the 571 * example code below. 572 * 573 * @return If the request to execute the function was posted successfully then 574 * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned 575 * if the timer service queue was full. 576 * 577 * Example usage: 578 * @code{c} 579 * #define BIT_0 ( 1 << 0 ) 580 * #define BIT_4 ( 1 << 4 ) 581 * 582 * // An event group which it is assumed has already been created by a call to 583 * // xEventGroupCreate(). 584 * EventGroupHandle_t xEventGroup; 585 * 586 * void anInterruptHandler( void ) 587 * { 588 * BaseType_t xHigherPriorityTaskWoken, xResult; 589 * 590 * // xHigherPriorityTaskWoken must be initialised to pdFALSE. 591 * xHigherPriorityTaskWoken = pdFALSE; 592 * 593 * // Set bit 0 and bit 4 in xEventGroup. 594 * xResult = xEventGroupSetBitsFromISR( 595 * xEventGroup, // The event group being updated. 596 * BIT_0 | BIT_4 // The bits being set. 597 * &xHigherPriorityTaskWoken ); 598 * 599 * // Was the message posted successfully? 600 * if( xResult == pdPASS ) 601 * { 602 * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context 603 * // switch should be requested. The macro used is port specific and 604 * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - 605 * // refer to the documentation page for the port being used. 606 * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); 607 * } 608 * } 609 * @endcode 610 * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR 611 * \ingroup EventGroup 612 */ 613 #if ( configUSE_TRACE_FACILITY == 1 ) 614 BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, 615 const EventBits_t uxBitsToSet, 616 BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; 617 #else 618 #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \ 619 xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) ) 620 #endif 621 622 /** 623 * event_groups.h 624 * @code{c} 625 * EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, 626 * const EventBits_t uxBitsToSet, 627 * const EventBits_t uxBitsToWaitFor, 628 * TickType_t xTicksToWait ); 629 * @endcode 630 * 631 * Atomically set bits within an event group, then wait for a combination of 632 * bits to be set within the same event group. This functionality is typically 633 * used to synchronise multiple tasks, where each task has to wait for the other 634 * tasks to reach a synchronisation point before proceeding. 635 * 636 * This function cannot be used from an interrupt. 637 * 638 * The function will return before its block time expires if the bits specified 639 * by the uxBitsToWait parameter are set, or become set within that time. In 640 * this case all the bits specified by uxBitsToWait will be automatically 641 * cleared before the function returns. 642 * 643 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSync() 644 * to be available. 645 * 646 * @param xEventGroup The event group in which the bits are being tested. The 647 * event group must have previously been created using a call to 648 * xEventGroupCreate(). 649 * 650 * @param uxBitsToSet The bits to set in the event group before determining 651 * if, and possibly waiting for, all the bits specified by the uxBitsToWait 652 * parameter are set. 653 * 654 * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test 655 * inside the event group. For example, to wait for bit 0 and bit 2 set 656 * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set 657 * uxBitsToWaitFor to 0x07. Etc. 658 * 659 * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait 660 * for all of the bits specified by uxBitsToWaitFor to become set. 661 * 662 * @return The value of the event group at the time either the bits being waited 663 * for became set, or the block time expired. Test the return value to know 664 * which bits were set. If xEventGroupSync() returned because its timeout 665 * expired then not all the bits being waited for will be set. If 666 * xEventGroupSync() returned because all the bits it was waiting for were 667 * set then the returned value is the event group value before any bits were 668 * automatically cleared. 669 * 670 * Example usage: 671 * @code{c} 672 * // Bits used by the three tasks. 673 * #define TASK_0_BIT ( 1 << 0 ) 674 * #define TASK_1_BIT ( 1 << 1 ) 675 * #define TASK_2_BIT ( 1 << 2 ) 676 * 677 * #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT ) 678 * 679 * // Use an event group to synchronise three tasks. It is assumed this event 680 * // group has already been created elsewhere. 681 * EventGroupHandle_t xEventBits; 682 * 683 * void vTask0( void *pvParameters ) 684 * { 685 * EventBits_t uxReturn; 686 * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; 687 * 688 * for( ;; ) 689 * { 690 * // Perform task functionality here. 691 * 692 * // Set bit 0 in the event flag to note this task has reached the 693 * // sync point. The other two tasks will set the other two bits defined 694 * // by ALL_SYNC_BITS. All three tasks have reached the synchronisation 695 * // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms 696 * // for this to happen. 697 * uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait ); 698 * 699 * if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS ) 700 * { 701 * // All three tasks reached the synchronisation point before the call 702 * // to xEventGroupSync() timed out. 703 * } 704 * } 705 * } 706 * 707 * void vTask1( void *pvParameters ) 708 * { 709 * for( ;; ) 710 * { 711 * // Perform task functionality here. 712 * 713 * // Set bit 1 in the event flag to note this task has reached the 714 * // synchronisation point. The other two tasks will set the other two 715 * // bits defined by ALL_SYNC_BITS. All three tasks have reached the 716 * // synchronisation point when all the ALL_SYNC_BITS are set. Wait 717 * // indefinitely for this to happen. 718 * xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); 719 * 720 * // xEventGroupSync() was called with an indefinite block time, so 721 * // this task will only reach here if the synchronisation was made by all 722 * // three tasks, so there is no need to test the return value. 723 * } 724 * } 725 * 726 * void vTask2( void *pvParameters ) 727 * { 728 * for( ;; ) 729 * { 730 * // Perform task functionality here. 731 * 732 * // Set bit 2 in the event flag to note this task has reached the 733 * // synchronisation point. The other two tasks will set the other two 734 * // bits defined by ALL_SYNC_BITS. All three tasks have reached the 735 * // synchronisation point when all the ALL_SYNC_BITS are set. Wait 736 * // indefinitely for this to happen. 737 * xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY ); 738 * 739 * // xEventGroupSync() was called with an indefinite block time, so 740 * // this task will only reach here if the synchronisation was made by all 741 * // three tasks, so there is no need to test the return value. 742 * } 743 * } 744 * 745 * @endcode 746 * \defgroup xEventGroupSync xEventGroupSync 747 * \ingroup EventGroup 748 */ 749 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, 750 const EventBits_t uxBitsToSet, 751 const EventBits_t uxBitsToWaitFor, 752 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; 753 754 755 /** 756 * event_groups.h 757 * @code{c} 758 * EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup ); 759 * @endcode 760 * 761 * Returns the current value of the bits in an event group. This function 762 * cannot be used from an interrupt. 763 * 764 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBits() 765 * to be available. 766 * 767 * @param xEventGroup The event group being queried. 768 * 769 * @return The event group bits at the time xEventGroupGetBits() was called. 770 * 771 * \defgroup xEventGroupGetBits xEventGroupGetBits 772 * \ingroup EventGroup 773 */ 774 #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( ( xEventGroup ), 0 ) 775 776 /** 777 * event_groups.h 778 * @code{c} 779 * EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); 780 * @endcode 781 * 782 * A version of xEventGroupGetBits() that can be called from an ISR. 783 * 784 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBitsFromISR() 785 * to be available. 786 * 787 * @param xEventGroup The event group being queried. 788 * 789 * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. 790 * 791 * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR 792 * \ingroup EventGroup 793 */ 794 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; 795 796 /** 797 * event_groups.h 798 * @code{c} 799 * void xEventGroupDelete( EventGroupHandle_t xEventGroup ); 800 * @endcode 801 * 802 * Delete an event group that was previously created by a call to 803 * xEventGroupCreate(). Tasks that are blocked on the event group will be 804 * unblocked and obtain 0 as the event group's value. 805 * 806 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for vEventGroupDelete() 807 * to be available. 808 * 809 * @param xEventGroup The event group being deleted. 810 */ 811 void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; 812 813 /** 814 * event_groups.h 815 * @code{c} 816 * BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, 817 * StaticEventGroup_t ** ppxEventGroupBuffer ); 818 * @endcode 819 * 820 * Retrieve a pointer to a statically created event groups's data structure 821 * buffer. It is the same buffer that is supplied at the time of creation. 822 * 823 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetStaticBuffer() 824 * to be available. 825 * 826 * @param xEventGroup The event group for which to retrieve the buffer. 827 * 828 * @param ppxEventGroupBuffer Used to return a pointer to the event groups's 829 * data structure buffer. 830 * 831 * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. 832 */ 833 #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) 834 BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, 835 StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; 836 #endif /* configSUPPORT_STATIC_ALLOCATION */ 837 838 /* For internal use only. */ 839 void vEventGroupSetBitsCallback( void * pvEventGroup, 840 uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; 841 void vEventGroupClearBitsCallback( void * pvEventGroup, 842 uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; 843 844 845 #if ( configUSE_TRACE_FACILITY == 1 ) 846 UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION; 847 void vEventGroupSetNumber( void * xEventGroup, 848 UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; 849 #endif 850 851 /* *INDENT-OFF* */ 852 #ifdef __cplusplus 853 } 854 #endif 855 /* *INDENT-ON* */ 856 857 #endif /* EVENT_GROUPS_H */ 858