2 * FreeRTOS Kernel V10.0.1
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
28 /* Standard includes. */
\r
31 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
\r
32 all the API functions to use the MPU wrappers. That should only be done when
\r
33 task.h is included from an application file. */
\r
34 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
36 /* FreeRTOS includes. */
\r
37 #include "FreeRTOS.h"
\r
40 #include "event_groups.h"
\r
42 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
\r
43 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
\r
44 header files above, but not in this file, in order to generate the correct
\r
45 privileged Vs unprivileged linkage and placement. */
\r
46 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
\r
48 /* The following bit fields convey control information in a task's event list
\r
49 item value. It is important they don't clash with the
\r
50 taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
\r
51 #if configUSE_16_BIT_TICKS == 1
\r
52 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
\r
53 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
\r
54 #define eventWAIT_FOR_ALL_BITS 0x0400U
\r
55 #define eventEVENT_BITS_CONTROL_BYTES 0xff00U
\r
57 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
\r
58 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
\r
59 #define eventWAIT_FOR_ALL_BITS 0x04000000UL
\r
60 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
\r
63 typedef struct xEventGroupDefinition
\r
65 EventBits_t uxEventBits;
\r
66 List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
\r
68 #if( configUSE_TRACE_FACILITY == 1 )
\r
69 UBaseType_t uxEventGroupNumber;
\r
72 #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
\r
73 uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
\r
77 /*-----------------------------------------------------------*/
\r
80 * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
\r
81 * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
\r
82 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
\r
83 * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
\r
84 * wait condition is met if any of the bits set in uxBitsToWait for are also set
\r
85 * in uxCurrentEventBits.
\r
87 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
\r
89 /*-----------------------------------------------------------*/
\r
91 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
93 EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
\r
95 EventGroup_t *pxEventBits;
\r
97 /* A StaticEventGroup_t object must be provided. */
\r
98 configASSERT( pxEventGroupBuffer );
\r
100 #if( configASSERT_DEFINED == 1 )
\r
102 /* Sanity check that the size of the structure used to declare a
\r
103 variable of type StaticEventGroup_t equals the size of the real
\r
104 event group structure. */
\r
105 volatile size_t xSize = sizeof( StaticEventGroup_t );
\r
106 configASSERT( xSize == sizeof( EventGroup_t ) );
\r
108 #endif /* configASSERT_DEFINED */
\r
110 /* The user has provided a statically allocated event group - use it. */
\r
111 pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
\r
113 if( pxEventBits != NULL )
\r
115 pxEventBits->uxEventBits = 0;
\r
116 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
\r
118 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
120 /* Both static and dynamic allocation can be used, so note that
\r
121 this event group was created statically in case the event group
\r
122 is later deleted. */
\r
123 pxEventBits->ucStaticallyAllocated = pdTRUE;
\r
125 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
127 traceEVENT_GROUP_CREATE( pxEventBits );
\r
131 traceEVENT_GROUP_CREATE_FAILED();
\r
134 return ( EventGroupHandle_t ) pxEventBits;
\r
137 #endif /* configSUPPORT_STATIC_ALLOCATION */
\r
138 /*-----------------------------------------------------------*/
\r
140 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
142 EventGroupHandle_t xEventGroupCreate( void )
\r
144 EventGroup_t *pxEventBits;
\r
146 /* Allocate the event group. */
\r
147 pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
\r
149 if( pxEventBits != NULL )
\r
151 pxEventBits->uxEventBits = 0;
\r
152 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
\r
154 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
156 /* Both static and dynamic allocation can be used, so note this
\r
157 event group was allocated statically in case the event group is
\r
159 pxEventBits->ucStaticallyAllocated = pdFALSE;
\r
161 #endif /* configSUPPORT_STATIC_ALLOCATION */
\r
163 traceEVENT_GROUP_CREATE( pxEventBits );
\r
167 traceEVENT_GROUP_CREATE_FAILED();
\r
170 return ( EventGroupHandle_t ) pxEventBits;
\r
173 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
174 /*-----------------------------------------------------------*/
\r
176 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
\r
178 EventBits_t uxOriginalBitValue, uxReturn;
\r
179 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
180 BaseType_t xAlreadyYielded;
\r
181 BaseType_t xTimeoutOccurred = pdFALSE;
\r
183 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
184 configASSERT( uxBitsToWaitFor != 0 );
\r
185 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
\r
187 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
\r
193 uxOriginalBitValue = pxEventBits->uxEventBits;
\r
195 ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
\r
197 if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
199 /* All the rendezvous bits are now set - no need to block. */
\r
200 uxReturn = ( uxOriginalBitValue | uxBitsToSet );
\r
202 /* Rendezvous always clear the bits. They will have been cleared
\r
203 already unless this is the only task in the rendezvous. */
\r
204 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
210 if( xTicksToWait != ( TickType_t ) 0 )
\r
212 traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
\r
214 /* Store the bits that the calling task is waiting for in the
\r
215 task's event list item so the kernel knows when a match is
\r
216 found. Then enter the blocked state. */
\r
217 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
\r
219 /* This assignment is obsolete as uxReturn will get set after
\r
220 the task unblocks, but some compilers mistakenly generate a
\r
221 warning about uxReturn being returned without being set if the
\r
222 assignment is omitted. */
\r
227 /* The rendezvous bits were not set, but no block time was
\r
228 specified - just return the current event bit value. */
\r
229 uxReturn = pxEventBits->uxEventBits;
\r
230 xTimeoutOccurred = pdTRUE;
\r
234 xAlreadyYielded = xTaskResumeAll();
\r
236 if( xTicksToWait != ( TickType_t ) 0 )
\r
238 if( xAlreadyYielded == pdFALSE )
\r
240 portYIELD_WITHIN_API();
\r
244 mtCOVERAGE_TEST_MARKER();
\r
247 /* The task blocked to wait for its required bits to be set - at this
\r
248 point either the required bits were set or the block time expired. If
\r
249 the required bits were set they will have been stored in the task's
\r
250 event list item, and they should now be retrieved then cleared. */
\r
251 uxReturn = uxTaskResetEventItemValue();
\r
253 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
\r
255 /* The task timed out, just return the current event bit value. */
\r
256 taskENTER_CRITICAL();
\r
258 uxReturn = pxEventBits->uxEventBits;
\r
260 /* Although the task got here because it timed out before the
\r
261 bits it was waiting for were set, it is possible that since it
\r
262 unblocked another task has set the bits. If this is the case
\r
263 then it needs to clear the bits before exiting. */
\r
264 if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
266 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
270 mtCOVERAGE_TEST_MARKER();
\r
273 taskEXIT_CRITICAL();
\r
275 xTimeoutOccurred = pdTRUE;
\r
279 /* The task unblocked because the bits were set. */
\r
282 /* Control bits might be set as the task had blocked should not be
\r
284 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
287 traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
\r
289 /* Prevent compiler warnings when trace macros are not used. */
\r
290 ( void ) xTimeoutOccurred;
\r
294 /*-----------------------------------------------------------*/
\r
296 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
\r
298 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
299 EventBits_t uxReturn, uxControlBits = 0;
\r
300 BaseType_t xWaitConditionMet, xAlreadyYielded;
\r
301 BaseType_t xTimeoutOccurred = pdFALSE;
\r
303 /* Check the user is not attempting to wait on the bits used by the kernel
\r
304 itself, and that at least one bit is being requested. */
\r
305 configASSERT( xEventGroup );
\r
306 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
307 configASSERT( uxBitsToWaitFor != 0 );
\r
308 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
\r
310 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
\r
316 const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
\r
318 /* Check to see if the wait condition is already met or not. */
\r
319 xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
\r
321 if( xWaitConditionMet != pdFALSE )
\r
323 /* The wait condition has already been met so there is no need to
\r
325 uxReturn = uxCurrentEventBits;
\r
326 xTicksToWait = ( TickType_t ) 0;
\r
328 /* Clear the wait bits if requested to do so. */
\r
329 if( xClearOnExit != pdFALSE )
\r
331 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
335 mtCOVERAGE_TEST_MARKER();
\r
338 else if( xTicksToWait == ( TickType_t ) 0 )
\r
340 /* The wait condition has not been met, but no block time was
\r
341 specified, so just return the current value. */
\r
342 uxReturn = uxCurrentEventBits;
\r
343 xTimeoutOccurred = pdTRUE;
\r
347 /* The task is going to block to wait for its required bits to be
\r
348 set. uxControlBits are used to remember the specified behaviour of
\r
349 this call to xEventGroupWaitBits() - for use when the event bits
\r
350 unblock the task. */
\r
351 if( xClearOnExit != pdFALSE )
\r
353 uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
\r
357 mtCOVERAGE_TEST_MARKER();
\r
360 if( xWaitForAllBits != pdFALSE )
\r
362 uxControlBits |= eventWAIT_FOR_ALL_BITS;
\r
366 mtCOVERAGE_TEST_MARKER();
\r
369 /* Store the bits that the calling task is waiting for in the
\r
370 task's event list item so the kernel knows when a match is
\r
371 found. Then enter the blocked state. */
\r
372 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
\r
374 /* This is obsolete as it will get set after the task unblocks, but
\r
375 some compilers mistakenly generate a warning about the variable
\r
376 being returned without being set if it is not done. */
\r
379 traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
\r
382 xAlreadyYielded = xTaskResumeAll();
\r
384 if( xTicksToWait != ( TickType_t ) 0 )
\r
386 if( xAlreadyYielded == pdFALSE )
\r
388 portYIELD_WITHIN_API();
\r
392 mtCOVERAGE_TEST_MARKER();
\r
395 /* The task blocked to wait for its required bits to be set - at this
\r
396 point either the required bits were set or the block time expired. If
\r
397 the required bits were set they will have been stored in the task's
\r
398 event list item, and they should now be retrieved then cleared. */
\r
399 uxReturn = uxTaskResetEventItemValue();
\r
401 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
\r
403 taskENTER_CRITICAL();
\r
405 /* The task timed out, just return the current event bit value. */
\r
406 uxReturn = pxEventBits->uxEventBits;
\r
408 /* It is possible that the event bits were updated between this
\r
409 task leaving the Blocked state and running again. */
\r
410 if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
\r
412 if( xClearOnExit != pdFALSE )
\r
414 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
418 mtCOVERAGE_TEST_MARKER();
\r
423 mtCOVERAGE_TEST_MARKER();
\r
425 xTimeoutOccurred = pdTRUE;
\r
427 taskEXIT_CRITICAL();
\r
431 /* The task unblocked because the bits were set. */
\r
434 /* The task blocked so control bits may have been set. */
\r
435 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
437 traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
\r
439 /* Prevent compiler warnings when trace macros are not used. */
\r
440 ( void ) xTimeoutOccurred;
\r
444 /*-----------------------------------------------------------*/
\r
446 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
\r
448 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
449 EventBits_t uxReturn;
\r
451 /* Check the user is not attempting to clear the bits used by the kernel
\r
453 configASSERT( xEventGroup );
\r
454 configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
456 taskENTER_CRITICAL();
\r
458 traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
\r
460 /* The value returned is the event group value prior to the bits being
\r
462 uxReturn = pxEventBits->uxEventBits;
\r
464 /* Clear the bits. */
\r
465 pxEventBits->uxEventBits &= ~uxBitsToClear;
\r
467 taskEXIT_CRITICAL();
\r
471 /*-----------------------------------------------------------*/
\r
473 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
\r
475 BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
\r
477 BaseType_t xReturn;
\r
479 traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
\r
480 xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
\r
486 /*-----------------------------------------------------------*/
\r
488 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
\r
490 UBaseType_t uxSavedInterruptStatus;
\r
491 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
492 EventBits_t uxReturn;
\r
494 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
\r
496 uxReturn = pxEventBits->uxEventBits;
\r
498 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
502 /*-----------------------------------------------------------*/
\r
504 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
\r
506 ListItem_t *pxListItem, *pxNext;
\r
507 ListItem_t const *pxListEnd;
\r
509 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
\r
510 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
511 BaseType_t xMatchFound = pdFALSE;
\r
513 /* Check the user is not attempting to set the bits used by the kernel
\r
515 configASSERT( xEventGroup );
\r
516 configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
518 pxList = &( pxEventBits->xTasksWaitingForBits );
\r
519 pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
\r
522 traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
\r
524 pxListItem = listGET_HEAD_ENTRY( pxList );
\r
526 /* Set the bits. */
\r
527 pxEventBits->uxEventBits |= uxBitsToSet;
\r
529 /* See if the new bit value should unblock any tasks. */
\r
530 while( pxListItem != pxListEnd )
\r
532 pxNext = listGET_NEXT( pxListItem );
\r
533 uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
\r
534 xMatchFound = pdFALSE;
\r
536 /* Split the bits waited for from the control bits. */
\r
537 uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
\r
538 uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
540 if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
\r
542 /* Just looking for single bit being set. */
\r
543 if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
\r
545 xMatchFound = pdTRUE;
\r
549 mtCOVERAGE_TEST_MARKER();
\r
552 else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
\r
554 /* All bits are set. */
\r
555 xMatchFound = pdTRUE;
\r
559 /* Need all bits to be set, but not all the bits were set. */
\r
562 if( xMatchFound != pdFALSE )
\r
564 /* The bits match. Should the bits be cleared on exit? */
\r
565 if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
\r
567 uxBitsToClear |= uxBitsWaitedFor;
\r
571 mtCOVERAGE_TEST_MARKER();
\r
574 /* Store the actual event flag value in the task's event list
\r
575 item before removing the task from the event list. The
\r
576 eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
\r
577 that is was unblocked due to its required bits matching, rather
\r
578 than because it timed out. */
\r
579 vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
\r
582 /* Move onto the next list item. Note pxListItem->pxNext is not
\r
583 used here as the list item may have been removed from the event list
\r
584 and inserted into the ready/pending reading list. */
\r
585 pxListItem = pxNext;
\r
588 /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
\r
589 bit was set in the control word. */
\r
590 pxEventBits->uxEventBits &= ~uxBitsToClear;
\r
592 ( void ) xTaskResumeAll();
\r
594 return pxEventBits->uxEventBits;
\r
596 /*-----------------------------------------------------------*/
\r
598 void vEventGroupDelete( EventGroupHandle_t xEventGroup )
\r
600 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
601 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
\r
605 traceEVENT_GROUP_DELETE( xEventGroup );
\r
607 while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
\r
609 /* Unblock the task, returning 0 as the event list is being deleted
\r
610 and cannot therefore have any bits set. */
\r
611 configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
\r
612 vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
\r
615 #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
\r
617 /* The event group can only have been allocated dynamically - free
\r
619 vPortFree( pxEventBits );
\r
621 #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
\r
623 /* The event group could have been allocated statically or
\r
624 dynamically, so check before attempting to free the memory. */
\r
625 if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
\r
627 vPortFree( pxEventBits );
\r
631 mtCOVERAGE_TEST_MARKER();
\r
634 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
636 ( void ) xTaskResumeAll();
\r
638 /*-----------------------------------------------------------*/
\r
640 /* For internal use only - execute a 'set bits' command that was pended from
\r
642 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
\r
644 ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
\r
646 /*-----------------------------------------------------------*/
\r
648 /* For internal use only - execute a 'clear bits' command that was pended from
\r
650 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
\r
652 ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
\r
654 /*-----------------------------------------------------------*/
\r
656 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
\r
658 BaseType_t xWaitConditionMet = pdFALSE;
\r
660 if( xWaitForAllBits == pdFALSE )
\r
662 /* Task only has to wait for one bit within uxBitsToWaitFor to be
\r
663 set. Is one already set? */
\r
664 if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
\r
666 xWaitConditionMet = pdTRUE;
\r
670 mtCOVERAGE_TEST_MARKER();
\r
675 /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
\r
676 Are they set already? */
\r
677 if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
679 xWaitConditionMet = pdTRUE;
\r
683 mtCOVERAGE_TEST_MARKER();
\r
687 return xWaitConditionMet;
\r
689 /*-----------------------------------------------------------*/
\r
691 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
\r
693 BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
\r
695 BaseType_t xReturn;
\r
697 traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
\r
698 xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
\r
704 /*-----------------------------------------------------------*/
\r
706 #if (configUSE_TRACE_FACILITY == 1)
\r
708 UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
\r
710 UBaseType_t xReturn;
\r
711 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
713 if( xEventGroup == NULL )
\r
719 xReturn = pxEventBits->uxEventGroupNumber;
\r
725 #endif /* configUSE_TRACE_FACILITY */
\r
726 /*-----------------------------------------------------------*/
\r
728 #if ( configUSE_TRACE_FACILITY == 1 )
\r
730 void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
\r
732 ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
\r
735 #endif /* configUSE_TRACE_FACILITY */
\r
736 /*-----------------------------------------------------------*/
\r