Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: frdm_k64f_freertos_lib
src/event_groups.c@0:62cd296ba2a7, 2017-05-31 (annotated)
- 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?
| User | Revision | Line number | New 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 |