event_groups.c
Go to the documentation of this file.
1 /*
2  * FreeRTOS Kernel V10.0.0
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software. If you wish to use our Amazon
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * http://www.FreeRTOS.org
24  * http://aws.amazon.com/freertos
25  *
26  * 1 tab == 4 spaces!
27  */
28 
29 /* Standard includes. */
30 #include <stdlib.h>
31 
32 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
33 all the API functions to use the MPU wrappers. That should only be done when
34 task.h is included from an application file. */
35 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
36 
37 /* FreeRTOS includes. */
38 #include "FreeRTOS.h"
39 #include "task.h"
40 #include "timers.h"
41 #include "event_groups.h"
42 
43 /* Lint e961 and e750 are suppressed as a MISRA exception justified because the
44 MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
45 header files above, but not in this file, in order to generate the correct
46 privileged Vs unprivileged linkage and placement. */
47 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
48 
49 /* The following bit fields convey control information in a task's event list
50 item value. It is important they don't clash with the
51 taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
52 #if configUSE_16_BIT_TICKS == 1
53  #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
54  #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
55  #define eventWAIT_FOR_ALL_BITS 0x0400U
56  #define eventEVENT_BITS_CONTROL_BYTES 0xff00U
57 #else
58  #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
59  #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
60  #define eventWAIT_FOR_ALL_BITS 0x04000000UL
61  #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
62 #endif
63 
64 typedef struct xEventGroupDefinition
65 {
67  List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
68 
69  #if( configUSE_TRACE_FACILITY == 1 )
70  UBaseType_t uxEventGroupNumber;
71  #endif
72 
73  #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
74  uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
75  #endif
76 } EventGroup_t;
77 
78 /*-----------------------------------------------------------*/
79 
80 /*
81  * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
82  * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
83  * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
84  * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
85  * wait condition is met if any of the bits set in uxBitsToWait for are also set
86  * in uxCurrentEventBits.
87  */
88 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
89 
90 /*-----------------------------------------------------------*/
91 
92 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
93 
94  EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
95  {
96  EventGroup_t *pxEventBits;
97 
98  /* A StaticEventGroup_t object must be provided. */
99  configASSERT( pxEventGroupBuffer );
100 
101  #if( configASSERT_DEFINED == 1 )
102  {
103  /* Sanity check that the size of the structure used to declare a
104  variable of type StaticEventGroup_t equals the size of the real
105  event group structure. */
106  volatile size_t xSize = sizeof( StaticEventGroup_t );
107  configASSERT( xSize == sizeof( EventGroup_t ) );
108  }
109  #endif /* configASSERT_DEFINED */
110 
111  /* The user has provided a statically allocated event group - use it. */
112  pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */
113 
114  if( pxEventBits != NULL )
115  {
116  pxEventBits->uxEventBits = 0;
117  vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
118 
119  #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
120  {
121  /* Both static and dynamic allocation can be used, so note that
122  this event group was created statically in case the event group
123  is later deleted. */
124  pxEventBits->ucStaticallyAllocated = pdTRUE;
125  }
126  #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
127 
128  traceEVENT_GROUP_CREATE( pxEventBits );
129  }
130  else
131  {
133  }
134 
135  return ( EventGroupHandle_t ) pxEventBits;
136  }
137 
138 #endif /* configSUPPORT_STATIC_ALLOCATION */
139 /*-----------------------------------------------------------*/
140 
141 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
142 
143  EventGroupHandle_t xEventGroupCreate( void )
144  {
145  EventGroup_t *pxEventBits;
146 
147  /* Allocate the event group. */
148  pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
149 
150  if( pxEventBits != NULL )
151  {
152  pxEventBits->uxEventBits = 0;
153  vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
154 
155  #if( configSUPPORT_STATIC_ALLOCATION == 1 )
156  {
157  /* Both static and dynamic allocation can be used, so note this
158  event group was allocated statically in case the event group is
159  later deleted. */
160  pxEventBits->ucStaticallyAllocated = pdFALSE;
161  }
162  #endif /* configSUPPORT_STATIC_ALLOCATION */
163 
164  traceEVENT_GROUP_CREATE( pxEventBits );
165  }
166  else
167  {
169  }
170 
171  return ( EventGroupHandle_t ) pxEventBits;
172  }
173 
174 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
175 /*-----------------------------------------------------------*/
176 
177 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
178 {
179 EventBits_t uxOriginalBitValue, uxReturn;
180 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
181 BaseType_t xAlreadyYielded;
182 BaseType_t xTimeoutOccurred = pdFALSE;
183 
184  configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
185  configASSERT( uxBitsToWaitFor != 0 );
186  #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
187  {
188  configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
189  }
190  #endif
191 
192  vTaskSuspendAll();
193  {
194  uxOriginalBitValue = pxEventBits->uxEventBits;
195 
196  ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
197 
198  if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
199  {
200  /* All the rendezvous bits are now set - no need to block. */
201  uxReturn = ( uxOriginalBitValue | uxBitsToSet );
202 
203  /* Rendezvous always clear the bits. They will have been cleared
204  already unless this is the only task in the rendezvous. */
205  pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
206 
207  xTicksToWait = 0;
208  }
209  else
210  {
211  if( xTicksToWait != ( TickType_t ) 0 )
212  {
213  traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
214 
215  /* Store the bits that the calling task is waiting for in the
216  task's event list item so the kernel knows when a match is
217  found. Then enter the blocked state. */
218  vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
219 
220  /* This assignment is obsolete as uxReturn will get set after
221  the task unblocks, but some compilers mistakenly generate a
222  warning about uxReturn being returned without being set if the
223  assignment is omitted. */
224  uxReturn = 0;
225  }
226  else
227  {
228  /* The rendezvous bits were not set, but no block time was
229  specified - just return the current event bit value. */
230  uxReturn = pxEventBits->uxEventBits;
231  xTimeoutOccurred = pdTRUE;
232  }
233  }
234  }
235  xAlreadyYielded = xTaskResumeAll();
236 
237  if( xTicksToWait != ( TickType_t ) 0 )
238  {
239  if( xAlreadyYielded == pdFALSE )
240  {
242  }
243  else
244  {
246  }
247 
248  /* The task blocked to wait for its required bits to be set - at this
249  point either the required bits were set or the block time expired. If
250  the required bits were set they will have been stored in the task's
251  event list item, and they should now be retrieved then cleared. */
252  uxReturn = uxTaskResetEventItemValue();
253 
254  if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
255  {
256  /* The task timed out, just return the current event bit value. */
258  {
259  uxReturn = pxEventBits->uxEventBits;
260 
261  /* Although the task got here because it timed out before the
262  bits it was waiting for were set, it is possible that since it
263  unblocked another task has set the bits. If this is the case
264  then it needs to clear the bits before exiting. */
265  if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
266  {
267  pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
268  }
269  else
270  {
272  }
273  }
275 
276  xTimeoutOccurred = pdTRUE;
277  }
278  else
279  {
280  /* The task unblocked because the bits were set. */
281  }
282 
283  /* Control bits might be set as the task had blocked should not be
284  returned. */
285  uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
286  }
287 
288  traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
289 
290  /* Prevent compiler warnings when trace macros are not used. */
291  ( void ) xTimeoutOccurred;
292 
293  return uxReturn;
294 }
295 /*-----------------------------------------------------------*/
296 
297 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
298 {
299 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
300 EventBits_t uxReturn, uxControlBits = 0;
301 BaseType_t xWaitConditionMet, xAlreadyYielded;
302 BaseType_t xTimeoutOccurred = pdFALSE;
303 
304  /* Check the user is not attempting to wait on the bits used by the kernel
305  itself, and that at least one bit is being requested. */
306  configASSERT( xEventGroup );
307  configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
308  configASSERT( uxBitsToWaitFor != 0 );
309  #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
310  {
311  configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
312  }
313  #endif
314 
315  vTaskSuspendAll();
316  {
317  const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
318 
319  /* Check to see if the wait condition is already met or not. */
320  xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
321 
322  if( xWaitConditionMet != pdFALSE )
323  {
324  /* The wait condition has already been met so there is no need to
325  block. */
326  uxReturn = uxCurrentEventBits;
327  xTicksToWait = ( TickType_t ) 0;
328 
329  /* Clear the wait bits if requested to do so. */
330  if( xClearOnExit != pdFALSE )
331  {
332  pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
333  }
334  else
335  {
337  }
338  }
339  else if( xTicksToWait == ( TickType_t ) 0 )
340  {
341  /* The wait condition has not been met, but no block time was
342  specified, so just return the current value. */
343  uxReturn = uxCurrentEventBits;
344  xTimeoutOccurred = pdTRUE;
345  }
346  else
347  {
348  /* The task is going to block to wait for its required bits to be
349  set. uxControlBits are used to remember the specified behaviour of
350  this call to xEventGroupWaitBits() - for use when the event bits
351  unblock the task. */
352  if( xClearOnExit != pdFALSE )
353  {
354  uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
355  }
356  else
357  {
359  }
360 
361  if( xWaitForAllBits != pdFALSE )
362  {
363  uxControlBits |= eventWAIT_FOR_ALL_BITS;
364  }
365  else
366  {
368  }
369 
370  /* Store the bits that the calling task is waiting for in the
371  task's event list item so the kernel knows when a match is
372  found. Then enter the blocked state. */
373  vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
374 
375  /* This is obsolete as it will get set after the task unblocks, but
376  some compilers mistakenly generate a warning about the variable
377  being returned without being set if it is not done. */
378  uxReturn = 0;
379 
380  traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
381  }
382  }
383  xAlreadyYielded = xTaskResumeAll();
384 
385  if( xTicksToWait != ( TickType_t ) 0 )
386  {
387  if( xAlreadyYielded == pdFALSE )
388  {
390  }
391  else
392  {
394  }
395 
396  /* The task blocked to wait for its required bits to be set - at this
397  point either the required bits were set or the block time expired. If
398  the required bits were set they will have been stored in the task's
399  event list item, and they should now be retrieved then cleared. */
400  uxReturn = uxTaskResetEventItemValue();
401 
402  if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
403  {
405  {
406  /* The task timed out, just return the current event bit value. */
407  uxReturn = pxEventBits->uxEventBits;
408 
409  /* It is possible that the event bits were updated between this
410  task leaving the Blocked state and running again. */
411  if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
412  {
413  if( xClearOnExit != pdFALSE )
414  {
415  pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
416  }
417  else
418  {
420  }
421  }
422  else
423  {
425  }
426  xTimeoutOccurred = pdTRUE;
427  }
429  }
430  else
431  {
432  /* The task unblocked because the bits were set. */
433  }
434 
435  /* The task blocked so control bits may have been set. */
436  uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
437  }
438  traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
439 
440  /* Prevent compiler warnings when trace macros are not used. */
441  ( void ) xTimeoutOccurred;
442 
443  return uxReturn;
444 }
445 /*-----------------------------------------------------------*/
446 
448 {
449 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
450 EventBits_t uxReturn;
451 
452  /* Check the user is not attempting to clear the bits used by the kernel
453  itself. */
454  configASSERT( xEventGroup );
455  configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
456 
458  {
459  traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
460 
461  /* The value returned is the event group value prior to the bits being
462  cleared. */
463  uxReturn = pxEventBits->uxEventBits;
464 
465  /* Clear the bits. */
466  pxEventBits->uxEventBits &= ~uxBitsToClear;
467  }
469 
470  return uxReturn;
471 }
472 /*-----------------------------------------------------------*/
473 
474 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
475 
476  BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
477  {
478  BaseType_t xReturn;
479 
480  traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
481  xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
482 
483  return xReturn;
484  }
485 
486 #endif
487 /*-----------------------------------------------------------*/
488 
490 {
491 UBaseType_t uxSavedInterruptStatus;
492 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
493 EventBits_t uxReturn;
494 
495  uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
496  {
497  uxReturn = pxEventBits->uxEventBits;
498  }
499  portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
500 
501  return uxReturn;
502 }
503 /*-----------------------------------------------------------*/
504 
506 {
507 ListItem_t *pxListItem, *pxNext;
508 ListItem_t const *pxListEnd;
509 List_t *pxList;
510 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
511 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
512 BaseType_t xMatchFound = pdFALSE;
513 
514  /* Check the user is not attempting to set the bits used by the kernel
515  itself. */
516  configASSERT( xEventGroup );
517  configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
518 
519  pxList = &( pxEventBits->xTasksWaitingForBits );
520  pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
521  vTaskSuspendAll();
522  {
523  traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
524 
525  pxListItem = listGET_HEAD_ENTRY( pxList );
526 
527  /* Set the bits. */
528  pxEventBits->uxEventBits |= uxBitsToSet;
529 
530  /* See if the new bit value should unblock any tasks. */
531  while( pxListItem != pxListEnd )
532  {
533  pxNext = listGET_NEXT( pxListItem );
534  uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
535  xMatchFound = pdFALSE;
536 
537  /* Split the bits waited for from the control bits. */
538  uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
539  uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
540 
541  if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
542  {
543  /* Just looking for single bit being set. */
544  if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
545  {
546  xMatchFound = pdTRUE;
547  }
548  else
549  {
551  }
552  }
553  else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
554  {
555  /* All bits are set. */
556  xMatchFound = pdTRUE;
557  }
558  else
559  {
560  /* Need all bits to be set, but not all the bits were set. */
561  }
562 
563  if( xMatchFound != pdFALSE )
564  {
565  /* The bits match. Should the bits be cleared on exit? */
566  if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
567  {
568  uxBitsToClear |= uxBitsWaitedFor;
569  }
570  else
571  {
573  }
574 
575  /* Store the actual event flag value in the task's event list
576  item before removing the task from the event list. The
577  eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
578  that is was unblocked due to its required bits matching, rather
579  than because it timed out. */
581  }
582 
583  /* Move onto the next list item. Note pxListItem->pxNext is not
584  used here as the list item may have been removed from the event list
585  and inserted into the ready/pending reading list. */
586  pxListItem = pxNext;
587  }
588 
589  /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
590  bit was set in the control word. */
591  pxEventBits->uxEventBits &= ~uxBitsToClear;
592  }
593  ( void ) xTaskResumeAll();
594 
595  return pxEventBits->uxEventBits;
596 }
597 /*-----------------------------------------------------------*/
598 
600 {
601 EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
602 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
603 
604  vTaskSuspendAll();
605  {
606  traceEVENT_GROUP_DELETE( xEventGroup );
607 
608  while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
609  {
610  /* Unblock the task, returning 0 as the event list is being deleted
611  and cannot therefore have any bits set. */
612  configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
614  }
615 
616  #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
617  {
618  /* The event group can only have been allocated dynamically - free
619  it again. */
620  vPortFree( pxEventBits );
621  }
622  #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
623  {
624  /* The event group could have been allocated statically or
625  dynamically, so check before attempting to free the memory. */
626  if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
627  {
628  vPortFree( pxEventBits );
629  }
630  else
631  {
633  }
634  }
635  #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
636  }
637  ( void ) xTaskResumeAll();
638 }
639 /*-----------------------------------------------------------*/
640 
641 /* For internal use only - execute a 'set bits' command that was pended from
642 an interrupt. */
643 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
644 {
645  ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
646 }
647 /*-----------------------------------------------------------*/
648 
649 /* For internal use only - execute a 'clear bits' command that was pended from
650 an interrupt. */
651 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
652 {
653  ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );
654 }
655 /*-----------------------------------------------------------*/
656 
657 static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
658 {
659 BaseType_t xWaitConditionMet = pdFALSE;
660 
661  if( xWaitForAllBits == pdFALSE )
662  {
663  /* Task only has to wait for one bit within uxBitsToWaitFor to be
664  set. Is one already set? */
665  if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
666  {
667  xWaitConditionMet = pdTRUE;
668  }
669  else
670  {
672  }
673  }
674  else
675  {
676  /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
677  Are they set already? */
678  if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
679  {
680  xWaitConditionMet = pdTRUE;
681  }
682  else
683  {
685  }
686  }
687 
688  return xWaitConditionMet;
689 }
690 /*-----------------------------------------------------------*/
691 
692 #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
693 
694  BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
695  {
696  BaseType_t xReturn;
697 
698  traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
699  xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
700 
701  return xReturn;
702  }
703 
704 #endif
705 /*-----------------------------------------------------------*/
706 
707 #if (configUSE_TRACE_FACILITY == 1)
708 
709  UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
710  {
711  UBaseType_t xReturn;
712  EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
713 
714  if( xEventGroup == NULL )
715  {
716  xReturn = 0;
717  }
718  else
719  {
720  xReturn = pxEventBits->uxEventGroupNumber;
721  }
722 
723  return xReturn;
724  }
725 
726 #endif /* configUSE_TRACE_FACILITY */
727 /*-----------------------------------------------------------*/
728 
729 #if ( configUSE_TRACE_FACILITY == 1 )
730 
731  void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )
732  {
733  ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;
734  }
735 
736 #endif /* configUSE_TRACE_FACILITY */
737 /*-----------------------------------------------------------*/
738 
739 
#define pdTRUE
Definition: projdefs.h:46
#define xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken)
Definition: event_groups.h:562
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_4.c:311
#define listGET_LIST_ITEM_VALUE(pxListItem)
Definition: list.h:208
BaseType_t xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION
struct xLIST_ITEM *configLIST_VOLATILE pxNext
Definition: list.h:156
#define traceEVENT_GROUP_WAIT_BITS_BLOCK(xEventGroup, uxBitsToWaitFor)
Definition: FreeRTOS.h:573
Definition: list.h:164
TickType_t EventBits_t
Definition: event_groups.h:92
#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(xEventGroup, uxBitsToClear)
Definition: FreeRTOS.h:585
#define traceEVENT_GROUP_SYNC_BLOCK(xEventGroup, uxBitsToSet, uxBitsToWaitFor)
Definition: FreeRTOS.h:565
void vEventGroupSetBitsCallback(void *pvEventGroup, const uint32_t ulBitsToSet)
Definition: event_groups.c:643
#define taskEXIT_CRITICAL()
Definition: task.h:194
void vTaskSuspendAll(void) PRIVILEGED_FUNCTION
Definition: tasks.c:2034
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear)
Definition: event_groups.c:447
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:155
#define NULL
Definition: nm_bsp.h:52
#define traceEVENT_GROUP_CREATE_FAILED()
Definition: FreeRTOS.h:561
void vTaskPlaceOnUnorderedEventList(List_t *pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait) PRIVILEGED_FUNCTION
Definition: tasks.c:2929
#define traceEVENT_GROUP_CREATE(xEventGroup)
Definition: FreeRTOS.h:557
void vEventGroupClearBitsCallback(void *pvEventGroup, const uint32_t ulBitsToClear)
Definition: event_groups.c:651
unsigned long UBaseType_t
Definition: portmacro.h:58
EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)
Definition: event_groups.c:489
uint32_t TickType_t
Definition: portmacro.h:64
#define portSET_INTERRUPT_MASK_FROM_ISR()
Definition: FreeRTOS.h:259
#define traceEVENT_GROUP_DELETE(xEventGroup)
Definition: FreeRTOS.h:597
#define configASSERT(x)
Definition: FreeRTOS.h:235
#define traceEVENT_GROUP_SYNC_END(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred)
Definition: FreeRTOS.h:569
void vEventGroupDelete(EventGroupHandle_t xEventGroup)
Definition: event_groups.c:599
#define traceEVENT_GROUP_CLEAR_BITS(xEventGroup, uxBitsToClear)
Definition: FreeRTOS.h:581
#define eventCLEAR_EVENTS_ON_EXIT_BIT
Definition: event_groups.c:58
#define listGET_NEXT(pxListItem)
Definition: list.h:233
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet)
Definition: event_groups.c:505
long BaseType_t
Definition: portmacro.h:57
EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait)
Definition: event_groups.c:297
struct xSTATIC_EVENT_GROUP StaticEventGroup_t
TickType_t uxTaskResetEventItemValue(void) PRIVILEGED_FUNCTION
Definition: tasks.c:4388
#define xEventGroupClearBitsFromISR(xEventGroup, uxBitsToClear)
Definition: event_groups.h:410
#define traceEVENT_GROUP_WAIT_BITS_END(xEventGroup, uxBitsToWaitFor, xTimeoutOccurred)
Definition: FreeRTOS.h:577
#define traceEVENT_GROUP_SET_BITS(xEventGroup, uxBitsToSet)
Definition: FreeRTOS.h:589
#define portYIELD_WITHIN_API
Definition: FreeRTOS.h:723
#define pdFALSE
Definition: projdefs.h:45
BaseType_t xTaskResumeAll(void) PRIVILEGED_FUNCTION
Definition: tasks.c:2107
#define eventWAIT_FOR_ALL_BITS
Definition: event_groups.c:60
BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION
#define taskENTER_CRITICAL()
Definition: task.h:179
EventBits_t uxEventBits
Definition: event_groups.c:66
MiniListItem_t xListEnd
Definition: list.h:169
static BaseType_t prvTestWaitCondition(const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits) PRIVILEGED_FUNCTION
Definition: event_groups.c:657
#define eventEVENT_BITS_CONTROL_BYTES
Definition: event_groups.c:61
void * EventGroupHandle_t
Definition: event_groups.h:82
#define PRIVILEGED_FUNCTION
Definition: mpu_wrappers.h:174
#define listGET_HEAD_ENTRY(pxList)
Definition: list.h:225
#define listGET_END_MARKER(pxList)
Definition: list.h:241
#define mtCOVERAGE_TEST_MARKER()
Definition: FreeRTOS.h:787
#define taskSCHEDULER_SUSPENDED
Definition: task.h:219
#define eventUNBLOCKED_DUE_TO_BIT_SET
Definition: event_groups.c:59
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue)
Definition: FreeRTOS.h:263
EventBits_t xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait)
Definition: event_groups.c:177
#define listCURRENT_LIST_LENGTH(pxList)
Definition: list.h:255
void vTaskRemoveFromUnorderedEventList(ListItem_t *pxEventListItem, const TickType_t xItemValue) PRIVILEGED_FUNCTION
Definition: tasks.c:3054
struct xEventGroupDefinition EventGroup_t
#define traceEVENT_GROUP_SET_BITS_FROM_ISR(xEventGroup, uxBitsToSet)
Definition: FreeRTOS.h:593
void vListInitialise(List_t *const pxList) PRIVILEGED_FUNCTION
Definition: list.c:38


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:04