2 * FreeRTOS Kernel V10.0.0
\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. If you wish to use our Amazon
\r
14 * FreeRTOS name, please do so in a fair use way that does not cause confusion.
\r
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
18 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
19 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
23 * http://www.FreeRTOS.org
\r
24 * http://aws.amazon.com/freertos
\r
26 * 1 tab == 4 spaces!
\r
29 /* Standard includes. */
\r
32 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
\r
33 all the API functions to use the MPU wrappers. That should only be done when
\r
34 task.h is included from an application file. */
\r
35 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
\r
37 /* FreeRTOS includes. */
\r
38 #include "FreeRTOS.h"
\r
41 #include "event_groups.h"
\r
43 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
\r
44 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
\r
45 header files above, but not in this file, in order to generate the correct
\r
46 privileged Vs unprivileged linkage and placement. */
\r
47 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
\r
49 /* The following bit fields convey control information in a task's event list
\r
50 item value. It is important they don't clash with the
\r
51 taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
\r
52 #if configUSE_16_BIT_TICKS == 1
\r
53 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
\r
54 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
\r
55 #define eventWAIT_FOR_ALL_BITS 0x0400U
\r
56 #define eventEVENT_BITS_CONTROL_BYTES 0xff00U
\r
58 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
\r
59 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
\r
60 #define eventWAIT_FOR_ALL_BITS 0x04000000UL
\r
61 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
\r
64 typedef struct xEventGroupDefinition
\r
66 EventBits_t uxEventBits;
\r
67 List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
\r
69 #if( configUSE_TRACE_FACILITY == 1 )
\r
70 UBaseType_t uxEventGroupNumber;
\r
73 #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
\r
74 uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
\r
78 /*-----------------------------------------------------------*/
\r
81 * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
\r
82 * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
\r
83 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
\r
84 * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
\r
85 * wait condition is met if any of the bits set in uxBitsToWait for are also set
\r
86 * in uxCurrentEventBits.
\r
88 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
\r
90 /*-----------------------------------------------------------*/
\r
92 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
94 EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
\r
96 EventGroup_t *pxEventBits;
\r
98 /* A StaticEventGroup_t object must be provided. */
\r
99 configASSERT( pxEventGroupBuffer );
\r
101 #if( configASSERT_DEFINED == 1 )
\r
103 /* Sanity check that the size of the structure used to declare a
\r
104 variable of type StaticEventGroup_t equals the size of the real
\r
105 event group structure. */
\r
106 volatile size_t xSize = sizeof( StaticEventGroup_t );
\r
107 configASSERT( xSize == sizeof( EventGroup_t ) );
\r
109 #endif /* configASSERT_DEFINED */
\r
111 /* The user has provided a statically allocated event group - use it. */
\r
112 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
114 if( pxEventBits != NULL )
\r
116 pxEventBits->uxEventBits = 0;
\r
117 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
\r
119 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
121 /* Both static and dynamic allocation can be used, so note that
\r
122 this event group was created statically in case the event group
\r
123 is later deleted. */
\r
124 pxEventBits->ucStaticallyAllocated = pdTRUE;
\r
126 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
128 traceEVENT_GROUP_CREATE( pxEventBits );
\r
132 traceEVENT_GROUP_CREATE_FAILED();
\r
135 return ( EventGroupHandle_t ) pxEventBits;
\r
138 #endif /* configSUPPORT_STATIC_ALLOCATION */
\r
139 /*-----------------------------------------------------------*/
\r
141 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
\r
143 EventGroupHandle_t xEventGroupCreate( void )
\r
145 EventGroup_t *pxEventBits;
\r
147 /* Allocate the event group. */
\r
148 pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
\r
150 if( pxEventBits != NULL )
\r
152 pxEventBits->uxEventBits = 0;
\r
153 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
\r
155 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
157 /* Both static and dynamic allocation can be used, so note this
\r
158 event group was allocated statically in case the event group is
\r
160 pxEventBits->ucStaticallyAllocated = pdFALSE;
\r
162 #endif /* configSUPPORT_STATIC_ALLOCATION */
\r
164 traceEVENT_GROUP_CREATE( pxEventBits );
\r
168 traceEVENT_GROUP_CREATE_FAILED();
\r
171 return ( EventGroupHandle_t ) pxEventBits;
\r
174 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
175 /*-----------------------------------------------------------*/
\r
177 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
\r
179 EventBits_t uxOriginalBitValue, uxReturn;
\r
180 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
181 BaseType_t xAlreadyYielded;
\r
182 BaseType_t xTimeoutOccurred = pdFALSE;
\r
184 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
185 configASSERT( uxBitsToWaitFor != 0 );
\r
186 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
\r
188 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
\r
194 uxOriginalBitValue = pxEventBits->uxEventBits;
\r
196 ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
\r
198 if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
200 /* All the rendezvous bits are now set - no need to block. */
\r
201 uxReturn = ( uxOriginalBitValue | uxBitsToSet );
\r
203 /* Rendezvous always clear the bits. They will have been cleared
\r
204 already unless this is the only task in the rendezvous. */
\r
205 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
211 if( xTicksToWait != ( TickType_t ) 0 )
\r
213 traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
\r
215 /* Store the bits that the calling task is waiting for in the
\r
216 task's event list item so the kernel knows when a match is
\r
217 found. Then enter the blocked state. */
\r
218 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
\r
220 /* This assignment is obsolete as uxReturn will get set after
\r
221 the task unblocks, but some compilers mistakenly generate a
\r
222 warning about uxReturn being returned without being set if the
\r
223 assignment is omitted. */
\r
228 /* The rendezvous bits were not set, but no block time was
\r
229 specified - just return the current event bit value. */
\r
230 uxReturn = pxEventBits->uxEventBits;
\r
231 xTimeoutOccurred = pdTRUE;
\r
235 xAlreadyYielded = xTaskResumeAll();
\r
237 if( xTicksToWait != ( TickType_t ) 0 )
\r
239 if( xAlreadyYielded == pdFALSE )
\r
241 portYIELD_WITHIN_API();
\r
245 mtCOVERAGE_TEST_MARKER();
\r
248 /* The task blocked to wait for its required bits to be set - at this
\r
249 point either the required bits were set or the block time expired. If
\r
250 the required bits were set they will have been stored in the task's
\r
251 event list item, and they should now be retrieved then cleared. */
\r
252 uxReturn = uxTaskResetEventItemValue();
\r
254 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
\r
256 /* The task timed out, just return the current event bit value. */
\r
257 taskENTER_CRITICAL();
\r
259 uxReturn = pxEventBits->uxEventBits;
\r
261 /* Although the task got here because it timed out before the
\r
262 bits it was waiting for were set, it is possible that since it
\r
263 unblocked another task has set the bits. If this is the case
\r
264 then it needs to clear the bits before exiting. */
\r
265 if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
267 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
271 mtCOVERAGE_TEST_MARKER();
\r
274 taskEXIT_CRITICAL();
\r
276 xTimeoutOccurred = pdTRUE;
\r
280 /* The task unblocked because the bits were set. */
\r
283 /* Control bits might be set as the task had blocked should not be
\r
285 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
288 traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
\r
290 /* Prevent compiler warnings when trace macros are not used. */
\r
291 ( void ) xTimeoutOccurred;
\r
295 /*-----------------------------------------------------------*/
\r
297 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
\r
299 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
300 EventBits_t uxReturn, uxControlBits = 0;
\r
301 BaseType_t xWaitConditionMet, xAlreadyYielded;
\r
302 BaseType_t xTimeoutOccurred = pdFALSE;
\r
304 /* Check the user is not attempting to wait on the bits used by the kernel
\r
305 itself, and that at least one bit is being requested. */
\r
306 configASSERT( xEventGroup );
\r
307 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
308 configASSERT( uxBitsToWaitFor != 0 );
\r
309 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
\r
311 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
\r
317 const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
\r
319 /* Check to see if the wait condition is already met or not. */
\r
320 xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
\r
322 if( xWaitConditionMet != pdFALSE )
\r
324 /* The wait condition has already been met so there is no need to
\r
326 uxReturn = uxCurrentEventBits;
\r
327 xTicksToWait = ( TickType_t ) 0;
\r
329 /* Clear the wait bits if requested to do so. */
\r
330 if( xClearOnExit != pdFALSE )
\r
332 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
336 mtCOVERAGE_TEST_MARKER();
\r
339 else if( xTicksToWait == ( TickType_t ) 0 )
\r
341 /* The wait condition has not been met, but no block time was
\r
342 specified, so just return the current value. */
\r
343 uxReturn = uxCurrentEventBits;
\r
344 xTimeoutOccurred = pdTRUE;
\r
348 /* The task is going to block to wait for its required bits to be
\r
349 set. uxControlBits are used to remember the specified behaviour of
\r
350 this call to xEventGroupWaitBits() - for use when the event bits
\r
351 unblock the task. */
\r
352 if( xClearOnExit != pdFALSE )
\r
354 uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
\r
358 mtCOVERAGE_TEST_MARKER();
\r
361 if( xWaitForAllBits != pdFALSE )
\r
363 uxControlBits |= eventWAIT_FOR_ALL_BITS;
\r
367 mtCOVERAGE_TEST_MARKER();
\r
370 /* Store the bits that the calling task is waiting for in the
\r
371 task's event list item so the kernel knows when a match is
\r
372 found. Then enter the blocked state. */
\r
373 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
\r
375 /* This is obsolete as it will get set after the task unblocks, but
\r
376 some compilers mistakenly generate a warning about the variable
\r
377 being returned without being set if it is not done. */
\r
380 traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
\r
383 xAlreadyYielded = xTaskResumeAll();
\r
385 if( xTicksToWait != ( TickType_t ) 0 )
\r
387 if( xAlreadyYielded == pdFALSE )
\r
389 portYIELD_WITHIN_API();
\r
393 mtCOVERAGE_TEST_MARKER();
\r
396 /* The task blocked to wait for its required bits to be set - at this
\r
397 point either the required bits were set or the block time expired. If
\r
398 the required bits were set they will have been stored in the task's
\r
399 event list item, and they should now be retrieved then cleared. */
\r
400 uxReturn = uxTaskResetEventItemValue();
\r
402 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
\r
404 taskENTER_CRITICAL();
\r
406 /* The task timed out, just return the current event bit value. */
\r
407 uxReturn = pxEventBits->uxEventBits;
\r
409 /* It is possible that the event bits were updated between this
\r
410 task leaving the Blocked state and running again. */
\r
411 if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
\r
413 if( xClearOnExit != pdFALSE )
\r
415 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
\r
419 mtCOVERAGE_TEST_MARKER();
\r
424 mtCOVERAGE_TEST_MARKER();
\r
426 xTimeoutOccurred = pdTRUE;
\r
428 taskEXIT_CRITICAL();
\r
432 /* The task unblocked because the bits were set. */
\r
435 /* The task blocked so control bits may have been set. */
\r
436 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
438 traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
\r
440 /* Prevent compiler warnings when trace macros are not used. */
\r
441 ( void ) xTimeoutOccurred;
\r
445 /*-----------------------------------------------------------*/
\r
447 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
\r
449 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
450 EventBits_t uxReturn;
\r
452 /* Check the user is not attempting to clear the bits used by the kernel
\r
454 configASSERT( xEventGroup );
\r
455 configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
457 taskENTER_CRITICAL();
\r
459 traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
\r
461 /* The value returned is the event group value prior to the bits being
\r
463 uxReturn = pxEventBits->uxEventBits;
\r
465 /* Clear the bits. */
\r
466 pxEventBits->uxEventBits &= ~uxBitsToClear;
\r
468 taskEXIT_CRITICAL();
\r
472 /*-----------------------------------------------------------*/
\r
474 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
\r
476 BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
\r
478 BaseType_t xReturn;
\r
480 traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
\r
481 xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
\r
487 /*-----------------------------------------------------------*/
\r
489 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
\r
491 UBaseType_t uxSavedInterruptStatus;
\r
492 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
493 EventBits_t uxReturn;
\r
495 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
\r
497 uxReturn = pxEventBits->uxEventBits;
\r
499 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
\r
503 /*-----------------------------------------------------------*/
\r
505 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
\r
507 ListItem_t *pxListItem, *pxNext;
\r
508 ListItem_t const *pxListEnd;
\r
510 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
\r
511 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
512 BaseType_t xMatchFound = pdFALSE;
\r
514 /* Check the user is not attempting to set the bits used by the kernel
\r
516 configASSERT( xEventGroup );
\r
517 configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
\r
519 pxList = &( pxEventBits->xTasksWaitingForBits );
\r
520 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
523 traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
\r
525 pxListItem = listGET_HEAD_ENTRY( pxList );
\r
527 /* Set the bits. */
\r
528 pxEventBits->uxEventBits |= uxBitsToSet;
\r
530 /* See if the new bit value should unblock any tasks. */
\r
531 while( pxListItem != pxListEnd )
\r
533 pxNext = listGET_NEXT( pxListItem );
\r
534 uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
\r
535 xMatchFound = pdFALSE;
\r
537 /* Split the bits waited for from the control bits. */
\r
538 uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
\r
539 uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
\r
541 if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
\r
543 /* Just looking for single bit being set. */
\r
544 if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
\r
546 xMatchFound = pdTRUE;
\r
550 mtCOVERAGE_TEST_MARKER();
\r
553 else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
\r
555 /* All bits are set. */
\r
556 xMatchFound = pdTRUE;
\r
560 /* Need all bits to be set, but not all the bits were set. */
\r
563 if( xMatchFound != pdFALSE )
\r
565 /* The bits match. Should the bits be cleared on exit? */
\r
566 if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
\r
568 uxBitsToClear |= uxBitsWaitedFor;
\r
572 mtCOVERAGE_TEST_MARKER();
\r
575 /* Store the actual event flag value in the task's event list
\r
576 item before removing the task from the event list. The
\r
577 eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
\r
578 that is was unblocked due to its required bits matching, rather
\r
579 than because it timed out. */
\r
580 vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
\r
583 /* Move onto the next list item. Note pxListItem->pxNext is not
\r
584 used here as the list item may have been removed from the event list
\r
585 and inserted into the ready/pending reading list. */
\r
586 pxListItem = pxNext;
\r
589 /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
\r
590 bit was set in the control word. */
\r
591 pxEventBits->uxEventBits &= ~uxBitsToClear;
\r
593 ( void ) xTaskResumeAll();
\r
595 return pxEventBits->uxEventBits;
\r
597 /*-----------------------------------------------------------*/
\r
599 void vEventGroupDelete( EventGroupHandle_t xEventGroup )
\r
601 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
602 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
\r
606 traceEVENT_GROUP_DELETE( xEventGroup );
\r
608 while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
\r
610 /* Unblock the task, returning 0 as the event list is being deleted
\r
611 and cannot therefore have any bits set. */
\r
612 configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
\r
613 vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
\r
616 #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
\r
618 /* The event group can only have been allocated dynamically - free
\r
620 vPortFree( pxEventBits );
\r
622 #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
\r
624 /* The event group could have been allocated statically or
\r
625 dynamically, so check before attempting to free the memory. */
\r
626 if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
\r
628 vPortFree( pxEventBits );
\r
632 mtCOVERAGE_TEST_MARKER();
\r
635 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
\r
637 ( void ) xTaskResumeAll();
\r
639 /*-----------------------------------------------------------*/
\r
641 /* For internal use only - execute a 'set bits' command that was pended from
\r
643 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
\r
645 ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
\r
647 /*-----------------------------------------------------------*/
\r
649 /* For internal use only - execute a 'clear bits' command that was pended from
\r
651 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
\r
653 ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
\r
655 /*-----------------------------------------------------------*/
\r
657 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
\r
659 BaseType_t xWaitConditionMet = pdFALSE;
\r
661 if( xWaitForAllBits == pdFALSE )
\r
663 /* Task only has to wait for one bit within uxBitsToWaitFor to be
\r
664 set. Is one already set? */
\r
665 if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
\r
667 xWaitConditionMet = pdTRUE;
\r
671 mtCOVERAGE_TEST_MARKER();
\r
676 /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
\r
677 Are they set already? */
\r
678 if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
\r
680 xWaitConditionMet = pdTRUE;
\r
684 mtCOVERAGE_TEST_MARKER();
\r
688 return xWaitConditionMet;
\r
690 /*-----------------------------------------------------------*/
\r
692 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
\r
694 BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
\r
696 BaseType_t xReturn;
\r
698 traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
\r
699 xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
\r
705 /*-----------------------------------------------------------*/
\r
707 #if (configUSE_TRACE_FACILITY == 1)
\r
709 UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
\r
711 UBaseType_t xReturn;
\r
712 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
\r
714 if( xEventGroup == NULL )
\r
720 xReturn = pxEventBits->uxEventGroupNumber;
\r
726 #endif /* configUSE_TRACE_FACILITY */
\r
727 /*-----------------------------------------------------------*/
\r
729 #if ( configUSE_TRACE_FACILITY == 1 )
\r
731 void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
\r
733 ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
\r
736 #endif /* configUSE_TRACE_FACILITY */
\r
737 /*-----------------------------------------------------------*/
\r