2 FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
7 This file is part of the FreeRTOS distribution.
9 FreeRTOS is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License (version 2) as published by the
11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
13 ***************************************************************************
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
15 >>! distribute a combined work that includes FreeRTOS without being !<<
16 >>! obliged to provide the source code for proprietary components !<<
17 >>! outside of the FreeRTOS kernel. !<<
18 ***************************************************************************
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
23 link: http://www.freertos.org/a00114.html
25 ***************************************************************************
27 * FreeRTOS provides completely free yet professionally developed, *
28 * robust, strictly quality controlled, supported, and cross *
29 * platform software that is more than just the market leader, it *
30 * is the industry's de facto standard. *
32 * Help yourself get started quickly while simultaneously helping *
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
34 * tutorial book, reference manual, or both: *
35 * http://www.FreeRTOS.org/Documentation *
37 ***************************************************************************
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
40 the FAQ page "My application does not run, what could be wrong?". Have you
41 defined configASSERT()?
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
44 embedded software for free we request you assist our global community by
45 participating in the support forum.
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
48 be as productive as possible as early as possible. Now you can receive
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50 Ltd, and the world's leading authority on the world's leading RTOS.
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
61 licenses offer ticketed support, indemnification and commercial middleware.
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64 engineered and independently SIL3 certified version for use in safety and
65 mission critical applications that require provable dependability.
73 * This file contains fairly comprehensive checks on the behaviour of event
74 * groups. It is not intended to be a user friendly demonstration of the
77 * NOTE: The tests implemented in this file are informal 'sanity' tests
78 * only and are not part of the module tests that make use of the
79 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
83 /* Scheduler include files. */
86 #include "event_groups.h"
88 /* Demo app includes. */
89 #include "EventGroupsDemo.h"
91 #if( INCLUDE_eTaskGetState != 1 )
92 #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.
95 /* Priorities used by the tasks. */
96 #define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY )
97 #define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
99 /* Generic bit definitions. */
100 #define ebBIT_0 ( 0x01 )
101 #define ebBIT_1 ( 0x02 )
102 #define ebBIT_2 ( 0x04 )
103 #define ebBIT_3 ( 0x08 )
104 #define ebBIT_4 ( 0x10 )
105 #define ebBIT_5 ( 0x20 )
106 #define ebBIT_6 ( 0x40 )
107 #define ebBIT_7 ( 0x80 )
109 /* Combinations of bits used in the demo. */
110 #define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )
111 #define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )
113 /* Associate a bit to each task. These bits are used to identify all the tasks
114 that synchronise with the xEventGroupSync() function. */
115 #define ebSET_BIT_TASK_SYNC_BIT ebBIT_0
116 #define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1
117 #define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2
118 #define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3
119 #define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT )
121 /* A block time of zero simply means "don't block". */
122 #define ebDONT_BLOCK ( 0 )
125 #define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 )
127 /* Used in the selective bits test which checks no, one or both tasks blocked on
128 event bits in a group are unblocked as appropriate as different bits get set. */
129 #define ebSELECTIVE_BITS_1 0x03
130 #define ebSELECTIVE_BITS_2 0x05
132 /*-----------------------------------------------------------*/
135 * NOTE: The tests implemented in this function are informal 'sanity' tests
136 * only and are not part of the module tests that make use of the
137 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
139 * The master test task. This task:
141 * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two
142 * tasks are blocked on different bits in an event group. The counterpart of
143 * this test is implemented by the prvSelectiveBitsTestSlaveFunction()
144 * function (which is called by the two tasks that block on the event group).
146 * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when
147 * just one task is blocked on various combinations of bits within an event
148 * group. The counterpart of this test is implemented within the 'test
151 * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.
153 static void prvTestMasterTask( void *pvParameters );
156 * A helper task that enables the 'test master' task to perform several
157 * behavioural tests. See the comments above the prvTestMasterTask() prototype
160 static void prvTestSlaveTask( void *pvParameters );
163 * The part of the test that is performed between the 'test master' task and the
164 * 'test slave' task to test the behaviour when the slave blocks on various
165 * event bit combinations.
167 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
170 * The part of the test that uses all the tasks to test the task synchronisation
173 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
176 * Two instances of prvSyncTask() are created. They start by calling
177 * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is
178 * executing the prvSelectiveBitsTestMasterFunction() function. They then loop
179 * to test the task synchronisation (rendezvous) behaviour.
181 static void prvSyncTask( void *pvParameters );
184 * Functions used in a test that blocks two tasks on various different bits
185 * within an event group - then sets each bit in turn and checks that the
186 * correct tasks unblock at the correct times.
188 static BaseType_t prvSelectiveBitsTestMasterFunction( void );
189 static void prvSelectiveBitsTestSlaveFunction( void );
191 /*-----------------------------------------------------------*/
193 /* Variables that are incremented by the tasks on each cycle provided no errors
194 have been found. Used to detect an error or stall in the test cycling. */
195 static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;
197 /* The event group used by all the task based tests. */
198 static EventGroupHandle_t xEventGroup = NULL;
200 /* The event group used by the interrupt based tests. */
201 static EventGroupHandle_t xISREventGroup = NULL;
203 /* Handles to the tasks that only take part in the synchronisation calls. */
204 static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;
206 /*-----------------------------------------------------------*/
208 void vStartEventGroupTasks( void )
210 TaskHandle_t xTestSlaveTaskHandle;
213 * This file contains fairly comprehensive checks on the behaviour of event
214 * groups. It is not intended to be a user friendly demonstration of the
217 * NOTE: The tests implemented in this file are informal 'sanity' tests
218 * only and are not part of the module tests that make use of the
219 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
221 * Create the test tasks as described at the top of this file.
223 xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );
224 xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );
225 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );
226 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );
228 /* If the last task was created then the others will have been too. */
229 configASSERT( xSyncTask2 );
231 /* Create the event group used by the ISR tests. The event group used by
232 the tasks is created by the tasks themselves. */
233 xISREventGroup = xEventGroupCreate();
234 configASSERT( xISREventGroup );
236 /*-----------------------------------------------------------*/
238 static void prvTestMasterTask( void *pvParameters )
242 /* The handle to the slave task is passed in as the task parameter. */
243 TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;
245 /* Avoid compiler warnings. */
246 ( void ) pvParameters;
248 /* Create the event group used by the tasks ready for the initial tests. */
249 xEventGroup = xEventGroupCreate();
250 configASSERT( xEventGroup );
252 /* Perform the tests that block two tasks on different combinations of bits,
253 then set each bit in turn and check the correct tasks unblock at the correct
255 xError = prvSelectiveBitsTestMasterFunction();
259 /* Recreate the event group ready for the next cycle. */
260 xEventGroup = xEventGroupCreate();
261 configASSERT( xEventGroup );
263 /* Perform the tests that check the behaviour when a single task is
264 blocked on various combinations of event bits. */
265 xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );
267 /* Perform the task synchronisation tests. */
268 xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );
270 /* Delete the event group. */
271 vEventGroupDelete( xEventGroup );
273 /* Now all the other tasks should have completed and suspended
274 themselves ready for the next go around the loop. */
275 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
280 if( eTaskGetState( xSyncTask1 ) != eSuspended )
285 if( eTaskGetState( xSyncTask2 ) != eSuspended )
290 /* Only increment the cycle variable if no errors have been detected. */
291 if( xError == pdFALSE )
293 ulTestMasterCycles++;
296 configASSERT( xError == pdFALSE );
299 /*-----------------------------------------------------------*/
301 static void prvSyncTask( void *pvParameters )
303 EventBits_t uxSynchronisationBit, uxReturned;
305 /* A few tests that check the behaviour when two tasks are blocked on
306 various different bits within an event group are performed before this task
307 enters its infinite loop to carry out its main demo function. */
308 prvSelectiveBitsTestSlaveFunction();
310 /* The bit to use to indicate this task is at the synchronisation point is
311 passed in as the task parameter. */
312 uxSynchronisationBit = ( EventBits_t ) pvParameters;
316 /* Now this task takes part in a task synchronisation - sometimes known
317 as a 'rendezvous'. Its execution pattern is controlled by the 'test
318 master' task, which is responsible for taking this task out of the
319 Suspended state when it is time to test the synchronisation behaviour.
320 See: http://www.freertos.org/xEventGroupSync.html. */
321 vTaskSuspend( NULL );
323 /* Set the bit that indicates this task is at the synchronisation
324 point. The first time this is done the 'test master' task has a lower
325 priority than this task so this task will get to the sync point before
326 the set bits task. */
327 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
328 uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */
329 ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */
330 portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */
332 /* A max delay was used, so this task should only exit the above
333 function call when the sync condition is met. Check this is the
335 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
337 /* Remove compiler warning if configASSERT() is not defined. */
340 /* Wait until the 'test master' task unsuspends this task again. */
341 vTaskSuspend( NULL );
343 /* Set the bit that indicates this task is at the synchronisation
344 point again. This time the 'test master' task has a higher priority
345 than this task so will get to the sync point before this task. */
346 uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );
348 /* Again a max delay was used, so this task should only exit the above
349 function call when the sync condition is met. Check this is the
351 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
353 /* Block on the event group again. This time the event group is going
354 to be deleted while this task is blocked on it so it is expected that 0
356 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
357 configASSERT( uxReturned == 0 );
360 /*-----------------------------------------------------------*/
362 static void prvTestSlaveTask( void *pvParameters )
364 EventBits_t uxReturned;
365 BaseType_t xError = pdFALSE;
367 /* Avoid compiler warnings. */
368 ( void ) pvParameters;
372 /**********************************************************************
373 * Part 1: This section is the counterpart to the
374 * prvBitCombinationTestMasterFunction() function which is called by the
376 ***********************************************************************
378 This task is controller by the 'test master' task (which is
379 implemented by prvTestMasterTask()). Suspend until resumed by the
380 'test master' task. */
381 vTaskSuspend( NULL );
383 /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get
384 set. Clear the bit on exit. */
385 uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */
386 ebBIT_1, /* The bit to wait for. */
387 pdTRUE, /* Clear the bit on exit. */
388 pdTRUE, /* Wait for all the bits (only one in this case anyway). */
389 portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */
391 /* The 'test master' task set all the bits defined by ebCOMBINED_BITS,
392 only one of which was being waited for by this task. The return value
393 shows the state of the event bits when the task was unblocked, however
394 because the task was waiting for ebBIT_1 and 'clear on exit' was set to
395 the current state of the event bits will have ebBIT_1 clear. */
396 if( uxReturned != ebCOMBINED_BITS )
401 /* Now call xEventGroupWaitBits() again, this time waiting for all the
402 bits in ebCOMBINED_BITS to be set. This call should block until the
403 'test master' task sets ebBIT_1 - which was the bit cleared in the call
404 to xEventGroupWaitBits() above. */
405 uxReturned = xEventGroupWaitBits( xEventGroup,
406 ebCOMBINED_BITS, /* The bits being waited on. */
407 pdFALSE, /* Don't clear the bits on exit. */
408 pdTRUE, /* All the bits must be set to unblock. */
411 /* Were all the bits set? */
412 if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )
417 /* Suspend again to wait for the 'test master' task. */
418 vTaskSuspend( NULL );
420 /* Now call xEventGroupWaitBits() again, again waiting for all the bits
421 in ebCOMBINED_BITS to be set, but this time clearing the bits when the
422 task is unblocked. */
423 uxReturned = xEventGroupWaitBits( xEventGroup,
424 ebCOMBINED_BITS, /* The bits being waited on. */
425 pdTRUE, /* Clear the bits on exit. */
426 pdTRUE, /* All the bits must be set to unblock. */
429 /* The 'test master' task set all the bits in the event group, so that
430 is the value that should have been returned. The bits defined by
431 ebCOMBINED_BITS will have been clear again in the current value though
432 as 'clear on exit' was set to pdTRUE. */
433 if( uxReturned != ebALL_BITS )
442 /**********************************************************************
443 * Part 2: This section is the counterpart to the
444 * prvPerformTaskSyncTests() function which is called by the
446 ***********************************************************************
449 Once again wait for the 'test master' task to unsuspend this task
450 when it is time for the next test. */
451 vTaskSuspend( NULL );
453 /* Now peform a synchronisation with all the other tasks. At this point
454 the 'test master' task has the lowest priority so will get to the sync
455 point after all the other synchronising tasks. */
456 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */
457 ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */
458 ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */
459 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */
461 /* A sync with a max delay should only exit when all the synchronisation
463 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
468 /* ...but now the synchronisation bits should be clear again. Read back
469 the current value of the bits within the event group to check that is
470 the case. Setting the bits to zero will return the bits previous value
471 then leave all the bits clear. */
472 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
477 /* Check the bits are indeed 0 now by simply reading then. */
478 if( xEventGroupGetBits( xEventGroup ) != 0 )
483 if( xError == pdFALSE )
485 /* This task is still cycling without finding an error. */
489 vTaskSuspend( NULL );
491 /* This time sync when the 'test master' task has the highest priority
492 at the point where it sets its sync bit - so this time the 'test master'
493 task will get to the sync point before this task. */
494 uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
496 /* A sync with a max delay should only exit when all the synchronisation
498 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
503 /* ...but now the sync bits should be clear again. */
504 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
509 /* Block on the event group again. This time the event group is going
510 to be deleted while this task is blocked on it, so it is expected that 0
512 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
514 if( uxReturned != 0 )
519 if( xError == pdFALSE )
521 /* This task is still cycling without finding an error. */
525 configASSERT( xError == pdFALSE );
528 /*-----------------------------------------------------------*/
530 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
534 /* The three tasks that take part in the synchronisation (rendezvous) are
535 expected to be in the suspended state at the start of the test. */
536 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
541 if( eTaskGetState( xSyncTask1 ) != eSuspended )
546 if( eTaskGetState( xSyncTask2 ) != eSuspended )
551 /* Try a synch with no other tasks involved. First set all the bits other
552 than this task's bit. */
553 xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
555 /* Then wait on just one bit - the bit that is being set. */
556 uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
557 ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
558 ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */
559 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
561 /* A sync with a max delay should only exit when all the synchronise
562 bits are set...check that is the case. In this case there is only one
564 if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )
569 /* ...but now the sync bits should be clear again, leaving all the other
570 bits set (as only one bit was being waited for). */
571 if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )
576 /* Clear all the bits to zero again. */
577 xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
578 if( xEventGroupGetBits( xEventGroup ) != 0 )
583 /* Unsuspend the other tasks then check they have executed up to the
584 synchronisation point. */
585 vTaskResume( xTestSlaveTaskHandle );
586 vTaskResume( xSyncTask1 );
587 vTaskResume( xSyncTask2 );
589 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
594 if( eTaskGetState( xSyncTask1 ) != eBlocked )
599 if( eTaskGetState( xSyncTask2 ) != eBlocked )
604 /* Set this task's sync bit. */
605 uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
606 ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
607 ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */
608 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
610 /* A sync with a max delay should only exit when all the synchronise
611 bits are set...check that is the case. */
612 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
617 /* ...but now the sync bits should be clear again. */
618 if( xEventGroupGetBits( xEventGroup ) != 0 )
624 /* The other tasks should now all be suspended again, ready for the next
626 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
631 if( eTaskGetState( xSyncTask1 ) != eSuspended )
636 if( eTaskGetState( xSyncTask2 ) != eSuspended )
642 /* Sync again - but this time set the last necessary bit as the
643 highest priority task, rather than the lowest priority task. Unsuspend
644 the other tasks then check they have executed up to the synchronisation
646 vTaskResume( xTestSlaveTaskHandle );
647 vTaskResume( xSyncTask1 );
648 vTaskResume( xSyncTask2 );
650 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
655 if( eTaskGetState( xSyncTask1 ) != eBlocked )
660 if( eTaskGetState( xSyncTask2 ) != eBlocked )
665 /* Raise the priority of this task above that of the other tasks. */
666 vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );
668 /* Set this task's sync bit. */
669 uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
671 /* A sync with a max delay should only exit when all the synchronisation
673 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
678 /* ...but now the sync bits should be clear again. */
679 if( xEventGroupGetBits( xEventGroup ) != 0 )
685 /* The other tasks should now all be in the ready state again, but not
686 executed yet as this task still has a higher relative priority. */
687 if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )
692 if( eTaskGetState( xSyncTask1 ) != eReady )
697 if( eTaskGetState( xSyncTask2 ) != eReady )
703 /* Reset the priority of this task back to its original value. */
704 vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );
706 /* Now all the other tasks should have reblocked on the event bits
707 to test the behaviour when the event bits are deleted. */
708 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
713 if( eTaskGetState( xSyncTask1 ) != eBlocked )
718 if( eTaskGetState( xSyncTask2 ) != eBlocked )
725 /*-----------------------------------------------------------*/
727 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
731 /* Resume the other task. It will block, pending a single bit from
732 within ebCOMBINED_BITS. */
733 vTaskResume( xTestSlaveTaskHandle );
735 /* Ensure the other task is blocked on the task. */
736 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
741 /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only
742 blocked waiting for one of them. */
743 xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );
745 /* The 'test slave' task should now have executed, clearing ebBIT_1 (the
746 bit it was blocked on), then re-entered the Blocked state to wait for
747 all the other bits in ebCOMBINED_BITS to be set again. First check
749 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
751 if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
756 /* Ensure the other task is still in the blocked state. */
757 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
762 /* Set all the bits other than ebBIT_1 - which is the bit that must be
763 set before the other task unblocks. */
764 xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );
766 /* Ensure all the expected bits are still set. */
767 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
769 if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
774 /* Ensure the other task is still in the blocked state. */
775 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
780 /* Now also set ebBIT_1, which should unblock the other task, which will
781 then suspend itself. */
782 xEventGroupSetBits( xEventGroup, ebBIT_1 );
784 /* Ensure the other task is suspended. */
785 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
790 /* The other task should not have cleared the bits - so all the bits
791 should still be set. */
792 if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )
797 /* Clear ebBIT_1 again. */
798 if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )
803 /* Resume the other task - which will wait on all the ebCOMBINED_BITS
804 again - this time clearing the bits when it is unblocked. */
805 vTaskResume( xTestSlaveTaskHandle );
807 /* Ensure the other task is blocked once again. */
808 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
813 /* Set the bit the other task is waiting for. */
814 xEventGroupSetBits( xEventGroup, ebBIT_1 );
816 /* Ensure the other task is suspended once again. */
817 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
822 /* The other task should have cleared the bits in ebCOMBINED_BITS.
823 Clear the remaining bits. */
824 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
826 if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
831 /* Clear all bits ready for the sync with the other three tasks. The
832 value returned is the value prior to the bits being cleared. */
833 if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
838 /* The bits should be clear now. */
839 if( xEventGroupGetBits( xEventGroup ) != 0x00 )
846 /*-----------------------------------------------------------*/
848 static void prvSelectiveBitsTestSlaveFunction( void )
850 EventBits_t uxPendBits, uxReturned;
852 /* Used in a test that blocks two tasks on various different bits within an
853 event group - then sets each bit in turn and checks that the correct tasks
854 unblock at the correct times.
856 This function is called by two different tasks - each of which will use a
857 different bit. Check the task handle to see which task the function was
859 if( xTaskGetCurrentTaskHandle() == xSyncTask1 )
861 uxPendBits = ebSELECTIVE_BITS_1;
865 uxPendBits = ebSELECTIVE_BITS_2;
870 /* Wait until it is time to perform the next cycle of the test. The
871 task is unsuspended by the tests implemented in the
872 prvSelectiveBitsTestMasterFunction() function. */
873 vTaskSuspend( NULL );
874 uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );
876 if( uxReturned == ( EventBits_t ) 0 )
882 /*-----------------------------------------------------------*/
884 static BaseType_t prvSelectiveBitsTestMasterFunction( void )
886 BaseType_t xError = pdFALSE;
889 /* Used in a test that blocks two tasks on various different bits within an
890 event group - then sets each bit in turn and checks that the correct tasks
891 unblock at the correct times. The two other tasks (xSyncTask1 and
892 xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in
895 Both other tasks should start in the suspended state. */
896 if( eTaskGetState( xSyncTask1 ) != eSuspended )
901 if( eTaskGetState( xSyncTask2 ) != eSuspended )
906 /* Test each bit in the byte individually. */
907 for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
909 /* Resume both tasks. */
910 vTaskResume( xSyncTask1 );
911 vTaskResume( xSyncTask2 );
913 /* Now both tasks should be blocked on the event group. */
914 if( eTaskGetState( xSyncTask1 ) != eBlocked )
919 if( eTaskGetState( xSyncTask2 ) != eBlocked )
925 xEventGroupSetBits( xEventGroup, uxBit );
927 /* Is the bit set in the first set of selective bits? If so the first
928 sync task should have unblocked and returned to the suspended state. */
929 if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
931 /* Task should not have unblocked. */
932 if( eTaskGetState( xSyncTask1 ) != eBlocked )
939 /* Task should have unblocked and returned to the suspended state. */
940 if( eTaskGetState( xSyncTask1 ) != eSuspended )
946 /* Same checks for the second sync task. */
947 if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
949 /* Task should not have unblocked. */
950 if( eTaskGetState( xSyncTask2 ) != eBlocked )
957 /* Task should have unblocked and returned to the suspended state. */
958 if( eTaskGetState( xSyncTask2 ) != eSuspended )
965 /* Ensure both tasks are blocked on the event group again, then delete the
966 event group so the other tasks leave this portion of the test. */
967 vTaskResume( xSyncTask1 );
968 vTaskResume( xSyncTask2 );
970 /* Deleting the event group is the signal that the two other tasks should
971 leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main
972 part of their functionality. */
973 vEventGroupDelete( xEventGroup );
977 /*-----------------------------------------------------------*/
979 void vPeriodicEventGroupsProcessing( void )
981 static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;
982 const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;
983 const EventBits_t uxBitsToSet = 0x12U;
984 EventBits_t uxReturned;
985 BaseType_t xMessagePosted;
987 /* Called periodically from the tick hook to exercise the "FromISR"
992 if( xCallCount == xSetBitCount )
994 /* All the event bits should start clear. */
995 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
996 if( uxReturned != 0x00 )
998 xISRTestError = pdTRUE;
1002 /* Set the bits. This is called from the tick hook so it is not
1003 necessary to use the last parameter to ensure a context switch
1004 occurs immediately. */
1005 xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );
1006 if( xMessagePosted != pdPASS )
1008 xISRTestError = pdTRUE;
1012 else if( xCallCount == xGetBitsCount )
1014 /* Check the bits were set as expected. */
1015 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
1016 if( uxReturned != uxBitsToSet )
1018 xISRTestError = pdTRUE;
1021 else if( xCallCount == xClearBitsCount )
1023 /* Clear the bits again. */
1024 uxReturned = ( EventBits_t ) xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );
1026 /* Check the message was posted. */
1027 if( uxReturned != pdPASS )
1029 xISRTestError = pdTRUE;
1032 /* Go back to the start. */
1035 /* If no errors have been detected then increment the count of test
1037 if( xISRTestError == pdFALSE )
1044 /* Nothing else to do. */
1048 /*-----------------------------------------------------------*/
1049 /* This is called to check that all the created tasks are still running. */
1050 BaseType_t xAreEventGroupTasksStillRunning( void )
1052 static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;
1053 BaseType_t xStatus = pdPASS;
1055 /* Check the tasks are still cycling without finding any errors. */
1056 if( ulPreviousSetBitCycles == ulTestMasterCycles )
1060 ulPreviousSetBitCycles = ulTestMasterCycles;
1062 if( ulPreviousWaitBitCycles == ulTestSlaveCycles )
1066 ulPreviousWaitBitCycles = ulTestSlaveCycles;
1068 if( ulPreviousISRCycles == ulISRCycles )
1072 ulPreviousISRCycles = ulISRCycles;