TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.
event_groups.c
00001 /* 00002 FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd. 00003 All rights reserved 00004 00005 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 00006 00007 This file is part of the FreeRTOS distribution. 00008 00009 FreeRTOS is free software; you can redistribute it and/or modify it under 00010 the terms of the GNU General Public License (version 2) as published by the 00011 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. 00012 00013 *************************************************************************** 00014 >>! NOTE: The modification to the GPL is included to allow you to !<< 00015 >>! distribute a combined work that includes FreeRTOS without being !<< 00016 >>! obliged to provide the source code for proprietary components !<< 00017 >>! outside of the FreeRTOS kernel. !<< 00018 *************************************************************************** 00019 00020 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 00021 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00022 FOR A PARTICULAR PURPOSE. Full license text is available on the following 00023 link: http://www.freertos.org/a00114.html 00024 00025 *************************************************************************** 00026 * * 00027 * FreeRTOS provides completely free yet professionally developed, * 00028 * robust, strictly quality controlled, supported, and cross * 00029 * platform software that is more than just the market leader, it * 00030 * is the industry's de facto standard. * 00031 * * 00032 * Help yourself get started quickly while simultaneously helping * 00033 * to support the FreeRTOS project by purchasing a FreeRTOS * 00034 * tutorial book, reference manual, or both: * 00035 * http://www.FreeRTOS.org/Documentation * 00036 * * 00037 *************************************************************************** 00038 00039 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 00040 the FAQ page "My application does not run, what could be wrong?". Have you 00041 defined configASSERT()? 00042 00043 http://www.FreeRTOS.org/support - In return for receiving this top quality 00044 embedded software for free we request you assist our global community by 00045 participating in the support forum. 00046 00047 http://www.FreeRTOS.org/training - Investing in training allows your team to 00048 be as productive as possible as early as possible. Now you can receive 00049 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 00050 Ltd, and the world's leading authority on the world's leading RTOS. 00051 00052 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 00053 including FreeRTOS+Trace - an indispensable productivity tool, a DOS 00054 compatible FAT file system, and our tiny thread aware UDP/IP stack. 00055 00056 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 00057 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 00058 00059 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 00060 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 00061 licenses offer ticketed support, indemnification and commercial middleware. 00062 00063 http://www.SafeRTOS.com - High Integrity Systems also provide a safety 00064 engineered and independently SIL3 certified version for use in safety and 00065 mission critical applications that require provable dependability. 00066 00067 1 tab == 4 spaces! 00068 */ 00069 00070 /* Standard includes. */ 00071 #include <stdlib.h> 00072 00073 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining 00074 all the API functions to use the MPU wrappers. That should only be done when 00075 task.h is included from an application file. */ 00076 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE 00077 00078 /* FreeRTOS includes. */ 00079 #include "FreeRTOS.h" 00080 #include "task.h" 00081 #include "timers.h" 00082 #include "event_groups.h" 00083 00084 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the 00085 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the 00086 header files above, but not in this file, in order to generate the correct 00087 privileged Vs unprivileged linkage and placement. */ 00088 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ 00089 00090 #if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 ) 00091 #error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available. 00092 #endif 00093 00094 #if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 ) 00095 #error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available. 00096 #endif 00097 00098 /* The following bit fields convey control information in a task's event list 00099 item value. It is important they don't clash with the 00100 taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ 00101 #if configUSE_16_BIT_TICKS == 1 00102 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U 00103 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U 00104 #define eventWAIT_FOR_ALL_BITS 0x0400U 00105 #define eventEVENT_BITS_CONTROL_BYTES 0xff00U 00106 #else 00107 #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL 00108 #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL 00109 #define eventWAIT_FOR_ALL_BITS 0x04000000UL 00110 #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL 00111 #endif 00112 00113 typedef struct xEventGroupDefinition 00114 { 00115 EventBits_t uxEventBits; 00116 List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ 00117 00118 #if( configUSE_TRACE_FACILITY == 1 ) 00119 UBaseType_t uxEventGroupNumber; 00120 #endif 00121 00122 } EventGroup_t; 00123 00124 /*-----------------------------------------------------------*/ 00125 00126 /* 00127 * Test the bits set in uxCurrentEventBits to see if the wait condition is met. 00128 * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is 00129 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor 00130 * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the 00131 * wait condition is met if any of the bits set in uxBitsToWait for are also set 00132 * in uxCurrentEventBits. 00133 */ 00134 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ); 00135 00136 /*-----------------------------------------------------------*/ 00137 00138 EventGroupHandle_t xEventGroupCreate( void ) 00139 { 00140 EventGroup_t *pxEventBits; 00141 00142 pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); 00143 if( pxEventBits != NULL ) 00144 { 00145 pxEventBits->uxEventBits = 0; 00146 vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); 00147 traceEVENT_GROUP_CREATE( pxEventBits ); 00148 } 00149 else 00150 { 00151 traceEVENT_GROUP_CREATE_FAILED(); 00152 } 00153 00154 return ( EventGroupHandle_t ) pxEventBits; 00155 } 00156 /*-----------------------------------------------------------*/ 00157 00158 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) 00159 { 00160 EventBits_t uxOriginalBitValue, uxReturn; 00161 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00162 BaseType_t xAlreadyYielded; 00163 BaseType_t xTimeoutOccurred = pdFALSE; 00164 00165 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 00166 configASSERT( uxBitsToWaitFor != 0 ); 00167 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) 00168 { 00169 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); 00170 } 00171 #endif 00172 00173 vTaskSuspendAll(); 00174 { 00175 uxOriginalBitValue = pxEventBits->uxEventBits; 00176 00177 ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); 00178 00179 if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) 00180 { 00181 /* All the rendezvous bits are now set - no need to block. */ 00182 uxReturn = ( uxOriginalBitValue | uxBitsToSet ); 00183 00184 /* Rendezvous always clear the bits. They will have been cleared 00185 already unless this is the only task in the rendezvous. */ 00186 pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 00187 00188 xTicksToWait = 0; 00189 } 00190 else 00191 { 00192 if( xTicksToWait != ( TickType_t ) 0 ) 00193 { 00194 traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); 00195 00196 /* Store the bits that the calling task is waiting for in the 00197 task's event list item so the kernel knows when a match is 00198 found. Then enter the blocked state. */ 00199 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); 00200 00201 /* This assignment is obsolete as uxReturn will get set after 00202 the task unblocks, but some compilers mistakenly generate a 00203 warning about uxReturn being returned without being set if the 00204 assignment is omitted. */ 00205 uxReturn = 0; 00206 } 00207 else 00208 { 00209 /* The rendezvous bits were not set, but no block time was 00210 specified - just return the current event bit value. */ 00211 uxReturn = pxEventBits->uxEventBits; 00212 } 00213 } 00214 } 00215 xAlreadyYielded = xTaskResumeAll(); 00216 00217 if( xTicksToWait != ( TickType_t ) 0 ) 00218 { 00219 if( xAlreadyYielded == pdFALSE ) 00220 { 00221 portYIELD_WITHIN_API(); 00222 } 00223 else 00224 { 00225 mtCOVERAGE_TEST_MARKER(); 00226 } 00227 00228 /* The task blocked to wait for its required bits to be set - at this 00229 point either the required bits were set or the block time expired. If 00230 the required bits were set they will have been stored in the task's 00231 event list item, and they should now be retrieved then cleared. */ 00232 uxReturn = uxTaskResetEventItemValue(); 00233 00234 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) 00235 { 00236 /* The task timed out, just return the current event bit value. */ 00237 taskENTER_CRITICAL(); 00238 { 00239 uxReturn = pxEventBits->uxEventBits; 00240 00241 /* Although the task got here because it timed out before the 00242 bits it was waiting for were set, it is possible that since it 00243 unblocked another task has set the bits. If this is the case 00244 then it needs to clear the bits before exiting. */ 00245 if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) 00246 { 00247 pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 00248 } 00249 else 00250 { 00251 mtCOVERAGE_TEST_MARKER(); 00252 } 00253 } 00254 taskEXIT_CRITICAL(); 00255 00256 xTimeoutOccurred = pdTRUE; 00257 } 00258 else 00259 { 00260 /* The task unblocked because the bits were set. */ 00261 } 00262 00263 /* Control bits might be set as the task had blocked should not be 00264 returned. */ 00265 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; 00266 } 00267 00268 traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); 00269 00270 return uxReturn; 00271 } 00272 /*-----------------------------------------------------------*/ 00273 00274 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) 00275 { 00276 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00277 EventBits_t uxReturn, uxControlBits = 0; 00278 BaseType_t xWaitConditionMet, xAlreadyYielded; 00279 BaseType_t xTimeoutOccurred = pdFALSE; 00280 00281 /* Check the user is not attempting to wait on the bits used by the kernel 00282 itself, and that at least one bit is being requested. */ 00283 configASSERT( xEventGroup ); 00284 configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 00285 configASSERT( uxBitsToWaitFor != 0 ); 00286 #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) 00287 { 00288 configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); 00289 } 00290 #endif 00291 00292 vTaskSuspendAll(); 00293 { 00294 const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; 00295 00296 /* Check to see if the wait condition is already met or not. */ 00297 xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); 00298 00299 if( xWaitConditionMet != pdFALSE ) 00300 { 00301 /* The wait condition has already been met so there is no need to 00302 block. */ 00303 uxReturn = uxCurrentEventBits; 00304 xTicksToWait = ( TickType_t ) 0; 00305 00306 /* Clear the wait bits if requested to do so. */ 00307 if( xClearOnExit != pdFALSE ) 00308 { 00309 pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 00310 } 00311 else 00312 { 00313 mtCOVERAGE_TEST_MARKER(); 00314 } 00315 } 00316 else if( xTicksToWait == ( TickType_t ) 0 ) 00317 { 00318 /* The wait condition has not been met, but no block time was 00319 specified, so just return the current value. */ 00320 uxReturn = uxCurrentEventBits; 00321 } 00322 else 00323 { 00324 /* The task is going to block to wait for its required bits to be 00325 set. uxControlBits are used to remember the specified behaviour of 00326 this call to xEventGroupWaitBits() - for use when the event bits 00327 unblock the task. */ 00328 if( xClearOnExit != pdFALSE ) 00329 { 00330 uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; 00331 } 00332 else 00333 { 00334 mtCOVERAGE_TEST_MARKER(); 00335 } 00336 00337 if( xWaitForAllBits != pdFALSE ) 00338 { 00339 uxControlBits |= eventWAIT_FOR_ALL_BITS; 00340 } 00341 else 00342 { 00343 mtCOVERAGE_TEST_MARKER(); 00344 } 00345 00346 /* Store the bits that the calling task is waiting for in the 00347 task's event list item so the kernel knows when a match is 00348 found. Then enter the blocked state. */ 00349 vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); 00350 00351 /* This is obsolete as it will get set after the task unblocks, but 00352 some compilers mistakenly generate a warning about the variable 00353 being returned without being set if it is not done. */ 00354 uxReturn = 0; 00355 00356 traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); 00357 } 00358 } 00359 xAlreadyYielded = xTaskResumeAll(); 00360 00361 if( xTicksToWait != ( TickType_t ) 0 ) 00362 { 00363 if( xAlreadyYielded == pdFALSE ) 00364 { 00365 portYIELD_WITHIN_API(); 00366 } 00367 else 00368 { 00369 mtCOVERAGE_TEST_MARKER(); 00370 } 00371 00372 /* The task blocked to wait for its required bits to be set - at this 00373 point either the required bits were set or the block time expired. If 00374 the required bits were set they will have been stored in the task's 00375 event list item, and they should now be retrieved then cleared. */ 00376 uxReturn = uxTaskResetEventItemValue(); 00377 00378 if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) 00379 { 00380 taskENTER_CRITICAL(); 00381 { 00382 /* The task timed out, just return the current event bit value. */ 00383 uxReturn = pxEventBits->uxEventBits; 00384 00385 /* It is possible that the event bits were updated between this 00386 task leaving the Blocked state and running again. */ 00387 if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) 00388 { 00389 if( xClearOnExit != pdFALSE ) 00390 { 00391 pxEventBits->uxEventBits &= ~uxBitsToWaitFor; 00392 } 00393 else 00394 { 00395 mtCOVERAGE_TEST_MARKER(); 00396 } 00397 } 00398 else 00399 { 00400 mtCOVERAGE_TEST_MARKER(); 00401 } 00402 } 00403 taskEXIT_CRITICAL(); 00404 00405 /* Prevent compiler warnings when trace macros are not used. */ 00406 xTimeoutOccurred = pdFALSE; 00407 } 00408 else 00409 { 00410 /* The task unblocked because the bits were set. */ 00411 } 00412 00413 /* The task blocked so control bits may have been set. */ 00414 uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; 00415 } 00416 traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); 00417 00418 return uxReturn; 00419 } 00420 /*-----------------------------------------------------------*/ 00421 00422 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) 00423 { 00424 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00425 EventBits_t uxReturn; 00426 00427 /* Check the user is not attempting to clear the bits used by the kernel 00428 itself. */ 00429 configASSERT( xEventGroup ); 00430 configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 00431 00432 taskENTER_CRITICAL(); 00433 { 00434 traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); 00435 00436 /* The value returned is the event group value prior to the bits being 00437 cleared. */ 00438 uxReturn = pxEventBits->uxEventBits; 00439 00440 /* Clear the bits. */ 00441 pxEventBits->uxEventBits &= ~uxBitsToClear; 00442 } 00443 taskEXIT_CRITICAL(); 00444 00445 return uxReturn; 00446 } 00447 /*-----------------------------------------------------------*/ 00448 00449 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) 00450 00451 BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) 00452 { 00453 BaseType_t xReturn; 00454 00455 traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); 00456 xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); 00457 00458 return xReturn; 00459 } 00460 00461 #endif 00462 /*-----------------------------------------------------------*/ 00463 00464 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) 00465 { 00466 UBaseType_t uxSavedInterruptStatus; 00467 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00468 EventBits_t uxReturn; 00469 00470 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); 00471 { 00472 uxReturn = pxEventBits->uxEventBits; 00473 } 00474 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); 00475 00476 return uxReturn; 00477 } 00478 /*-----------------------------------------------------------*/ 00479 00480 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) 00481 { 00482 ListItem_t *pxListItem, *pxNext; 00483 ListItem_t const *pxListEnd; 00484 List_t *pxList; 00485 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; 00486 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00487 BaseType_t xMatchFound = pdFALSE; 00488 00489 /* Check the user is not attempting to set the bits used by the kernel 00490 itself. */ 00491 configASSERT( xEventGroup ); 00492 configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 00493 00494 pxList = &( pxEventBits->xTasksWaitingForBits ); 00495 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. */ 00496 vTaskSuspendAll(); 00497 { 00498 traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); 00499 00500 pxListItem = listGET_HEAD_ENTRY( pxList ); 00501 00502 /* Set the bits. */ 00503 pxEventBits->uxEventBits |= uxBitsToSet; 00504 00505 /* See if the new bit value should unblock any tasks. */ 00506 while( pxListItem != pxListEnd ) 00507 { 00508 pxNext = listGET_NEXT( pxListItem ); 00509 uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); 00510 xMatchFound = pdFALSE; 00511 00512 /* Split the bits waited for from the control bits. */ 00513 uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; 00514 uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; 00515 00516 if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) 00517 { 00518 /* Just looking for single bit being set. */ 00519 if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) 00520 { 00521 xMatchFound = pdTRUE; 00522 } 00523 else 00524 { 00525 mtCOVERAGE_TEST_MARKER(); 00526 } 00527 } 00528 else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) 00529 { 00530 /* All bits are set. */ 00531 xMatchFound = pdTRUE; 00532 } 00533 else 00534 { 00535 /* Need all bits to be set, but not all the bits were set. */ 00536 } 00537 00538 if( xMatchFound != pdFALSE ) 00539 { 00540 /* The bits match. Should the bits be cleared on exit? */ 00541 if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) 00542 { 00543 uxBitsToClear |= uxBitsWaitedFor; 00544 } 00545 else 00546 { 00547 mtCOVERAGE_TEST_MARKER(); 00548 } 00549 00550 /* Store the actual event flag value in the task's event list 00551 item before removing the task from the event list. The 00552 eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows 00553 that is was unblocked due to its required bits matching, rather 00554 than because it timed out. */ 00555 ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); 00556 } 00557 00558 /* Move onto the next list item. Note pxListItem->pxNext is not 00559 used here as the list item may have been removed from the event list 00560 and inserted into the ready/pending reading list. */ 00561 pxListItem = pxNext; 00562 } 00563 00564 /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT 00565 bit was set in the control word. */ 00566 pxEventBits->uxEventBits &= ~uxBitsToClear; 00567 } 00568 ( void ) xTaskResumeAll(); 00569 00570 return pxEventBits->uxEventBits; 00571 } 00572 /*-----------------------------------------------------------*/ 00573 00574 void vEventGroupDelete( EventGroupHandle_t xEventGroup ) 00575 { 00576 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00577 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); 00578 00579 vTaskSuspendAll(); 00580 { 00581 traceEVENT_GROUP_DELETE( xEventGroup ); 00582 00583 while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) 00584 { 00585 /* Unblock the task, returning 0 as the event list is being deleted 00586 and cannot therefore have any bits set. */ 00587 configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); 00588 ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); 00589 } 00590 00591 vPortFree( pxEventBits ); 00592 } 00593 ( void ) xTaskResumeAll(); 00594 } 00595 /*-----------------------------------------------------------*/ 00596 00597 /* For internal use only - execute a 'set bits' command that was pended from 00598 an interrupt. */ 00599 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) 00600 { 00601 ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); 00602 } 00603 /*-----------------------------------------------------------*/ 00604 00605 /* For internal use only - execute a 'clear bits' command that was pended from 00606 an interrupt. */ 00607 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) 00608 { 00609 ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); 00610 } 00611 /*-----------------------------------------------------------*/ 00612 00613 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) 00614 { 00615 BaseType_t xWaitConditionMet = pdFALSE; 00616 00617 if( xWaitForAllBits == pdFALSE ) 00618 { 00619 /* Task only has to wait for one bit within uxBitsToWaitFor to be 00620 set. Is one already set? */ 00621 if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) 00622 { 00623 xWaitConditionMet = pdTRUE; 00624 } 00625 else 00626 { 00627 mtCOVERAGE_TEST_MARKER(); 00628 } 00629 } 00630 else 00631 { 00632 /* Task has to wait for all the bits in uxBitsToWaitFor to be set. 00633 Are they set already? */ 00634 if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) 00635 { 00636 xWaitConditionMet = pdTRUE; 00637 } 00638 else 00639 { 00640 mtCOVERAGE_TEST_MARKER(); 00641 } 00642 } 00643 00644 return xWaitConditionMet; 00645 } 00646 /*-----------------------------------------------------------*/ 00647 00648 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) 00649 00650 BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) 00651 { 00652 BaseType_t xReturn; 00653 00654 traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); 00655 xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); 00656 00657 return xReturn; 00658 } 00659 00660 #endif 00661 /*-----------------------------------------------------------*/ 00662 00663 #if (configUSE_TRACE_FACILITY == 1) 00664 00665 UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) 00666 { 00667 UBaseType_t xReturn; 00668 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; 00669 00670 if( xEventGroup == NULL ) 00671 { 00672 xReturn = 0; 00673 } 00674 else 00675 { 00676 xReturn = pxEventBits->uxEventGroupNumber; 00677 } 00678 00679 return xReturn; 00680 } 00681 00682 #endif 00683 00684
Generated on Wed Jul 13 2022 15:58:45 by 1.7.2