Francisco Paez / freertos

Dependents:   frdm_k64f_freertos_lib

Committer:
fep
Date:
Wed May 31 02:27:10 2017 +0000
Revision:
0:62cd296ba2a7
FreeRTOS v9.0.0 for Cortex-M4F (FRDM-K64F and others...)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fep 0:62cd296ba2a7 1 /*
fep 0:62cd296ba2a7 2 FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
fep 0:62cd296ba2a7 3 All rights reserved
fep 0:62cd296ba2a7 4
fep 0:62cd296ba2a7 5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
fep 0:62cd296ba2a7 6
fep 0:62cd296ba2a7 7 This file is part of the FreeRTOS distribution.
fep 0:62cd296ba2a7 8
fep 0:62cd296ba2a7 9 FreeRTOS is free software; you can redistribute it and/or modify it under
fep 0:62cd296ba2a7 10 the terms of the GNU General Public License (version 2) as published by the
fep 0:62cd296ba2a7 11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
fep 0:62cd296ba2a7 12
fep 0:62cd296ba2a7 13 ***************************************************************************
fep 0:62cd296ba2a7 14 >>! NOTE: The modification to the GPL is included to allow you to !<<
fep 0:62cd296ba2a7 15 >>! distribute a combined work that includes FreeRTOS without being !<<
fep 0:62cd296ba2a7 16 >>! obliged to provide the source code for proprietary components !<<
fep 0:62cd296ba2a7 17 >>! outside of the FreeRTOS kernel. !<<
fep 0:62cd296ba2a7 18 ***************************************************************************
fep 0:62cd296ba2a7 19
fep 0:62cd296ba2a7 20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
fep 0:62cd296ba2a7 21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
fep 0:62cd296ba2a7 22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
fep 0:62cd296ba2a7 23 link: http://www.freertos.org/a00114.html
fep 0:62cd296ba2a7 24
fep 0:62cd296ba2a7 25 ***************************************************************************
fep 0:62cd296ba2a7 26 * *
fep 0:62cd296ba2a7 27 * FreeRTOS provides completely free yet professionally developed, *
fep 0:62cd296ba2a7 28 * robust, strictly quality controlled, supported, and cross *
fep 0:62cd296ba2a7 29 * platform software that is more than just the market leader, it *
fep 0:62cd296ba2a7 30 * is the industry's de facto standard. *
fep 0:62cd296ba2a7 31 * *
fep 0:62cd296ba2a7 32 * Help yourself get started quickly while simultaneously helping *
fep 0:62cd296ba2a7 33 * to support the FreeRTOS project by purchasing a FreeRTOS *
fep 0:62cd296ba2a7 34 * tutorial book, reference manual, or both: *
fep 0:62cd296ba2a7 35 * http://www.FreeRTOS.org/Documentation *
fep 0:62cd296ba2a7 36 * *
fep 0:62cd296ba2a7 37 ***************************************************************************
fep 0:62cd296ba2a7 38
fep 0:62cd296ba2a7 39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
fep 0:62cd296ba2a7 40 the FAQ page "My application does not run, what could be wrong?". Have you
fep 0:62cd296ba2a7 41 defined configASSERT()?
fep 0:62cd296ba2a7 42
fep 0:62cd296ba2a7 43 http://www.FreeRTOS.org/support - In return for receiving this top quality
fep 0:62cd296ba2a7 44 embedded software for free we request you assist our global community by
fep 0:62cd296ba2a7 45 participating in the support forum.
fep 0:62cd296ba2a7 46
fep 0:62cd296ba2a7 47 http://www.FreeRTOS.org/training - Investing in training allows your team to
fep 0:62cd296ba2a7 48 be as productive as possible as early as possible. Now you can receive
fep 0:62cd296ba2a7 49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
fep 0:62cd296ba2a7 50 Ltd, and the world's leading authority on the world's leading RTOS.
fep 0:62cd296ba2a7 51
fep 0:62cd296ba2a7 52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
fep 0:62cd296ba2a7 53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
fep 0:62cd296ba2a7 54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
fep 0:62cd296ba2a7 55
fep 0:62cd296ba2a7 56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
fep 0:62cd296ba2a7 57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
fep 0:62cd296ba2a7 58
fep 0:62cd296ba2a7 59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
fep 0:62cd296ba2a7 60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
fep 0:62cd296ba2a7 61 licenses offer ticketed support, indemnification and commercial middleware.
fep 0:62cd296ba2a7 62
fep 0:62cd296ba2a7 63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
fep 0:62cd296ba2a7 64 engineered and independently SIL3 certified version for use in safety and
fep 0:62cd296ba2a7 65 mission critical applications that require provable dependability.
fep 0:62cd296ba2a7 66
fep 0:62cd296ba2a7 67 1 tab == 4 spaces!
fep 0:62cd296ba2a7 68 */
fep 0:62cd296ba2a7 69
fep 0:62cd296ba2a7 70 /* Standard includes. */
fep 0:62cd296ba2a7 71 #include <stdlib.h>
fep 0:62cd296ba2a7 72
fep 0:62cd296ba2a7 73 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
fep 0:62cd296ba2a7 74 all the API functions to use the MPU wrappers. That should only be done when
fep 0:62cd296ba2a7 75 task.h is included from an application file. */
fep 0:62cd296ba2a7 76 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
fep 0:62cd296ba2a7 77
fep 0:62cd296ba2a7 78 /* FreeRTOS includes. */
fep 0:62cd296ba2a7 79 #include "FreeRTOS.h"
fep 0:62cd296ba2a7 80 #include "task.h"
fep 0:62cd296ba2a7 81 #include "timers.h"
fep 0:62cd296ba2a7 82 #include "event_groups.h"
fep 0:62cd296ba2a7 83
fep 0:62cd296ba2a7 84 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
fep 0:62cd296ba2a7 85 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
fep 0:62cd296ba2a7 86 header files above, but not in this file, in order to generate the correct
fep 0:62cd296ba2a7 87 privileged Vs unprivileged linkage and placement. */
fep 0:62cd296ba2a7 88 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
fep 0:62cd296ba2a7 89
fep 0:62cd296ba2a7 90 /* The following bit fields convey control information in a task's event list
fep 0:62cd296ba2a7 91 item value. It is important they don't clash with the
fep 0:62cd296ba2a7 92 taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
fep 0:62cd296ba2a7 93 #if configUSE_16_BIT_TICKS == 1
fep 0:62cd296ba2a7 94 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
fep 0:62cd296ba2a7 95 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
fep 0:62cd296ba2a7 96 #define eventWAIT_FOR_ALL_BITS 0x0400U
fep 0:62cd296ba2a7 97 #define eventEVENT_BITS_CONTROL_BYTES 0xff00U
fep 0:62cd296ba2a7 98 #else
fep 0:62cd296ba2a7 99 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
fep 0:62cd296ba2a7 100 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
fep 0:62cd296ba2a7 101 #define eventWAIT_FOR_ALL_BITS 0x04000000UL
fep 0:62cd296ba2a7 102 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
fep 0:62cd296ba2a7 103 #endif
fep 0:62cd296ba2a7 104
fep 0:62cd296ba2a7 105 typedef struct xEventGroupDefinition
fep 0:62cd296ba2a7 106 {
fep 0:62cd296ba2a7 107 EventBits_t uxEventBits;
fep 0:62cd296ba2a7 108 List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
fep 0:62cd296ba2a7 109
fep 0:62cd296ba2a7 110 #if( configUSE_TRACE_FACILITY == 1 )
fep 0:62cd296ba2a7 111 UBaseType_t uxEventGroupNumber;
fep 0:62cd296ba2a7 112 #endif
fep 0:62cd296ba2a7 113
fep 0:62cd296ba2a7 114 #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
fep 0:62cd296ba2a7 115 uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
fep 0:62cd296ba2a7 116 #endif
fep 0:62cd296ba2a7 117 } EventGroup_t;
fep 0:62cd296ba2a7 118
fep 0:62cd296ba2a7 119 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 120
fep 0:62cd296ba2a7 121 /*
fep 0:62cd296ba2a7 122 * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
fep 0:62cd296ba2a7 123 * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
fep 0:62cd296ba2a7 124 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
fep 0:62cd296ba2a7 125 * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
fep 0:62cd296ba2a7 126 * wait condition is met if any of the bits set in uxBitsToWait for are also set
fep 0:62cd296ba2a7 127 * in uxCurrentEventBits.
fep 0:62cd296ba2a7 128 */
fep 0:62cd296ba2a7 129 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
fep 0:62cd296ba2a7 130
fep 0:62cd296ba2a7 131 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 132
fep 0:62cd296ba2a7 133 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
fep 0:62cd296ba2a7 134
fep 0:62cd296ba2a7 135 EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
fep 0:62cd296ba2a7 136 {
fep 0:62cd296ba2a7 137 EventGroup_t *pxEventBits;
fep 0:62cd296ba2a7 138
fep 0:62cd296ba2a7 139 /* A StaticEventGroup_t object must be provided. */
fep 0:62cd296ba2a7 140 configASSERT( pxEventGroupBuffer );
fep 0:62cd296ba2a7 141
fep 0:62cd296ba2a7 142 /* The user has provided a statically allocated event group - use it. */
fep 0:62cd296ba2a7 143 pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
fep 0:62cd296ba2a7 144
fep 0:62cd296ba2a7 145 if( pxEventBits != NULL )
fep 0:62cd296ba2a7 146 {
fep 0:62cd296ba2a7 147 pxEventBits->uxEventBits = 0;
fep 0:62cd296ba2a7 148 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
fep 0:62cd296ba2a7 149
fep 0:62cd296ba2a7 150 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
fep 0:62cd296ba2a7 151 {
fep 0:62cd296ba2a7 152 /* Both static and dynamic allocation can be used, so note that
fep 0:62cd296ba2a7 153 this event group was created statically in case the event group
fep 0:62cd296ba2a7 154 is later deleted. */
fep 0:62cd296ba2a7 155 pxEventBits->ucStaticallyAllocated = pdTRUE;
fep 0:62cd296ba2a7 156 }
fep 0:62cd296ba2a7 157 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
fep 0:62cd296ba2a7 158
fep 0:62cd296ba2a7 159 traceEVENT_GROUP_CREATE( pxEventBits );
fep 0:62cd296ba2a7 160 }
fep 0:62cd296ba2a7 161 else
fep 0:62cd296ba2a7 162 {
fep 0:62cd296ba2a7 163 traceEVENT_GROUP_CREATE_FAILED();
fep 0:62cd296ba2a7 164 }
fep 0:62cd296ba2a7 165
fep 0:62cd296ba2a7 166 return ( EventGroupHandle_t ) pxEventBits;
fep 0:62cd296ba2a7 167 }
fep 0:62cd296ba2a7 168
fep 0:62cd296ba2a7 169 #endif /* configSUPPORT_STATIC_ALLOCATION */
fep 0:62cd296ba2a7 170 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 171
fep 0:62cd296ba2a7 172 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
fep 0:62cd296ba2a7 173
fep 0:62cd296ba2a7 174 EventGroupHandle_t xEventGroupCreate( void )
fep 0:62cd296ba2a7 175 {
fep 0:62cd296ba2a7 176 EventGroup_t *pxEventBits;
fep 0:62cd296ba2a7 177
fep 0:62cd296ba2a7 178 /* Allocate the event group. */
fep 0:62cd296ba2a7 179 pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
fep 0:62cd296ba2a7 180
fep 0:62cd296ba2a7 181 if( pxEventBits != NULL )
fep 0:62cd296ba2a7 182 {
fep 0:62cd296ba2a7 183 pxEventBits->uxEventBits = 0;
fep 0:62cd296ba2a7 184 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
fep 0:62cd296ba2a7 185
fep 0:62cd296ba2a7 186 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
fep 0:62cd296ba2a7 187 {
fep 0:62cd296ba2a7 188 /* Both static and dynamic allocation can be used, so note this
fep 0:62cd296ba2a7 189 event group was allocated statically in case the event group is
fep 0:62cd296ba2a7 190 later deleted. */
fep 0:62cd296ba2a7 191 pxEventBits->ucStaticallyAllocated = pdFALSE;
fep 0:62cd296ba2a7 192 }
fep 0:62cd296ba2a7 193 #endif /* configSUPPORT_STATIC_ALLOCATION */
fep 0:62cd296ba2a7 194
fep 0:62cd296ba2a7 195 traceEVENT_GROUP_CREATE( pxEventBits );
fep 0:62cd296ba2a7 196 }
fep 0:62cd296ba2a7 197 else
fep 0:62cd296ba2a7 198 {
fep 0:62cd296ba2a7 199 traceEVENT_GROUP_CREATE_FAILED();
fep 0:62cd296ba2a7 200 }
fep 0:62cd296ba2a7 201
fep 0:62cd296ba2a7 202 return ( EventGroupHandle_t ) pxEventBits;
fep 0:62cd296ba2a7 203 }
fep 0:62cd296ba2a7 204
fep 0:62cd296ba2a7 205 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
fep 0:62cd296ba2a7 206 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 207
fep 0:62cd296ba2a7 208 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
fep 0:62cd296ba2a7 209 {
fep 0:62cd296ba2a7 210 EventBits_t uxOriginalBitValue, uxReturn;
fep 0:62cd296ba2a7 211 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 212 BaseType_t xAlreadyYielded;
fep 0:62cd296ba2a7 213 BaseType_t xTimeoutOccurred = pdFALSE;
fep 0:62cd296ba2a7 214
fep 0:62cd296ba2a7 215 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
fep 0:62cd296ba2a7 216 configASSERT( uxBitsToWaitFor != 0 );
fep 0:62cd296ba2a7 217 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
fep 0:62cd296ba2a7 218 {
fep 0:62cd296ba2a7 219 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
fep 0:62cd296ba2a7 220 }
fep 0:62cd296ba2a7 221 #endif
fep 0:62cd296ba2a7 222
fep 0:62cd296ba2a7 223 vTaskSuspendAll();
fep 0:62cd296ba2a7 224 {
fep 0:62cd296ba2a7 225 uxOriginalBitValue = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 226
fep 0:62cd296ba2a7 227 ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
fep 0:62cd296ba2a7 228
fep 0:62cd296ba2a7 229 if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
fep 0:62cd296ba2a7 230 {
fep 0:62cd296ba2a7 231 /* All the rendezvous bits are now set - no need to block. */
fep 0:62cd296ba2a7 232 uxReturn = ( uxOriginalBitValue | uxBitsToSet );
fep 0:62cd296ba2a7 233
fep 0:62cd296ba2a7 234 /* Rendezvous always clear the bits. They will have been cleared
fep 0:62cd296ba2a7 235 already unless this is the only task in the rendezvous. */
fep 0:62cd296ba2a7 236 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
fep 0:62cd296ba2a7 237
fep 0:62cd296ba2a7 238 xTicksToWait = 0;
fep 0:62cd296ba2a7 239 }
fep 0:62cd296ba2a7 240 else
fep 0:62cd296ba2a7 241 {
fep 0:62cd296ba2a7 242 if( xTicksToWait != ( TickType_t ) 0 )
fep 0:62cd296ba2a7 243 {
fep 0:62cd296ba2a7 244 traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
fep 0:62cd296ba2a7 245
fep 0:62cd296ba2a7 246 /* Store the bits that the calling task is waiting for in the
fep 0:62cd296ba2a7 247 task's event list item so the kernel knows when a match is
fep 0:62cd296ba2a7 248 found. Then enter the blocked state. */
fep 0:62cd296ba2a7 249 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
fep 0:62cd296ba2a7 250
fep 0:62cd296ba2a7 251 /* This assignment is obsolete as uxReturn will get set after
fep 0:62cd296ba2a7 252 the task unblocks, but some compilers mistakenly generate a
fep 0:62cd296ba2a7 253 warning about uxReturn being returned without being set if the
fep 0:62cd296ba2a7 254 assignment is omitted. */
fep 0:62cd296ba2a7 255 uxReturn = 0;
fep 0:62cd296ba2a7 256 }
fep 0:62cd296ba2a7 257 else
fep 0:62cd296ba2a7 258 {
fep 0:62cd296ba2a7 259 /* The rendezvous bits were not set, but no block time was
fep 0:62cd296ba2a7 260 specified - just return the current event bit value. */
fep 0:62cd296ba2a7 261 uxReturn = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 262 }
fep 0:62cd296ba2a7 263 }
fep 0:62cd296ba2a7 264 }
fep 0:62cd296ba2a7 265 xAlreadyYielded = xTaskResumeAll();
fep 0:62cd296ba2a7 266
fep 0:62cd296ba2a7 267 if( xTicksToWait != ( TickType_t ) 0 )
fep 0:62cd296ba2a7 268 {
fep 0:62cd296ba2a7 269 if( xAlreadyYielded == pdFALSE )
fep 0:62cd296ba2a7 270 {
fep 0:62cd296ba2a7 271 portYIELD_WITHIN_API();
fep 0:62cd296ba2a7 272 }
fep 0:62cd296ba2a7 273 else
fep 0:62cd296ba2a7 274 {
fep 0:62cd296ba2a7 275 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 276 }
fep 0:62cd296ba2a7 277
fep 0:62cd296ba2a7 278 /* The task blocked to wait for its required bits to be set - at this
fep 0:62cd296ba2a7 279 point either the required bits were set or the block time expired. If
fep 0:62cd296ba2a7 280 the required bits were set they will have been stored in the task's
fep 0:62cd296ba2a7 281 event list item, and they should now be retrieved then cleared. */
fep 0:62cd296ba2a7 282 uxReturn = uxTaskResetEventItemValue();
fep 0:62cd296ba2a7 283
fep 0:62cd296ba2a7 284 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 285 {
fep 0:62cd296ba2a7 286 /* The task timed out, just return the current event bit value. */
fep 0:62cd296ba2a7 287 taskENTER_CRITICAL();
fep 0:62cd296ba2a7 288 {
fep 0:62cd296ba2a7 289 uxReturn = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 290
fep 0:62cd296ba2a7 291 /* Although the task got here because it timed out before the
fep 0:62cd296ba2a7 292 bits it was waiting for were set, it is possible that since it
fep 0:62cd296ba2a7 293 unblocked another task has set the bits. If this is the case
fep 0:62cd296ba2a7 294 then it needs to clear the bits before exiting. */
fep 0:62cd296ba2a7 295 if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
fep 0:62cd296ba2a7 296 {
fep 0:62cd296ba2a7 297 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
fep 0:62cd296ba2a7 298 }
fep 0:62cd296ba2a7 299 else
fep 0:62cd296ba2a7 300 {
fep 0:62cd296ba2a7 301 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 302 }
fep 0:62cd296ba2a7 303 }
fep 0:62cd296ba2a7 304 taskEXIT_CRITICAL();
fep 0:62cd296ba2a7 305
fep 0:62cd296ba2a7 306 xTimeoutOccurred = pdTRUE;
fep 0:62cd296ba2a7 307 }
fep 0:62cd296ba2a7 308 else
fep 0:62cd296ba2a7 309 {
fep 0:62cd296ba2a7 310 /* The task unblocked because the bits were set. */
fep 0:62cd296ba2a7 311 }
fep 0:62cd296ba2a7 312
fep 0:62cd296ba2a7 313 /* Control bits might be set as the task had blocked should not be
fep 0:62cd296ba2a7 314 returned. */
fep 0:62cd296ba2a7 315 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
fep 0:62cd296ba2a7 316 }
fep 0:62cd296ba2a7 317
fep 0:62cd296ba2a7 318 traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
fep 0:62cd296ba2a7 319
fep 0:62cd296ba2a7 320 return uxReturn;
fep 0:62cd296ba2a7 321 }
fep 0:62cd296ba2a7 322 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 323
fep 0:62cd296ba2a7 324 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
fep 0:62cd296ba2a7 325 {
fep 0:62cd296ba2a7 326 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 327 EventBits_t uxReturn, uxControlBits = 0;
fep 0:62cd296ba2a7 328 BaseType_t xWaitConditionMet, xAlreadyYielded;
fep 0:62cd296ba2a7 329 BaseType_t xTimeoutOccurred = pdFALSE;
fep 0:62cd296ba2a7 330
fep 0:62cd296ba2a7 331 /* Check the user is not attempting to wait on the bits used by the kernel
fep 0:62cd296ba2a7 332 itself, and that at least one bit is being requested. */
fep 0:62cd296ba2a7 333 configASSERT( xEventGroup );
fep 0:62cd296ba2a7 334 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
fep 0:62cd296ba2a7 335 configASSERT( uxBitsToWaitFor != 0 );
fep 0:62cd296ba2a7 336 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
fep 0:62cd296ba2a7 337 {
fep 0:62cd296ba2a7 338 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
fep 0:62cd296ba2a7 339 }
fep 0:62cd296ba2a7 340 #endif
fep 0:62cd296ba2a7 341
fep 0:62cd296ba2a7 342 vTaskSuspendAll();
fep 0:62cd296ba2a7 343 {
fep 0:62cd296ba2a7 344 const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 345
fep 0:62cd296ba2a7 346 /* Check to see if the wait condition is already met or not. */
fep 0:62cd296ba2a7 347 xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
fep 0:62cd296ba2a7 348
fep 0:62cd296ba2a7 349 if( xWaitConditionMet != pdFALSE )
fep 0:62cd296ba2a7 350 {
fep 0:62cd296ba2a7 351 /* The wait condition has already been met so there is no need to
fep 0:62cd296ba2a7 352 block. */
fep 0:62cd296ba2a7 353 uxReturn = uxCurrentEventBits;
fep 0:62cd296ba2a7 354 xTicksToWait = ( TickType_t ) 0;
fep 0:62cd296ba2a7 355
fep 0:62cd296ba2a7 356 /* Clear the wait bits if requested to do so. */
fep 0:62cd296ba2a7 357 if( xClearOnExit != pdFALSE )
fep 0:62cd296ba2a7 358 {
fep 0:62cd296ba2a7 359 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
fep 0:62cd296ba2a7 360 }
fep 0:62cd296ba2a7 361 else
fep 0:62cd296ba2a7 362 {
fep 0:62cd296ba2a7 363 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 364 }
fep 0:62cd296ba2a7 365 }
fep 0:62cd296ba2a7 366 else if( xTicksToWait == ( TickType_t ) 0 )
fep 0:62cd296ba2a7 367 {
fep 0:62cd296ba2a7 368 /* The wait condition has not been met, but no block time was
fep 0:62cd296ba2a7 369 specified, so just return the current value. */
fep 0:62cd296ba2a7 370 uxReturn = uxCurrentEventBits;
fep 0:62cd296ba2a7 371 }
fep 0:62cd296ba2a7 372 else
fep 0:62cd296ba2a7 373 {
fep 0:62cd296ba2a7 374 /* The task is going to block to wait for its required bits to be
fep 0:62cd296ba2a7 375 set. uxControlBits are used to remember the specified behaviour of
fep 0:62cd296ba2a7 376 this call to xEventGroupWaitBits() - for use when the event bits
fep 0:62cd296ba2a7 377 unblock the task. */
fep 0:62cd296ba2a7 378 if( xClearOnExit != pdFALSE )
fep 0:62cd296ba2a7 379 {
fep 0:62cd296ba2a7 380 uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
fep 0:62cd296ba2a7 381 }
fep 0:62cd296ba2a7 382 else
fep 0:62cd296ba2a7 383 {
fep 0:62cd296ba2a7 384 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 385 }
fep 0:62cd296ba2a7 386
fep 0:62cd296ba2a7 387 if( xWaitForAllBits != pdFALSE )
fep 0:62cd296ba2a7 388 {
fep 0:62cd296ba2a7 389 uxControlBits |= eventWAIT_FOR_ALL_BITS;
fep 0:62cd296ba2a7 390 }
fep 0:62cd296ba2a7 391 else
fep 0:62cd296ba2a7 392 {
fep 0:62cd296ba2a7 393 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 394 }
fep 0:62cd296ba2a7 395
fep 0:62cd296ba2a7 396 /* Store the bits that the calling task is waiting for in the
fep 0:62cd296ba2a7 397 task's event list item so the kernel knows when a match is
fep 0:62cd296ba2a7 398 found. Then enter the blocked state. */
fep 0:62cd296ba2a7 399 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
fep 0:62cd296ba2a7 400
fep 0:62cd296ba2a7 401 /* This is obsolete as it will get set after the task unblocks, but
fep 0:62cd296ba2a7 402 some compilers mistakenly generate a warning about the variable
fep 0:62cd296ba2a7 403 being returned without being set if it is not done. */
fep 0:62cd296ba2a7 404 uxReturn = 0;
fep 0:62cd296ba2a7 405
fep 0:62cd296ba2a7 406 traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
fep 0:62cd296ba2a7 407 }
fep 0:62cd296ba2a7 408 }
fep 0:62cd296ba2a7 409 xAlreadyYielded = xTaskResumeAll();
fep 0:62cd296ba2a7 410
fep 0:62cd296ba2a7 411 if( xTicksToWait != ( TickType_t ) 0 )
fep 0:62cd296ba2a7 412 {
fep 0:62cd296ba2a7 413 if( xAlreadyYielded == pdFALSE )
fep 0:62cd296ba2a7 414 {
fep 0:62cd296ba2a7 415 portYIELD_WITHIN_API();
fep 0:62cd296ba2a7 416 }
fep 0:62cd296ba2a7 417 else
fep 0:62cd296ba2a7 418 {
fep 0:62cd296ba2a7 419 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 420 }
fep 0:62cd296ba2a7 421
fep 0:62cd296ba2a7 422 /* The task blocked to wait for its required bits to be set - at this
fep 0:62cd296ba2a7 423 point either the required bits were set or the block time expired. If
fep 0:62cd296ba2a7 424 the required bits were set they will have been stored in the task's
fep 0:62cd296ba2a7 425 event list item, and they should now be retrieved then cleared. */
fep 0:62cd296ba2a7 426 uxReturn = uxTaskResetEventItemValue();
fep 0:62cd296ba2a7 427
fep 0:62cd296ba2a7 428 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 429 {
fep 0:62cd296ba2a7 430 taskENTER_CRITICAL();
fep 0:62cd296ba2a7 431 {
fep 0:62cd296ba2a7 432 /* The task timed out, just return the current event bit value. */
fep 0:62cd296ba2a7 433 uxReturn = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 434
fep 0:62cd296ba2a7 435 /* It is possible that the event bits were updated between this
fep 0:62cd296ba2a7 436 task leaving the Blocked state and running again. */
fep 0:62cd296ba2a7 437 if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
fep 0:62cd296ba2a7 438 {
fep 0:62cd296ba2a7 439 if( xClearOnExit != pdFALSE )
fep 0:62cd296ba2a7 440 {
fep 0:62cd296ba2a7 441 pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
fep 0:62cd296ba2a7 442 }
fep 0:62cd296ba2a7 443 else
fep 0:62cd296ba2a7 444 {
fep 0:62cd296ba2a7 445 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 446 }
fep 0:62cd296ba2a7 447 }
fep 0:62cd296ba2a7 448 else
fep 0:62cd296ba2a7 449 {
fep 0:62cd296ba2a7 450 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 451 }
fep 0:62cd296ba2a7 452 }
fep 0:62cd296ba2a7 453 taskEXIT_CRITICAL();
fep 0:62cd296ba2a7 454
fep 0:62cd296ba2a7 455 /* Prevent compiler warnings when trace macros are not used. */
fep 0:62cd296ba2a7 456 xTimeoutOccurred = pdFALSE;
fep 0:62cd296ba2a7 457 }
fep 0:62cd296ba2a7 458 else
fep 0:62cd296ba2a7 459 {
fep 0:62cd296ba2a7 460 /* The task unblocked because the bits were set. */
fep 0:62cd296ba2a7 461 }
fep 0:62cd296ba2a7 462
fep 0:62cd296ba2a7 463 /* The task blocked so control bits may have been set. */
fep 0:62cd296ba2a7 464 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
fep 0:62cd296ba2a7 465 }
fep 0:62cd296ba2a7 466 traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
fep 0:62cd296ba2a7 467
fep 0:62cd296ba2a7 468 return uxReturn;
fep 0:62cd296ba2a7 469 }
fep 0:62cd296ba2a7 470 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 471
fep 0:62cd296ba2a7 472 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
fep 0:62cd296ba2a7 473 {
fep 0:62cd296ba2a7 474 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 475 EventBits_t uxReturn;
fep 0:62cd296ba2a7 476
fep 0:62cd296ba2a7 477 /* Check the user is not attempting to clear the bits used by the kernel
fep 0:62cd296ba2a7 478 itself. */
fep 0:62cd296ba2a7 479 configASSERT( xEventGroup );
fep 0:62cd296ba2a7 480 configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
fep 0:62cd296ba2a7 481
fep 0:62cd296ba2a7 482 taskENTER_CRITICAL();
fep 0:62cd296ba2a7 483 {
fep 0:62cd296ba2a7 484 traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
fep 0:62cd296ba2a7 485
fep 0:62cd296ba2a7 486 /* The value returned is the event group value prior to the bits being
fep 0:62cd296ba2a7 487 cleared. */
fep 0:62cd296ba2a7 488 uxReturn = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 489
fep 0:62cd296ba2a7 490 /* Clear the bits. */
fep 0:62cd296ba2a7 491 pxEventBits->uxEventBits &= ~uxBitsToClear;
fep 0:62cd296ba2a7 492 }
fep 0:62cd296ba2a7 493 taskEXIT_CRITICAL();
fep 0:62cd296ba2a7 494
fep 0:62cd296ba2a7 495 return uxReturn;
fep 0:62cd296ba2a7 496 }
fep 0:62cd296ba2a7 497 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 498
fep 0:62cd296ba2a7 499 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
fep 0:62cd296ba2a7 500
fep 0:62cd296ba2a7 501 BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
fep 0:62cd296ba2a7 502 {
fep 0:62cd296ba2a7 503 BaseType_t xReturn;
fep 0:62cd296ba2a7 504
fep 0:62cd296ba2a7 505 traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
fep 0:62cd296ba2a7 506 xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
fep 0:62cd296ba2a7 507
fep 0:62cd296ba2a7 508 return xReturn;
fep 0:62cd296ba2a7 509 }
fep 0:62cd296ba2a7 510
fep 0:62cd296ba2a7 511 #endif
fep 0:62cd296ba2a7 512 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 513
fep 0:62cd296ba2a7 514 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
fep 0:62cd296ba2a7 515 {
fep 0:62cd296ba2a7 516 UBaseType_t uxSavedInterruptStatus;
fep 0:62cd296ba2a7 517 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 518 EventBits_t uxReturn;
fep 0:62cd296ba2a7 519
fep 0:62cd296ba2a7 520 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
fep 0:62cd296ba2a7 521 {
fep 0:62cd296ba2a7 522 uxReturn = pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 523 }
fep 0:62cd296ba2a7 524 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
fep 0:62cd296ba2a7 525
fep 0:62cd296ba2a7 526 return uxReturn;
fep 0:62cd296ba2a7 527 }
fep 0:62cd296ba2a7 528 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 529
fep 0:62cd296ba2a7 530 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
fep 0:62cd296ba2a7 531 {
fep 0:62cd296ba2a7 532 ListItem_t *pxListItem, *pxNext;
fep 0:62cd296ba2a7 533 ListItem_t const *pxListEnd;
fep 0:62cd296ba2a7 534 List_t *pxList;
fep 0:62cd296ba2a7 535 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
fep 0:62cd296ba2a7 536 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 537 BaseType_t xMatchFound = pdFALSE;
fep 0:62cd296ba2a7 538
fep 0:62cd296ba2a7 539 /* Check the user is not attempting to set the bits used by the kernel
fep 0:62cd296ba2a7 540 itself. */
fep 0:62cd296ba2a7 541 configASSERT( xEventGroup );
fep 0:62cd296ba2a7 542 configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
fep 0:62cd296ba2a7 543
fep 0:62cd296ba2a7 544 pxList = &( pxEventBits->xTasksWaitingForBits );
fep 0:62cd296ba2a7 545 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. */
fep 0:62cd296ba2a7 546 vTaskSuspendAll();
fep 0:62cd296ba2a7 547 {
fep 0:62cd296ba2a7 548 traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
fep 0:62cd296ba2a7 549
fep 0:62cd296ba2a7 550 pxListItem = listGET_HEAD_ENTRY( pxList );
fep 0:62cd296ba2a7 551
fep 0:62cd296ba2a7 552 /* Set the bits. */
fep 0:62cd296ba2a7 553 pxEventBits->uxEventBits |= uxBitsToSet;
fep 0:62cd296ba2a7 554
fep 0:62cd296ba2a7 555 /* See if the new bit value should unblock any tasks. */
fep 0:62cd296ba2a7 556 while( pxListItem != pxListEnd )
fep 0:62cd296ba2a7 557 {
fep 0:62cd296ba2a7 558 pxNext = listGET_NEXT( pxListItem );
fep 0:62cd296ba2a7 559 uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
fep 0:62cd296ba2a7 560 xMatchFound = pdFALSE;
fep 0:62cd296ba2a7 561
fep 0:62cd296ba2a7 562 /* Split the bits waited for from the control bits. */
fep 0:62cd296ba2a7 563 uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
fep 0:62cd296ba2a7 564 uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
fep 0:62cd296ba2a7 565
fep 0:62cd296ba2a7 566 if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 567 {
fep 0:62cd296ba2a7 568 /* Just looking for single bit being set. */
fep 0:62cd296ba2a7 569 if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 570 {
fep 0:62cd296ba2a7 571 xMatchFound = pdTRUE;
fep 0:62cd296ba2a7 572 }
fep 0:62cd296ba2a7 573 else
fep 0:62cd296ba2a7 574 {
fep 0:62cd296ba2a7 575 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 576 }
fep 0:62cd296ba2a7 577 }
fep 0:62cd296ba2a7 578 else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
fep 0:62cd296ba2a7 579 {
fep 0:62cd296ba2a7 580 /* All bits are set. */
fep 0:62cd296ba2a7 581 xMatchFound = pdTRUE;
fep 0:62cd296ba2a7 582 }
fep 0:62cd296ba2a7 583 else
fep 0:62cd296ba2a7 584 {
fep 0:62cd296ba2a7 585 /* Need all bits to be set, but not all the bits were set. */
fep 0:62cd296ba2a7 586 }
fep 0:62cd296ba2a7 587
fep 0:62cd296ba2a7 588 if( xMatchFound != pdFALSE )
fep 0:62cd296ba2a7 589 {
fep 0:62cd296ba2a7 590 /* The bits match. Should the bits be cleared on exit? */
fep 0:62cd296ba2a7 591 if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 592 {
fep 0:62cd296ba2a7 593 uxBitsToClear |= uxBitsWaitedFor;
fep 0:62cd296ba2a7 594 }
fep 0:62cd296ba2a7 595 else
fep 0:62cd296ba2a7 596 {
fep 0:62cd296ba2a7 597 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 598 }
fep 0:62cd296ba2a7 599
fep 0:62cd296ba2a7 600 /* Store the actual event flag value in the task's event list
fep 0:62cd296ba2a7 601 item before removing the task from the event list. The
fep 0:62cd296ba2a7 602 eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
fep 0:62cd296ba2a7 603 that is was unblocked due to its required bits matching, rather
fep 0:62cd296ba2a7 604 than because it timed out. */
fep 0:62cd296ba2a7 605 ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
fep 0:62cd296ba2a7 606 }
fep 0:62cd296ba2a7 607
fep 0:62cd296ba2a7 608 /* Move onto the next list item. Note pxListItem->pxNext is not
fep 0:62cd296ba2a7 609 used here as the list item may have been removed from the event list
fep 0:62cd296ba2a7 610 and inserted into the ready/pending reading list. */
fep 0:62cd296ba2a7 611 pxListItem = pxNext;
fep 0:62cd296ba2a7 612 }
fep 0:62cd296ba2a7 613
fep 0:62cd296ba2a7 614 /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
fep 0:62cd296ba2a7 615 bit was set in the control word. */
fep 0:62cd296ba2a7 616 pxEventBits->uxEventBits &= ~uxBitsToClear;
fep 0:62cd296ba2a7 617 }
fep 0:62cd296ba2a7 618 ( void ) xTaskResumeAll();
fep 0:62cd296ba2a7 619
fep 0:62cd296ba2a7 620 return pxEventBits->uxEventBits;
fep 0:62cd296ba2a7 621 }
fep 0:62cd296ba2a7 622 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 623
fep 0:62cd296ba2a7 624 void vEventGroupDelete( EventGroupHandle_t xEventGroup )
fep 0:62cd296ba2a7 625 {
fep 0:62cd296ba2a7 626 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 627 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
fep 0:62cd296ba2a7 628
fep 0:62cd296ba2a7 629 vTaskSuspendAll();
fep 0:62cd296ba2a7 630 {
fep 0:62cd296ba2a7 631 traceEVENT_GROUP_DELETE( xEventGroup );
fep 0:62cd296ba2a7 632
fep 0:62cd296ba2a7 633 while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
fep 0:62cd296ba2a7 634 {
fep 0:62cd296ba2a7 635 /* Unblock the task, returning 0 as the event list is being deleted
fep 0:62cd296ba2a7 636 and cannot therefore have any bits set. */
fep 0:62cd296ba2a7 637 configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
fep 0:62cd296ba2a7 638 ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
fep 0:62cd296ba2a7 639 }
fep 0:62cd296ba2a7 640
fep 0:62cd296ba2a7 641 #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
fep 0:62cd296ba2a7 642 {
fep 0:62cd296ba2a7 643 /* The event group can only have been allocated dynamically - free
fep 0:62cd296ba2a7 644 it again. */
fep 0:62cd296ba2a7 645 vPortFree( pxEventBits );
fep 0:62cd296ba2a7 646 }
fep 0:62cd296ba2a7 647 #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
fep 0:62cd296ba2a7 648 {
fep 0:62cd296ba2a7 649 /* The event group could have been allocated statically or
fep 0:62cd296ba2a7 650 dynamically, so check before attempting to free the memory. */
fep 0:62cd296ba2a7 651 if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
fep 0:62cd296ba2a7 652 {
fep 0:62cd296ba2a7 653 vPortFree( pxEventBits );
fep 0:62cd296ba2a7 654 }
fep 0:62cd296ba2a7 655 else
fep 0:62cd296ba2a7 656 {
fep 0:62cd296ba2a7 657 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 658 }
fep 0:62cd296ba2a7 659 }
fep 0:62cd296ba2a7 660 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
fep 0:62cd296ba2a7 661 }
fep 0:62cd296ba2a7 662 ( void ) xTaskResumeAll();
fep 0:62cd296ba2a7 663 }
fep 0:62cd296ba2a7 664 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 665
fep 0:62cd296ba2a7 666 /* For internal use only - execute a 'set bits' command that was pended from
fep 0:62cd296ba2a7 667 an interrupt. */
fep 0:62cd296ba2a7 668 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
fep 0:62cd296ba2a7 669 {
fep 0:62cd296ba2a7 670 ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
fep 0:62cd296ba2a7 671 }
fep 0:62cd296ba2a7 672 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 673
fep 0:62cd296ba2a7 674 /* For internal use only - execute a 'clear bits' command that was pended from
fep 0:62cd296ba2a7 675 an interrupt. */
fep 0:62cd296ba2a7 676 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
fep 0:62cd296ba2a7 677 {
fep 0:62cd296ba2a7 678 ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
fep 0:62cd296ba2a7 679 }
fep 0:62cd296ba2a7 680 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 681
fep 0:62cd296ba2a7 682 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
fep 0:62cd296ba2a7 683 {
fep 0:62cd296ba2a7 684 BaseType_t xWaitConditionMet = pdFALSE;
fep 0:62cd296ba2a7 685
fep 0:62cd296ba2a7 686 if( xWaitForAllBits == pdFALSE )
fep 0:62cd296ba2a7 687 {
fep 0:62cd296ba2a7 688 /* Task only has to wait for one bit within uxBitsToWaitFor to be
fep 0:62cd296ba2a7 689 set. Is one already set? */
fep 0:62cd296ba2a7 690 if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
fep 0:62cd296ba2a7 691 {
fep 0:62cd296ba2a7 692 xWaitConditionMet = pdTRUE;
fep 0:62cd296ba2a7 693 }
fep 0:62cd296ba2a7 694 else
fep 0:62cd296ba2a7 695 {
fep 0:62cd296ba2a7 696 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 697 }
fep 0:62cd296ba2a7 698 }
fep 0:62cd296ba2a7 699 else
fep 0:62cd296ba2a7 700 {
fep 0:62cd296ba2a7 701 /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
fep 0:62cd296ba2a7 702 Are they set already? */
fep 0:62cd296ba2a7 703 if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
fep 0:62cd296ba2a7 704 {
fep 0:62cd296ba2a7 705 xWaitConditionMet = pdTRUE;
fep 0:62cd296ba2a7 706 }
fep 0:62cd296ba2a7 707 else
fep 0:62cd296ba2a7 708 {
fep 0:62cd296ba2a7 709 mtCOVERAGE_TEST_MARKER();
fep 0:62cd296ba2a7 710 }
fep 0:62cd296ba2a7 711 }
fep 0:62cd296ba2a7 712
fep 0:62cd296ba2a7 713 return xWaitConditionMet;
fep 0:62cd296ba2a7 714 }
fep 0:62cd296ba2a7 715 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 716
fep 0:62cd296ba2a7 717 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
fep 0:62cd296ba2a7 718
fep 0:62cd296ba2a7 719 BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
fep 0:62cd296ba2a7 720 {
fep 0:62cd296ba2a7 721 BaseType_t xReturn;
fep 0:62cd296ba2a7 722
fep 0:62cd296ba2a7 723 traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
fep 0:62cd296ba2a7 724 xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
fep 0:62cd296ba2a7 725
fep 0:62cd296ba2a7 726 return xReturn;
fep 0:62cd296ba2a7 727 }
fep 0:62cd296ba2a7 728
fep 0:62cd296ba2a7 729 #endif
fep 0:62cd296ba2a7 730 /*-----------------------------------------------------------*/
fep 0:62cd296ba2a7 731
fep 0:62cd296ba2a7 732 #if (configUSE_TRACE_FACILITY == 1)
fep 0:62cd296ba2a7 733
fep 0:62cd296ba2a7 734 UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
fep 0:62cd296ba2a7 735 {
fep 0:62cd296ba2a7 736 UBaseType_t xReturn;
fep 0:62cd296ba2a7 737 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
fep 0:62cd296ba2a7 738
fep 0:62cd296ba2a7 739 if( xEventGroup == NULL )
fep 0:62cd296ba2a7 740 {
fep 0:62cd296ba2a7 741 xReturn = 0;
fep 0:62cd296ba2a7 742 }
fep 0:62cd296ba2a7 743 else
fep 0:62cd296ba2a7 744 {
fep 0:62cd296ba2a7 745 xReturn = pxEventBits->uxEventGroupNumber;
fep 0:62cd296ba2a7 746 }
fep 0:62cd296ba2a7 747
fep 0:62cd296ba2a7 748 return xReturn;
fep 0:62cd296ba2a7 749 }
fep 0:62cd296ba2a7 750
fep 0:62cd296ba2a7 751 #endif
fep 0:62cd296ba2a7 752
fep 0:62cd296ba2a7 753