2 FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 ***************************************************************************
\r
9 * FreeRTOS provides completely free yet professionally developed, *
\r
10 * robust, strictly quality controlled, supported, and cross *
\r
11 * platform software that has become a de facto standard. *
\r
13 * Help yourself get started quickly and support the FreeRTOS *
\r
14 * project by purchasing a FreeRTOS tutorial book, reference *
\r
15 * manual, or both from: http://www.FreeRTOS.org/Documentation *
\r
19 ***************************************************************************
\r
21 This file is part of the FreeRTOS distribution.
\r
23 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
24 the terms of the GNU General Public License (version 2) as published by the
\r
25 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
\r
27 >>! NOTE: The modification to the GPL is included to allow you to distribute
\r
28 >>! a combined work that includes FreeRTOS without being obliged to provide
\r
29 >>! the source code for proprietary components outside of the FreeRTOS
\r
32 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
33 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
34 FOR A PARTICULAR PURPOSE. Full license text is available from the following
\r
35 link: http://www.freertos.org/a00114.html
\r
39 ***************************************************************************
\r
41 * Having a problem? Start by reading the FAQ "My application does *
\r
42 * not run, what could be wrong?" *
\r
44 * http://www.FreeRTOS.org/FAQHelp.html *
\r
46 ***************************************************************************
\r
48 http://www.FreeRTOS.org - Documentation, books, training, latest versions,
\r
49 license and Real Time Engineers Ltd. contact details.
\r
51 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
52 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
53 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
55 http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
\r
56 Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
57 licenses offer ticketed support, indemnification and middleware.
\r
59 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
60 engineered and independently SIL3 certified version for use in safety and
\r
61 mission critical applications that require provable dependability.
\r
69 * This file contains fairly comprehensive checks on the behaviour of event
\r
70 * groups. It is not intended to be a user friendly demonstration of the event
\r
76 /* Scheduler include files. */
\r
77 #include "FreeRTOS.h"
\r
79 #include "event_groups.h"
\r
81 /* Priorities used by the tasks. */
\r
82 #define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
83 #define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
85 /* Generic bit definitions. */
\r
86 #define ebBIT_0 ( 0x01UL )
\r
87 #define ebBIT_1 ( 0x02UL )
\r
88 #define ebBIT_2 ( 0x04UL )
\r
89 #define ebBIT_3 ( 0x08UL )
\r
90 #define ebBIT_4 ( 0x10UL )
\r
91 #define ebBIT_5 ( 0x20UL )
\r
92 #define ebBIT_6 ( 0x40UL )
\r
93 #define ebBIT_7 ( 0x80UL )
\r
95 /* Combinations of bits used in the tests. */
\r
96 #define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )
\r
97 #define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )
\r
99 /* Associate a bit to each task. These bits are used to identify all the tasks
\r
100 that synchronise with the xEventGroupSync() function. */
\r
101 #define ebSET_BIT_TASK_SYNC_BIT ebBIT_0
\r
102 #define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1
\r
103 #define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2
\r
104 #define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3
\r
105 #define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT )
\r
107 /* A block time of zero simply means "don't block". */
\r
108 #define ebDONT_BLOCK ( 0 )
\r
111 #define ebSHORT_DELAY ( 5 / portTICK_RATE_MS )
\r
113 /* Used in the selective bits test which checks no, one or both tasks blocked on
\r
114 event bits in a group are unblocked as appropriate as different bits get set. */
\r
115 #define ebSELECTIVE_BITS_1 0x03
\r
116 #define ebSELECTIVE_BITS_2 0x05
\r
118 /*-----------------------------------------------------------*/
\r
121 * The primary task that manages and controls all the behavioural tests.
\r
123 static void prvSetBitsTask( void *pvParameters );
\r
126 * The task that participates in most of the non 'single task' tests performed
\r
127 * by prvSetBitsTask().
\r
129 static void prvWaitBitsTask( void *pvParameters );
\r
132 * Two instances of prvSyncTask() are created. Their only purpose is to
\r
133 * participate in synchronisations and test the behaviour when an event group on
\r
134 * which they are blocked is deleted.
\r
136 static void prvSyncTask( void *pvParameters );
\r
139 * Functions used in a test that blocks two tasks on various different bits
\r
140 * within an event group - then sets each bit in turn and checks that the
\r
141 * correct tasks unblock at the correct times.
\r
143 static portBASE_TYPE prvTestSelectiveBits( void );
\r
144 static void prvPreSyncSelectiveWakeTest( void );
\r
146 /*-----------------------------------------------------------*/
\r
148 /* Variables that are incremented by the tasks on each cycle provided no errors
\r
149 have been found. Used to detect an error or stall in the test cycling. */
\r
150 static volatile unsigned long ulSetBitCycles = 0, ulWaitBitCycles = 0;
\r
152 /* The event group used by all the tests. */
\r
153 static EventGroupHandle_t xEventBits = NULL;
\r
155 /* Handles to the tasks that only take part in the synchronisation calls. */
\r
156 static xTaskHandle xSyncTask1 = NULL, xSyncTask2 = NULL;
\r
158 /*-----------------------------------------------------------*/
\r
160 void vStartEventGroupTasks( void )
\r
162 xTaskHandle xWaitBitsTaskHandle;
\r
165 * This file contains fairly comprehensive checks on the behaviour of event
\r
166 * groups. It is not intended to be a user friendly demonstration of the
\r
167 * event groups API.
\r
170 xTaskCreate( prvWaitBitsTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xWaitBitsTaskHandle );
\r
171 xTaskCreate( prvSetBitsTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xWaitBitsTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );
\r
172 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );
\r
173 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );
\r
175 /* If the last task was created then the others will have been too. */
\r
176 configASSERT( xSyncTask2 );
\r
178 /*-----------------------------------------------------------*/
\r
180 static void prvSyncTask( void *pvParameters )
\r
182 EventBits_t uxSynchronisationBit, uxReturned;
\r
184 /* The bit to use to indicate this task is at the synchronisation point is
\r
185 passed in as the task parameter. */
\r
186 uxSynchronisationBit = ( EventBits_t ) pvParameters;
\r
188 /* A few tests are performed before entering the main demo loop. */
\r
189 prvPreSyncSelectiveWakeTest();
\r
193 /* Wait until the 'set bit' task unsuspends this task. */
\r
194 vTaskSuspend( NULL );
\r
196 /* Set the bit that indicates this task is at the synchronisation
\r
197 point. The first time this is done the 'set bit' task has a lower
\r
198 priority than this task. */
\r
199 uxReturned = xEventGroupSync( xEventBits, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );
\r
200 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
202 /* Wait until the 'set bit' task unsuspends this task again. */
\r
203 vTaskSuspend( NULL );
\r
205 /* Set the bit that indicates this task is at the synchronisation
\r
206 point again. This time the 'set bit' task has a higher priority than
\r
208 uxReturned = xEventGroupSync( xEventBits, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );
\r
209 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
211 /* Block on the event group again. This time the event group is going
\r
212 to be deleted, so 0 should be returned. */
\r
213 uxReturned = xEventGroupWaitBits( xEventBits, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
214 configASSERT( uxReturned == 0 );
\r
217 /*-----------------------------------------------------------*/
\r
219 static void prvWaitBitsTask( void *pvParameters )
\r
221 EventBits_t uxReturned;
\r
222 portBASE_TYPE xError = pdFALSE;
\r
224 /* Avoid compiler warnings. */
\r
225 ( void ) pvParameters;
\r
229 /* This task is controller by the prvSetBitsTask(). Suspend until resumed
\r
230 by prvSetBitsTask(). */
\r
231 vTaskSuspend( NULL );
\r
233 /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get
\r
234 set. Clear the bit on exit. */
\r
235 uxReturned = xEventGroupWaitBits( xEventBits, /* The event bits being queried. */
\r
236 ebBIT_1, /* The bit to wait for. */
\r
237 pdTRUE, /* Clear the bit on exit. */
\r
238 pdTRUE, /* Wait for all the bits (only one in this case anyway. */
\r
241 /* Should unblock after the 'set bit' task has set all the bits in the
\r
242 ebCOMBINED_BITS constant, therefore ebCOMBINED_BITS is what should have
\r
244 if( uxReturned != ebCOMBINED_BITS )
\r
249 /* Now call xEventGroupWaitBits() again, this time waiting for all the bits
\r
250 in ebCOMBINED_BITS to be set. This call should block until the 'set
\r
251 bits' task sets ebBIT_1 - which was the bit cleared in the call to
\r
252 xEventGroupWaitBits() above. */
\r
253 uxReturned = xEventGroupWaitBits( xEventBits,
\r
254 ebCOMBINED_BITS, /* The bits being waited on. */
\r
255 pdFALSE, /* Don't clear the bits on exit. */
\r
256 pdTRUE, /* All the bits must be set to unblock. */
\r
259 /* Were all the bits set? */
\r
260 if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )
\r
265 /* Suspend again to wait for the 'set bit' task. */
\r
266 vTaskSuspend( NULL );
\r
268 /* Now call xEventGroupWaitBits() again, again waiting for all the bits in
\r
269 ebCOMBINED_BITS to be set, but this time clearing the bits when the task
\r
271 uxReturned = xEventGroupWaitBits( xEventBits,
\r
272 ebCOMBINED_BITS, /* The bits being waited on. */
\r
273 pdTRUE, /* Clear the bits on exit. */
\r
274 pdTRUE, /* All the bits must be set to unblock. */
\r
278 if( uxReturned != ebALL_BITS )
\r
283 vTaskSuspend( NULL );
\r
285 /* Now to synchronise with when 'set bit' task has the lowest
\r
287 uxReturned = xEventGroupSync( xEventBits, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
289 /* A sync with a max delay should only exit when all the synchronisation
\r
291 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
296 /* ...but now the synchronisation bits should be clear again. */
\r
297 if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )
\r
302 if( xError == pdFALSE )
\r
304 /* This task is still cycling without finding an error. */
\r
308 vTaskSuspend( NULL );
\r
310 /* This time sync when the 'set bit' task has the highest priority
\r
311 at the point where it sets its sync bit. */
\r
312 uxReturned = xEventGroupSync( xEventBits, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
314 /* A sync with a max delay should only exit when all the synchronisation
\r
316 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
321 /* ...but now the sync bits should be clear again. */
\r
322 if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )
\r
327 /* Block on the event group again. This time the event group is going
\r
328 to be deleted, so 0 should be returned. */
\r
329 uxReturned = xEventGroupWaitBits( xEventBits, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
331 if( uxReturned != 0 )
\r
336 if( xError == pdFALSE )
\r
338 /* This task is still cycling without finding an error. */
\r
342 configASSERT( xError == pdFALSE );
\r
345 /*-----------------------------------------------------------*/
\r
347 static void prvSetBitsTask( void *pvParameters )
\r
349 EventBits_t uxBits;
\r
350 portBASE_TYPE xError;
\r
352 /* The handle to the other task is passed in as the task parameter. */
\r
353 xTaskHandle xWaitBitsTaskHandle = ( xTaskHandle ) pvParameters;
\r
355 /* Avoid compiler warnings. */
\r
356 ( void ) pvParameters;
\r
358 /* Create the event group ready for the initial tests. */
\r
359 xEventBits = xEventGroupCreate();
\r
360 configASSERT( xEventBits );
\r
362 /* Perform the tests that block two tasks on different combinations of bits,
\r
363 then set each bit in turn and check the correct tasks unblock at the correct
\r
365 xError = prvTestSelectiveBits();
\r
369 /* Recreate the event group ready for the next cycle. */
\r
370 xEventBits = xEventGroupCreate();
\r
371 configASSERT( xEventBits );
\r
373 /* Resume the other task. It will block, pending a single bit from
\r
374 within ebCOMBINED_BITS. */
\r
375 vTaskResume( xWaitBitsTaskHandle );
\r
377 /* Ensure the other task is blocked on the task. */
\r
378 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
383 /* Set all the bits in ebCOMBINED_BITS - the 'wait bits' task is only
\r
384 blocked waiting for one of them. */
\r
385 xEventGroupSetBits( xEventBits, ebCOMBINED_BITS );
\r
387 /* The 'wait bits' task should now have executed, clearing ebBIT_1 (the
\r
388 bit it was blocked on), then re-entered the Blocked state to wait for
\r
389 all the other bits in ebCOMBINED_BITS to be set again. First check
\r
390 ebBIT_1 is clear. */
\r
391 uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
393 if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
\r
398 /* Ensure the other task is still in the blocked state. */
\r
399 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
404 /* Set all the bits other than ebBIT_1 - which is the bit that must be
\r
405 set before the other task unblocks. */
\r
406 xEventGroupSetBits( xEventBits, ebALL_BITS & ~ebBIT_1 );
\r
408 /* Ensure all the expected bits are still set. */
\r
409 uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
411 if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
\r
416 /* Ensure the other task is still in the blocked state. */
\r
417 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
422 /* Now also set ebBIT_1, which should unblock the other task, which will
\r
423 then suspend itself. */
\r
424 xEventGroupSetBits( xEventBits, ebBIT_1 );
\r
426 /* Ensure the other task is suspended. */
\r
427 if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )
\r
432 /* The other task should not have cleared the bits - so all the bits
\r
433 should still be set. */
\r
434 if( xEventGroupSetBits( xEventBits, 0x00 ) != ebALL_BITS )
\r
439 /* Clear ebBIT_1 again. */
\r
440 if( xEventGroupClearBits( xEventBits, ebBIT_1 ) != ebALL_BITS )
\r
445 /* Resume the other task - which will wait on all the ebCOMBINED_BITS
\r
446 again - this time clearing the bits when it is unblocked. */
\r
447 vTaskResume( xWaitBitsTaskHandle );
\r
449 /* Ensure the other task is blocked once again. */
\r
450 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
455 /* Set the bit the other task is waiting for. */
\r
456 xEventGroupSetBits( xEventBits, ebBIT_1 );
\r
458 /* Ensure the other task is suspended once again. */
\r
459 if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )
\r
464 /* The other task should have cleared the bits in ebCOMBINED_BITS.
\r
465 Clear the remaining bits. */
\r
466 uxBits = xEventGroupWaitBits( xEventBits, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
468 if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
473 /* Clear all bits ready for the sync with the other three tasks. The
\r
474 value returned is the value prior to the bits being cleared. */
\r
475 if( xEventGroupClearBits( xEventBits, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
480 /* The bits should be clear now. */
\r
481 if( xEventGroupGetBits( xEventBits ) != 0x00 )
\r
486 /* Check the other three tasks are suspended. */
\r
487 if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )
\r
492 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
497 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
502 /* Unsuspend the other tasks then check they have executed up to the
\r
503 synchronisation point. */
\r
504 vTaskResume( xWaitBitsTaskHandle );
\r
505 vTaskResume( xSyncTask1 );
\r
506 vTaskResume( xSyncTask2 );
\r
508 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
513 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
518 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
523 /* Set this task's sync bit. */
\r
524 uxBits = xEventGroupSync( xEventBits, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
526 /* A sync with a max delay should only exit when all the synchronise
\r
528 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
533 /* ...but now the sync bits should be clear again. */
\r
534 if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )
\r
540 /* The other tasks should now all be suspended again, ready for the next
\r
541 synchronisation. */
\r
542 if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )
\r
547 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
552 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
558 /* Sync again - but this time set the last necessary bit as the
\r
559 highest priority task, rather than the lowest priority task. Unsuspend
\r
560 the other tasks then check they have executed up to the synchronisation
\r
562 vTaskResume( xWaitBitsTaskHandle );
\r
563 vTaskResume( xSyncTask1 );
\r
564 vTaskResume( xSyncTask2 );
\r
566 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
571 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
576 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
581 /* Raise the priority of this task above that of the other tasks. */
\r
582 vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );
\r
584 /* Set this task's sync bit. */
\r
585 uxBits = xEventGroupSync( xEventBits, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
587 /* A sync with a max delay should only exit when all the synchronisation
\r
589 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
594 /* ...but now the sync bits should be clear again. */
\r
595 if( xEventGroupSetBits( xEventBits, 0x00 ) != 0 )
\r
601 /* The other tasks should now all be in the ready state again, but not
\r
602 executed yet as this task still has a higher relative priority. */
\r
603 if( eTaskGetState( xWaitBitsTaskHandle ) != eReady )
\r
608 if( eTaskGetState( xSyncTask1 ) != eReady )
\r
613 if( eTaskGetState( xSyncTask2 ) != eReady )
\r
619 /* Reset the priority of this task back to its original value. */
\r
620 vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );
\r
622 /* Now all the other tasks should have reblocked on the event bits
\r
623 to test the behaviour when the event bits are deleted. */
\r
624 if( eTaskGetState( xWaitBitsTaskHandle ) != eBlocked )
\r
629 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
634 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
639 /* Delete the event group. */
\r
640 vEventGroupDelete( xEventBits );
\r
642 /* Now all the other tasks should have completed and suspended
\r
643 themselves ready for the next go around the loop. */
\r
644 if( eTaskGetState( xWaitBitsTaskHandle ) != eSuspended )
\r
649 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
654 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
660 if( xError == pdFALSE )
\r
665 configASSERT( xError == pdFALSE );
\r
668 /*-----------------------------------------------------------*/
\r
670 static void prvPreSyncSelectiveWakeTest( void )
\r
672 EventBits_t uxPendBits, uxReturned;
\r
674 if( xTaskGetCurrentTaskHandle() == xSyncTask1 )
\r
676 uxPendBits = ebSELECTIVE_BITS_1;
\r
680 uxPendBits = ebSELECTIVE_BITS_2;
\r
685 vTaskSuspend( NULL );
\r
686 uxReturned = xEventGroupWaitBits( xEventBits, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );
\r
688 if( uxReturned == ( EventBits_t ) 0 )
\r
694 /*-----------------------------------------------------------*/
\r
696 static portBASE_TYPE prvTestSelectiveBits( void )
\r
698 portBASE_TYPE xError = pdFALSE;
\r
701 /* Both tasks should start in the suspended state. */
\r
702 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
707 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
712 /* Test each bit in the byte individually. */
\r
713 for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
\r
715 /* Resume both tasks. */
\r
716 vTaskResume( xSyncTask1 );
\r
717 vTaskResume( xSyncTask2 );
\r
719 /* Now both tasks should be blocked on the event group. */
\r
720 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
725 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
731 xEventGroupSetBits( xEventBits, uxBit );
\r
733 /* Is the bit set in the first set of selective bits? If so the first
\r
734 sync task should have unblocked and returned to the suspended state. */
\r
735 if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
\r
737 /* Task should not have unblocked. */
\r
738 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
745 /* Task should have unblocked and returned to the suspended state. */
\r
746 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
752 /* Same checks for the second sync task. */
\r
753 if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
\r
755 /* Task should not have unblocked. */
\r
756 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
763 /* Task should have unblocked and returned to the suspended state. */
\r
764 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
771 /* Ensure both tasks are blocked on the event group again, then delete the
\r
772 event group so the other tasks leave this portion of the test. */
\r
773 vTaskResume( xSyncTask1 );
\r
774 vTaskResume( xSyncTask2 );
\r
776 vEventGroupDelete( xEventBits );
\r
780 /*-----------------------------------------------------------*/
\r
782 /* This is called to check that all the created tasks are still running. */
\r
783 portBASE_TYPE xAreEventGroupTasksStillRunning( void )
\r
785 static unsigned long ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0;
\r
786 portBASE_TYPE xStatus = pdPASS;
\r
788 /* Check the tasks are still cycling without finding any errors. */
\r
789 if( ulPreviousSetBitCycles == ulSetBitCycles )
\r
793 ulPreviousSetBitCycles = ulSetBitCycles;
\r
795 if( ulPreviousWaitBitCycles == ulWaitBitCycles )
\r
799 ulPreviousWaitBitCycles = ulWaitBitCycles;
\r