2 FreeRTOS V8.0.0:rc1 - Copyright (C) 2014 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
\r
73 * NOTE: The tests implemented in this file are informal 'sanity' tests
\r
74 * only and are not part of the module tests that make use of the
\r
75 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
79 /* Scheduler include files. */
\r
80 #include "FreeRTOS.h"
\r
82 #include "event_groups.h"
\r
84 /* Demo app includes. */
\r
85 #include "EventGroupsDemo.h"
\r
87 #if( INCLUDE_eTaskGetState != 1 )
\r
88 #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.
\r
91 /* Priorities used by the tasks. */
\r
92 #define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
93 #define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
95 /* Generic bit definitions. */
\r
96 #define ebBIT_0 ( 0x01UL )
\r
97 #define ebBIT_1 ( 0x02UL )
\r
98 #define ebBIT_2 ( 0x04UL )
\r
99 #define ebBIT_3 ( 0x08UL )
\r
100 #define ebBIT_4 ( 0x10UL )
\r
101 #define ebBIT_5 ( 0x20UL )
\r
102 #define ebBIT_6 ( 0x40UL )
\r
103 #define ebBIT_7 ( 0x80UL )
\r
105 /* Combinations of bits used in the demo. */
\r
106 #define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )
\r
107 #define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )
\r
109 /* Associate a bit to each task. These bits are used to identify all the tasks
\r
110 that synchronise with the xEventGroupSync() function. */
\r
111 #define ebSET_BIT_TASK_SYNC_BIT ebBIT_0
\r
112 #define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1
\r
113 #define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2
\r
114 #define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3
\r
115 #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
117 /* A block time of zero simply means "don't block". */
\r
118 #define ebDONT_BLOCK ( 0 )
\r
121 #define ebSHORT_DELAY ( 5 / portTICK_PERIOD_MS )
\r
123 /* Used in the selective bits test which checks no, one or both tasks blocked on
\r
124 event bits in a group are unblocked as appropriate as different bits get set. */
\r
125 #define ebSELECTIVE_BITS_1 0x03
\r
126 #define ebSELECTIVE_BITS_2 0x05
\r
128 /*-----------------------------------------------------------*/
\r
131 * NOTE: The tests implemented in this function are informal 'sanity' tests
\r
132 * only and are not part of the module tests that make use of the
\r
133 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
135 * The master test task. This task:
\r
137 * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two
\r
138 * tasks are blocked on different bits in an event group. The counterpart of
\r
139 * this test is implemented by the prvSelectiveBitsTestSlaveFunction()
\r
140 * function (which is called by the two tasks that block on the event group).
\r
142 * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when
\r
143 * just one task is blocked on various combinations of bits within an event
\r
144 * group. The counterpart of this test is implemented within the 'test
\r
147 * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.
\r
149 static void prvTestMasterTask( void *pvParameters );
\r
152 * A helper task that enables the 'test master' task to perform several
\r
153 * behavioural tests. See the comments above the prvTestMasterTask() prototype
\r
156 static void prvTestSlaveTask( void *pvParameters );
\r
159 * The part of the test that is performed between the 'test master' task and the
\r
160 * 'test slave' task to test the behaviour when the slave blocks on various
\r
161 * event bit combinations.
\r
163 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
\r
166 * The part of the test that uses all the tasks to test the task synchronisation
\r
169 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
\r
172 * Two instances of prvSyncTask() are created. They start by calling
\r
173 * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is
\r
174 * executing the prvSelectiveBitsTestMasterFunction() function. They then loop
\r
175 * to test the task synchronisation (rendezvous) behaviour.
\r
177 static void prvSyncTask( void *pvParameters );
\r
180 * Functions used in a test that blocks two tasks on various different bits
\r
181 * within an event group - then sets each bit in turn and checks that the
\r
182 * correct tasks unblock at the correct times.
\r
184 static BaseType_t prvSelectiveBitsTestMasterFunction( void );
\r
185 static void prvSelectiveBitsTestSlaveFunction( void );
\r
187 /*-----------------------------------------------------------*/
\r
189 /* Variables that are incremented by the tasks on each cycle provided no errors
\r
190 have been found. Used to detect an error or stall in the test cycling. */
\r
191 static volatile unsigned long ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;
\r
193 /* The event group used by all the task based tests. */
\r
194 static EventGroupHandle_t xEventGroup = NULL;
\r
196 /* The event group used by the interrupt based tests. */
\r
197 static EventGroupHandle_t xISREventGroup = NULL;
\r
199 /* Handles to the tasks that only take part in the synchronisation calls. */
\r
200 static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;
\r
202 /*-----------------------------------------------------------*/
\r
204 void vStartEventGroupTasks( void )
\r
206 TaskHandle_t xTestSlaveTaskHandle;
\r
209 * This file contains fairly comprehensive checks on the behaviour of event
\r
210 * groups. It is not intended to be a user friendly demonstration of the
\r
211 * event groups API.
\r
213 * NOTE: The tests implemented in this file are informal 'sanity' tests
\r
214 * only and are not part of the module tests that make use of the
\r
215 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
217 * Create the test tasks as described at the top of this file.
\r
219 xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );
\r
220 xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );
\r
221 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );
\r
222 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );
\r
224 /* If the last task was created then the others will have been too. */
\r
225 configASSERT( xSyncTask2 );
\r
227 /* Create the event group used by the ISR tests. The event group used by
\r
228 the tasks is created by the tasks themselves. */
\r
229 xISREventGroup = xEventGroupCreate();
\r
230 configASSERT( xISREventGroup );
\r
232 /*-----------------------------------------------------------*/
\r
234 static void prvTestMasterTask( void *pvParameters )
\r
238 /* The handle to the slave task is passed in as the task parameter. */
\r
239 TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;
\r
241 /* Avoid compiler warnings. */
\r
242 ( void ) pvParameters;
\r
244 /* Create the event group used by the tasks ready for the initial tests. */
\r
245 xEventGroup = xEventGroupCreate();
\r
246 configASSERT( xEventGroup );
\r
248 /* Perform the tests that block two tasks on different combinations of bits,
\r
249 then set each bit in turn and check the correct tasks unblock at the correct
\r
251 xError = prvSelectiveBitsTestMasterFunction();
\r
255 /* Recreate the event group ready for the next cycle. */
\r
256 xEventGroup = xEventGroupCreate();
\r
257 configASSERT( xEventGroup );
\r
259 /* Perform the tests that check the behaviour when a single task is
\r
260 blocked on various combinations of event bits. */
\r
261 xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );
\r
263 /* Perform the task synchronisation tests. */
\r
264 xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );
\r
266 /* Delete the event group. */
\r
267 vEventGroupDelete( xEventGroup );
\r
269 /* Now all the other tasks should have completed and suspended
\r
270 themselves ready for the next go around the loop. */
\r
271 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
276 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
281 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
286 /* Only increment the cycle variable if no errors have been detected. */
\r
287 if( xError == pdFALSE )
\r
289 ulTestMasterCycles++;
\r
292 configASSERT( xError == pdFALSE );
\r
295 /*-----------------------------------------------------------*/
\r
297 static void prvSyncTask( void *pvParameters )
\r
299 EventBits_t uxSynchronisationBit, uxReturned;
\r
301 /* A few tests that check the behaviour when two tasks are blocked on
\r
302 various different bits within an event group are performed before this task
\r
303 enters its infinite loop to carry out its main demo function. */
\r
304 prvSelectiveBitsTestSlaveFunction();
\r
306 /* The bit to use to indicate this task is at the synchronisation point is
\r
307 passed in as the task parameter. */
\r
308 uxSynchronisationBit = ( EventBits_t ) pvParameters;
\r
312 /* Now this task takes part in a task synchronisation - sometimes known
\r
313 as a 'rendezvous'. Its execution pattern is controlled by the 'test
\r
314 master' task, which is responsible for taking this task out of the
\r
315 Suspended state when it is time to test the synchronisation behaviour.
\r
316 See: http://www.freertos.org/xEventGroupSync.html. */
\r
317 vTaskSuspend( NULL );
\r
319 /* Set the bit that indicates this task is at the synchronisation
\r
320 point. The first time this is done the 'test master' task has a lower
\r
321 priority than this task so this task will get to the sync point before
\r
322 the set bits task. */
\r
323 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
\r
324 uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */
\r
325 ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */
\r
326 portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */
\r
328 /* A max delay was used, so this task should only exit the above
\r
329 function call when the sync condition is met. Check this is the
\r
331 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
333 /* Remove compiler warning if configASSERT() is not defined. */
\r
334 ( void ) uxReturned;
\r
336 /* Wait until the 'test master' task unsuspends this task again. */
\r
337 vTaskSuspend( NULL );
\r
339 /* Set the bit that indicates this task is at the synchronisation
\r
340 point again. This time the 'test master' task has a higher priority
\r
341 than this task so will get to the sync point before this task. */
\r
342 uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );
\r
344 /* Again a max delay was used, so this task should only exit the above
\r
345 function call when the sync condition is met. Check this is the
\r
347 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
349 /* Block on the event group again. This time the event group is going
\r
350 to be deleted while this task is blocked on it so it is expected that 0
\r
352 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
353 configASSERT( uxReturned == 0 );
\r
356 /*-----------------------------------------------------------*/
\r
358 static void prvTestSlaveTask( void *pvParameters )
\r
360 EventBits_t uxReturned;
\r
361 BaseType_t xError = pdFALSE;
\r
363 /* Avoid compiler warnings. */
\r
364 ( void ) pvParameters;
\r
368 /**********************************************************************
\r
369 * Part 1: This section is the counterpart to the
\r
370 * prvBitCombinationTestMasterFunction() function which is called by the
\r
371 * test master task.
\r
372 ***********************************************************************
\r
374 This task is controller by the 'test master' task (which is
\r
375 implemented by prvTestMasterTask()). Suspend until resumed by the
\r
376 'test master' task. */
\r
377 vTaskSuspend( NULL );
\r
379 /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get
\r
380 set. Clear the bit on exit. */
\r
381 uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */
\r
382 ebBIT_1, /* The bit to wait for. */
\r
383 pdTRUE, /* Clear the bit on exit. */
\r
384 pdTRUE, /* Wait for all the bits (only one in this case anyway). */
\r
385 portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */
\r
387 /* The 'test master' task set all the bits defined by ebCOMBINED_BITS,
\r
388 only one of which was being waited for by this task. The return value
\r
389 shows the state of the event bits when the task was unblocked, however
\r
390 because the task was waiting for ebBIT_1 and 'clear on exit' was set to
\r
391 the current state of the event bits will have ebBIT_1 clear. */
\r
392 if( uxReturned != ebCOMBINED_BITS )
\r
397 /* Now call xEventGroupWaitBits() again, this time waiting for all the
\r
398 bits in ebCOMBINED_BITS to be set. This call should block until the
\r
399 'test master' task sets ebBIT_1 - which was the bit cleared in the call
\r
400 to xEventGroupWaitBits() above. */
\r
401 uxReturned = xEventGroupWaitBits( xEventGroup,
\r
402 ebCOMBINED_BITS, /* The bits being waited on. */
\r
403 pdFALSE, /* Don't clear the bits on exit. */
\r
404 pdTRUE, /* All the bits must be set to unblock. */
\r
407 /* Were all the bits set? */
\r
408 if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )
\r
413 /* Suspend again to wait for the 'test master' task. */
\r
414 vTaskSuspend( NULL );
\r
416 /* Now call xEventGroupWaitBits() again, again waiting for all the bits
\r
417 in ebCOMBINED_BITS to be set, but this time clearing the bits when the
\r
418 task is unblocked. */
\r
419 uxReturned = xEventGroupWaitBits( xEventGroup,
\r
420 ebCOMBINED_BITS, /* The bits being waited on. */
\r
421 pdTRUE, /* Clear the bits on exit. */
\r
422 pdTRUE, /* All the bits must be set to unblock. */
\r
425 /* The 'test master' task set all the bits in the event group, so that
\r
426 is the value that should have been returned. The bits defined by
\r
427 ebCOMBINED_BITS will have been clear again in the current value though
\r
428 as 'clear on exit' was set to pdTRUE. */
\r
429 if( uxReturned != ebALL_BITS )
\r
438 /**********************************************************************
\r
439 * Part 2: This section is the counterpart to the
\r
440 * prvPerformTaskSyncTests() function which is called by the
\r
441 * test master task.
\r
442 ***********************************************************************
\r
445 Once again wait for the 'test master' task to unsuspend this task
\r
446 when it is time for the next test. */
\r
447 vTaskSuspend( NULL );
\r
449 /* Now peform a synchronisation with all the other tasks. At this point
\r
450 the 'test master' task has the lowest priority so will get to the sync
\r
451 point after all the other synchronising tasks. */
\r
452 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */
\r
453 ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */
\r
454 ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */
\r
455 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */
\r
457 /* A sync with a max delay should only exit when all the synchronisation
\r
459 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
464 /* ...but now the synchronisation bits should be clear again. Read back
\r
465 the current value of the bits within the event group to check that is
\r
466 the case. Setting the bits to zero will return the bits previous value
\r
467 then leave all the bits clear. */
\r
468 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
\r
473 /* Check the bits are indeed 0 now by simply reading then. */
\r
474 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
479 if( xError == pdFALSE )
\r
481 /* This task is still cycling without finding an error. */
\r
482 ulTestSlaveCycles++;
\r
485 vTaskSuspend( NULL );
\r
487 /* This time sync when the 'test master' task has the highest priority
\r
488 at the point where it sets its sync bit - so this time the 'test master'
\r
489 task will get to the sync point before this task. */
\r
490 uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
492 /* A sync with a max delay should only exit when all the synchronisation
\r
494 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
499 /* ...but now the sync bits should be clear again. */
\r
500 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
\r
505 /* Block on the event group again. This time the event group is going
\r
506 to be deleted while this task is blocked on it, so it is expected that 0
\r
507 will be returned. */
\r
508 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
510 if( uxReturned != 0 )
\r
515 if( xError == pdFALSE )
\r
517 /* This task is still cycling without finding an error. */
\r
518 ulTestSlaveCycles++;
\r
521 configASSERT( xError == pdFALSE );
\r
524 /*-----------------------------------------------------------*/
\r
526 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
\r
528 EventBits_t uxBits;
\r
530 /* The three tasks that take part in the synchronisation (rendezvous) are
\r
531 expected to be in the suspended state at the start of the test. */
\r
532 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
537 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
542 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
547 /* Unsuspend the other tasks then check they have executed up to the
\r
548 synchronisation point. */
\r
549 vTaskResume( xTestSlaveTaskHandle );
\r
550 vTaskResume( xSyncTask1 );
\r
551 vTaskResume( xSyncTask2 );
\r
553 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
558 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
563 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
568 /* Set this task's sync bit. */
\r
569 uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
\r
570 ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
\r
571 ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */
\r
572 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
\r
574 /* A sync with a max delay should only exit when all the synchronise
\r
575 bits are set...check that is the case. */
\r
576 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
581 /* ...but now the sync bits should be clear again. */
\r
582 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
588 /* The other tasks should now all be suspended again, ready for the next
\r
589 synchronisation. */
\r
590 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
595 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
600 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
606 /* Sync again - but this time set the last necessary bit as the
\r
607 highest priority task, rather than the lowest priority task. Unsuspend
\r
608 the other tasks then check they have executed up to the synchronisation
\r
610 vTaskResume( xTestSlaveTaskHandle );
\r
611 vTaskResume( xSyncTask1 );
\r
612 vTaskResume( xSyncTask2 );
\r
614 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
619 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
624 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
629 /* Raise the priority of this task above that of the other tasks. */
\r
630 vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );
\r
632 /* Set this task's sync bit. */
\r
633 uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
635 /* A sync with a max delay should only exit when all the synchronisation
\r
637 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
642 /* ...but now the sync bits should be clear again. */
\r
643 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
649 /* The other tasks should now all be in the ready state again, but not
\r
650 executed yet as this task still has a higher relative priority. */
\r
651 if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )
\r
656 if( eTaskGetState( xSyncTask1 ) != eReady )
\r
661 if( eTaskGetState( xSyncTask2 ) != eReady )
\r
667 /* Reset the priority of this task back to its original value. */
\r
668 vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );
\r
670 /* Now all the other tasks should have reblocked on the event bits
\r
671 to test the behaviour when the event bits are deleted. */
\r
672 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
677 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
682 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
689 /*-----------------------------------------------------------*/
\r
691 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
\r
693 EventBits_t uxBits;
\r
695 /* Resume the other task. It will block, pending a single bit from
\r
696 within ebCOMBINED_BITS. */
\r
697 vTaskResume( xTestSlaveTaskHandle );
\r
699 /* Ensure the other task is blocked on the task. */
\r
700 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
705 /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only
\r
706 blocked waiting for one of them. */
\r
707 xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );
\r
709 /* The 'test slave' task should now have executed, clearing ebBIT_1 (the
\r
710 bit it was blocked on), then re-entered the Blocked state to wait for
\r
711 all the other bits in ebCOMBINED_BITS to be set again. First check
\r
712 ebBIT_1 is clear. */
\r
713 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
715 if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
\r
720 /* Ensure the other task is still in the blocked state. */
\r
721 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
726 /* Set all the bits other than ebBIT_1 - which is the bit that must be
\r
727 set before the other task unblocks. */
\r
728 xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );
\r
730 /* Ensure all the expected bits are still set. */
\r
731 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
733 if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
\r
738 /* Ensure the other task is still in the blocked state. */
\r
739 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
744 /* Now also set ebBIT_1, which should unblock the other task, which will
\r
745 then suspend itself. */
\r
746 xEventGroupSetBits( xEventGroup, ebBIT_1 );
\r
748 /* Ensure the other task is suspended. */
\r
749 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
754 /* The other task should not have cleared the bits - so all the bits
\r
755 should still be set. */
\r
756 if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )
\r
761 /* Clear ebBIT_1 again. */
\r
762 if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )
\r
767 /* Resume the other task - which will wait on all the ebCOMBINED_BITS
\r
768 again - this time clearing the bits when it is unblocked. */
\r
769 vTaskResume( xTestSlaveTaskHandle );
\r
771 /* Ensure the other task is blocked once again. */
\r
772 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
777 /* Set the bit the other task is waiting for. */
\r
778 xEventGroupSetBits( xEventGroup, ebBIT_1 );
\r
780 /* Ensure the other task is suspended once again. */
\r
781 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
786 /* The other task should have cleared the bits in ebCOMBINED_BITS.
\r
787 Clear the remaining bits. */
\r
788 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
790 if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
795 /* Clear all bits ready for the sync with the other three tasks. The
\r
796 value returned is the value prior to the bits being cleared. */
\r
797 if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
802 /* The bits should be clear now. */
\r
803 if( xEventGroupGetBits( xEventGroup ) != 0x00 )
\r
810 /*-----------------------------------------------------------*/
\r
812 static void prvSelectiveBitsTestSlaveFunction( void )
\r
814 EventBits_t uxPendBits, uxReturned;
\r
816 /* Used in a test that blocks two tasks on various different bits within an
\r
817 event group - then sets each bit in turn and checks that the correct tasks
\r
818 unblock at the correct times.
\r
820 This function is called by two different tasks - each of which will use a
\r
821 different bit. Check the task handle to see which task the function was
\r
823 if( xTaskGetCurrentTaskHandle() == xSyncTask1 )
\r
825 uxPendBits = ebSELECTIVE_BITS_1;
\r
829 uxPendBits = ebSELECTIVE_BITS_2;
\r
834 /* Wait until it is time to perform the next cycle of the test. The
\r
835 task is unsuspended by the tests implemented in the
\r
836 prvSelectiveBitsTestMasterFunction() function. */
\r
837 vTaskSuspend( NULL );
\r
838 uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );
\r
840 if( uxReturned == ( EventBits_t ) 0 )
\r
846 /*-----------------------------------------------------------*/
\r
848 static BaseType_t prvSelectiveBitsTestMasterFunction( void )
\r
850 BaseType_t xError = pdFALSE;
\r
853 /* Used in a test that blocks two tasks on various different bits within an
\r
854 event group - then sets each bit in turn and checks that the correct tasks
\r
855 unblock at the correct times. The two other tasks (xSyncTask1 and
\r
856 xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in
\r
859 Both other tasks should start in the suspended state. */
\r
860 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
865 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
870 /* Test each bit in the byte individually. */
\r
871 for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
\r
873 /* Resume both tasks. */
\r
874 vTaskResume( xSyncTask1 );
\r
875 vTaskResume( xSyncTask2 );
\r
877 /* Now both tasks should be blocked on the event group. */
\r
878 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
883 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
889 xEventGroupSetBits( xEventGroup, uxBit );
\r
891 /* Is the bit set in the first set of selective bits? If so the first
\r
892 sync task should have unblocked and returned to the suspended state. */
\r
893 if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
\r
895 /* Task should not have unblocked. */
\r
896 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
903 /* Task should have unblocked and returned to the suspended state. */
\r
904 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
910 /* Same checks for the second sync task. */
\r
911 if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
\r
913 /* Task should not have unblocked. */
\r
914 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
921 /* Task should have unblocked and returned to the suspended state. */
\r
922 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
929 /* Ensure both tasks are blocked on the event group again, then delete the
\r
930 event group so the other tasks leave this portion of the test. */
\r
931 vTaskResume( xSyncTask1 );
\r
932 vTaskResume( xSyncTask2 );
\r
934 /* Deleting the event group is the signal that the two other tasks should
\r
935 leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main
\r
936 part of their functionality. */
\r
937 vEventGroupDelete( xEventGroup );
\r
941 /*-----------------------------------------------------------*/
\r
943 void vPeriodicEventGroupsProcessing( void )
\r
945 static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;
\r
946 const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;
\r
947 const EventBits_t uxBitsToSet = 0x12U;
\r
948 EventBits_t uxReturned;
\r
949 BaseType_t xMessagePosted;
\r
951 /* Called periodically from the tick hook to exercise the "FromISR"
\r
956 if( xCallCount == xSetBitCount )
\r
958 /* All the event bits should start clear. */
\r
959 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
\r
960 if( uxReturned != 0x00 )
\r
962 xISRTestError = pdTRUE;
\r
966 /* Set the bits. This is called from the tick hook so it is not
\r
967 necessary to use the last parameter to ensure a context switch
\r
968 occurs immediately. */
\r
969 xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );
\r
970 if( xMessagePosted != pdPASS )
\r
972 xISRTestError = pdTRUE;
\r
976 else if( xCallCount == xGetBitsCount )
\r
978 /* Check the bits were set as expected. */
\r
979 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
\r
980 if( uxReturned != uxBitsToSet )
\r
982 xISRTestError = pdTRUE;
\r
985 else if( xCallCount == xClearBitsCount )
\r
987 /* Clear the bits again. */
\r
988 uxReturned = xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );
\r
990 /* The returned value should be the value before the bits were cleaed.*/
\r
991 if( uxReturned != uxBitsToSet )
\r
993 xISRTestError = pdTRUE;
\r
996 /* Go back to the start. */
\r
999 /* If no errors have been detected then increment the count of test
\r
1001 if( xISRTestError == pdFALSE )
\r
1008 /* Nothing else to do. */
\r
1012 /*-----------------------------------------------------------*/
\r
1013 /* This is called to check that all the created tasks are still running. */
\r
1014 BaseType_t xAreEventGroupTasksStillRunning( void )
\r
1016 static unsigned long ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;
\r
1017 BaseType_t xStatus = pdPASS;
\r
1019 /* Check the tasks are still cycling without finding any errors. */
\r
1020 if( ulPreviousSetBitCycles == ulTestMasterCycles )
\r
1024 ulPreviousSetBitCycles = ulTestMasterCycles;
\r
1026 if( ulPreviousWaitBitCycles == ulTestSlaveCycles )
\r
1030 ulPreviousWaitBitCycles = ulTestSlaveCycles;
\r
1032 if( ulPreviousISRCycles == ulISRCycles )
\r
1036 ulPreviousISRCycles = ulISRCycles;
\r