2 * FreeRTOS Kernel V10.0.0
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software. If you wish to use our Amazon
\r
14 * FreeRTOS name, please do so in a fair use way that does not cause confusion.
\r
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
18 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
19 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
23 * http://www.FreeRTOS.org
\r
24 * http://aws.amazon.com/freertos
\r
26 * 1 tab == 4 spaces!
\r
32 * This file contains fairly comprehensive checks on the behaviour of event
\r
33 * groups. It is not intended to be a user friendly demonstration of the
\r
36 * NOTE: The tests implemented in this file are informal 'sanity' tests
\r
37 * only and are not part of the module tests that make use of the
\r
38 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
42 /* Scheduler include files. */
\r
43 #include "FreeRTOS.h"
\r
45 #include "event_groups.h"
\r
47 /* Demo app includes. */
\r
48 #include "EventGroupsDemo.h"
\r
50 #if( INCLUDE_eTaskGetState != 1 )
\r
51 #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.
\r
54 /* Priorities used by the tasks. */
\r
55 #define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
56 #define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
58 /* Generic bit definitions. */
\r
59 #define ebBIT_0 ( 0x01 )
\r
60 #define ebBIT_1 ( 0x02 )
\r
61 #define ebBIT_2 ( 0x04 )
\r
62 #define ebBIT_3 ( 0x08 )
\r
63 #define ebBIT_4 ( 0x10 )
\r
64 #define ebBIT_5 ( 0x20 )
\r
65 #define ebBIT_6 ( 0x40 )
\r
66 #define ebBIT_7 ( 0x80 )
\r
68 /* Combinations of bits used in the demo. */
\r
69 #define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )
\r
70 #define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )
\r
72 /* Associate a bit to each task. These bits are used to identify all the tasks
\r
73 that synchronise with the xEventGroupSync() function. */
\r
74 #define ebSET_BIT_TASK_SYNC_BIT ebBIT_0
\r
75 #define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1
\r
76 #define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2
\r
77 #define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3
\r
78 #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
80 /* A block time of zero simply means "don't block". */
\r
81 #define ebDONT_BLOCK ( 0 )
\r
84 #define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 )
\r
86 /* Used in the selective bits test which checks no, one or both tasks blocked on
\r
87 event bits in a group are unblocked as appropriate as different bits get set. */
\r
88 #define ebSELECTIVE_BITS_1 0x03
\r
89 #define ebSELECTIVE_BITS_2 0x05
\r
91 /*-----------------------------------------------------------*/
\r
94 * NOTE: The tests implemented in this function are informal 'sanity' tests
\r
95 * only and are not part of the module tests that make use of the
\r
96 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
98 * The master test task. This task:
\r
100 * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two
\r
101 * tasks are blocked on different bits in an event group. The counterpart of
\r
102 * this test is implemented by the prvSelectiveBitsTestSlaveFunction()
\r
103 * function (which is called by the two tasks that block on the event group).
\r
105 * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when
\r
106 * just one task is blocked on various combinations of bits within an event
\r
107 * group. The counterpart of this test is implemented within the 'test
\r
110 * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.
\r
112 static void prvTestMasterTask( void *pvParameters );
\r
115 * A helper task that enables the 'test master' task to perform several
\r
116 * behavioural tests. See the comments above the prvTestMasterTask() prototype
\r
119 static void prvTestSlaveTask( void *pvParameters );
\r
122 * The part of the test that is performed between the 'test master' task and the
\r
123 * 'test slave' task to test the behaviour when the slave blocks on various
\r
124 * event bit combinations.
\r
126 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
\r
129 * The part of the test that uses all the tasks to test the task synchronisation
\r
132 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );
\r
135 * Two instances of prvSyncTask() are created. They start by calling
\r
136 * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is
\r
137 * executing the prvSelectiveBitsTestMasterFunction() function. They then loop
\r
138 * to test the task synchronisation (rendezvous) behaviour.
\r
140 static void prvSyncTask( void *pvParameters );
\r
143 * Functions used in a test that blocks two tasks on various different bits
\r
144 * within an event group - then sets each bit in turn and checks that the
\r
145 * correct tasks unblock at the correct times.
\r
147 static BaseType_t prvSelectiveBitsTestMasterFunction( void );
\r
148 static void prvSelectiveBitsTestSlaveFunction( void );
\r
150 /*-----------------------------------------------------------*/
\r
152 /* Variables that are incremented by the tasks on each cycle provided no errors
\r
153 have been found. Used to detect an error or stall in the test cycling. */
\r
154 static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;
\r
156 /* The event group used by all the task based tests. */
\r
157 static EventGroupHandle_t xEventGroup = NULL;
\r
159 /* The event group used by the interrupt based tests. */
\r
160 static EventGroupHandle_t xISREventGroup = NULL;
\r
162 /* Handles to the tasks that only take part in the synchronisation calls. */
\r
163 static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;
\r
165 /*-----------------------------------------------------------*/
\r
167 void vStartEventGroupTasks( void )
\r
169 TaskHandle_t xTestSlaveTaskHandle;
\r
172 * This file contains fairly comprehensive checks on the behaviour of event
\r
173 * groups. It is not intended to be a user friendly demonstration of the
\r
174 * event groups API.
\r
176 * NOTE: The tests implemented in this file are informal 'sanity' tests
\r
177 * only and are not part of the module tests that make use of the
\r
178 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.
\r
180 * Create the test tasks as described at the top of this file.
\r
182 xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );
\r
183 xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );
\r
184 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );
\r
185 xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );
\r
187 /* If the last task was created then the others will have been too. */
\r
188 configASSERT( xSyncTask2 );
\r
190 /* Create the event group used by the ISR tests. The event group used by
\r
191 the tasks is created by the tasks themselves. */
\r
192 xISREventGroup = xEventGroupCreate();
\r
193 configASSERT( xISREventGroup );
\r
195 /*-----------------------------------------------------------*/
\r
197 static void prvTestMasterTask( void *pvParameters )
\r
201 /* The handle to the slave task is passed in as the task parameter. */
\r
202 TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;
\r
204 /* Avoid compiler warnings. */
\r
205 ( void ) pvParameters;
\r
207 /* Create the event group used by the tasks ready for the initial tests. */
\r
208 xEventGroup = xEventGroupCreate();
\r
209 configASSERT( xEventGroup );
\r
211 /* Perform the tests that block two tasks on different combinations of bits,
\r
212 then set each bit in turn and check the correct tasks unblock at the correct
\r
214 xError = prvSelectiveBitsTestMasterFunction();
\r
218 /* Recreate the event group ready for the next cycle. */
\r
219 xEventGroup = xEventGroupCreate();
\r
220 configASSERT( xEventGroup );
\r
222 /* Perform the tests that check the behaviour when a single task is
\r
223 blocked on various combinations of event bits. */
\r
224 xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );
\r
226 /* Perform the task synchronisation tests. */
\r
227 xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );
\r
229 /* Delete the event group. */
\r
230 vEventGroupDelete( xEventGroup );
\r
232 /* Now all the other tasks should have completed and suspended
\r
233 themselves ready for the next go around the loop. */
\r
234 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
239 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
244 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
249 /* Only increment the cycle variable if no errors have been detected. */
\r
250 if( xError == pdFALSE )
\r
252 ulTestMasterCycles++;
\r
255 configASSERT( xError == pdFALSE );
\r
258 /*-----------------------------------------------------------*/
\r
260 static void prvSyncTask( void *pvParameters )
\r
262 EventBits_t uxSynchronisationBit, uxReturned;
\r
264 /* A few tests that check the behaviour when two tasks are blocked on
\r
265 various different bits within an event group are performed before this task
\r
266 enters its infinite loop to carry out its main demo function. */
\r
267 prvSelectiveBitsTestSlaveFunction();
\r
269 /* The bit to use to indicate this task is at the synchronisation point is
\r
270 passed in as the task parameter. */
\r
271 uxSynchronisationBit = ( EventBits_t ) pvParameters;
\r
275 /* Now this task takes part in a task synchronisation - sometimes known
\r
276 as a 'rendezvous'. Its execution pattern is controlled by the 'test
\r
277 master' task, which is responsible for taking this task out of the
\r
278 Suspended state when it is time to test the synchronisation behaviour.
\r
279 See: http://www.freertos.org/xEventGroupSync.html. */
\r
280 vTaskSuspend( NULL );
\r
282 /* Set the bit that indicates this task is at the synchronisation
\r
283 point. The first time this is done the 'test master' task has a lower
\r
284 priority than this task so this task will get to the sync point before
\r
285 the set bits task. */
\r
286 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
\r
287 uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */
\r
288 ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */
\r
289 portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */
\r
291 /* A max delay was used, so this task should only exit the above
\r
292 function call when the sync condition is met. Check this is the
\r
294 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
296 /* Remove compiler warning if configASSERT() is not defined. */
\r
297 ( void ) uxReturned;
\r
299 /* Wait until the 'test master' task unsuspends this task again. */
\r
300 vTaskSuspend( NULL );
\r
302 /* Set the bit that indicates this task is at the synchronisation
\r
303 point again. This time the 'test master' task has a higher priority
\r
304 than this task so will get to the sync point before this task. */
\r
305 uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );
\r
307 /* Again a max delay was used, so this task should only exit the above
\r
308 function call when the sync condition is met. Check this is the
\r
310 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );
\r
312 /* Block on the event group again. This time the event group is going
\r
313 to be deleted while this task is blocked on it so it is expected that 0
\r
315 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
316 configASSERT( uxReturned == 0 );
\r
319 /*-----------------------------------------------------------*/
\r
321 static void prvTestSlaveTask( void *pvParameters )
\r
323 EventBits_t uxReturned;
\r
324 BaseType_t xError = pdFALSE;
\r
326 /* Avoid compiler warnings. */
\r
327 ( void ) pvParameters;
\r
331 /**********************************************************************
\r
332 * Part 1: This section is the counterpart to the
\r
333 * prvBitCombinationTestMasterFunction() function which is called by the
\r
334 * test master task.
\r
335 ***********************************************************************
\r
337 This task is controller by the 'test master' task (which is
\r
338 implemented by prvTestMasterTask()). Suspend until resumed by the
\r
339 'test master' task. */
\r
340 vTaskSuspend( NULL );
\r
342 /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get
\r
343 set. Clear the bit on exit. */
\r
344 uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */
\r
345 ebBIT_1, /* The bit to wait for. */
\r
346 pdTRUE, /* Clear the bit on exit. */
\r
347 pdTRUE, /* Wait for all the bits (only one in this case anyway). */
\r
348 portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */
\r
350 /* The 'test master' task set all the bits defined by ebCOMBINED_BITS,
\r
351 only one of which was being waited for by this task. The return value
\r
352 shows the state of the event bits when the task was unblocked, however
\r
353 because the task was waiting for ebBIT_1 and 'clear on exit' was set to
\r
354 the current state of the event bits will have ebBIT_1 clear. */
\r
355 if( uxReturned != ebCOMBINED_BITS )
\r
360 /* Now call xEventGroupWaitBits() again, this time waiting for all the
\r
361 bits in ebCOMBINED_BITS to be set. This call should block until the
\r
362 'test master' task sets ebBIT_1 - which was the bit cleared in the call
\r
363 to xEventGroupWaitBits() above. */
\r
364 uxReturned = xEventGroupWaitBits( xEventGroup,
\r
365 ebCOMBINED_BITS, /* The bits being waited on. */
\r
366 pdFALSE, /* Don't clear the bits on exit. */
\r
367 pdTRUE, /* All the bits must be set to unblock. */
\r
370 /* Were all the bits set? */
\r
371 if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )
\r
376 /* Suspend again to wait for the 'test master' task. */
\r
377 vTaskSuspend( NULL );
\r
379 /* Now call xEventGroupWaitBits() again, again waiting for all the bits
\r
380 in ebCOMBINED_BITS to be set, but this time clearing the bits when the
\r
381 task is unblocked. */
\r
382 uxReturned = xEventGroupWaitBits( xEventGroup,
\r
383 ebCOMBINED_BITS, /* The bits being waited on. */
\r
384 pdTRUE, /* Clear the bits on exit. */
\r
385 pdTRUE, /* All the bits must be set to unblock. */
\r
388 /* The 'test master' task set all the bits in the event group, so that
\r
389 is the value that should have been returned. The bits defined by
\r
390 ebCOMBINED_BITS will have been clear again in the current value though
\r
391 as 'clear on exit' was set to pdTRUE. */
\r
392 if( uxReturned != ebALL_BITS )
\r
401 /**********************************************************************
\r
402 * Part 2: This section is the counterpart to the
\r
403 * prvPerformTaskSyncTests() function which is called by the
\r
404 * test master task.
\r
405 ***********************************************************************
\r
408 Once again wait for the 'test master' task to unsuspend this task
\r
409 when it is time for the next test. */
\r
410 vTaskSuspend( NULL );
\r
412 /* Now peform a synchronisation with all the other tasks. At this point
\r
413 the 'test master' task has the lowest priority so will get to the sync
\r
414 point after all the other synchronising tasks. */
\r
415 uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */
\r
416 ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */
\r
417 ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */
\r
418 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */
\r
420 /* A sync with a max delay should only exit when all the synchronisation
\r
422 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
427 /* ...but now the synchronisation bits should be clear again. Read back
\r
428 the current value of the bits within the event group to check that is
\r
429 the case. Setting the bits to zero will return the bits previous value
\r
430 then leave all the bits clear. */
\r
431 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
\r
436 /* Check the bits are indeed 0 now by simply reading then. */
\r
437 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
442 if( xError == pdFALSE )
\r
444 /* This task is still cycling without finding an error. */
\r
445 ulTestSlaveCycles++;
\r
448 vTaskSuspend( NULL );
\r
450 /* This time sync when the 'test master' task has the highest priority
\r
451 at the point where it sets its sync bit - so this time the 'test master'
\r
452 task will get to the sync point before this task. */
\r
453 uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
455 /* A sync with a max delay should only exit when all the synchronisation
\r
457 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
462 /* ...but now the sync bits should be clear again. */
\r
463 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )
\r
468 /* Block on the event group again. This time the event group is going
\r
469 to be deleted while this task is blocked on it, so it is expected that 0
\r
470 will be returned. */
\r
471 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );
\r
473 if( uxReturned != 0 )
\r
478 if( xError == pdFALSE )
\r
480 /* This task is still cycling without finding an error. */
\r
481 ulTestSlaveCycles++;
\r
484 configASSERT( xError == pdFALSE );
\r
487 /*-----------------------------------------------------------*/
\r
489 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
\r
491 EventBits_t uxBits;
\r
493 /* The three tasks that take part in the synchronisation (rendezvous) are
\r
494 expected to be in the suspended state at the start of the test. */
\r
495 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
500 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
505 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
510 /* Try a synch with no other tasks involved. First set all the bits other
\r
511 than this task's bit. */
\r
512 xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
\r
514 /* Then wait on just one bit - the bit that is being set. */
\r
515 uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
\r
516 ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
\r
517 ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */
\r
518 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
\r
520 /* A sync with a max delay should only exit when all the synchronise
\r
521 bits are set...check that is the case. In this case there is only one
\r
522 sync bit anyway. */
\r
523 if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )
\r
528 /* ...but now the sync bits should be clear again, leaving all the other
\r
529 bits set (as only one bit was being waited for). */
\r
530 if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )
\r
535 /* Clear all the bits to zero again. */
\r
536 xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );
\r
537 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
542 /* Unsuspend the other tasks then check they have executed up to the
\r
543 synchronisation point. */
\r
544 vTaskResume( xTestSlaveTaskHandle );
\r
545 vTaskResume( xSyncTask1 );
\r
546 vTaskResume( xSyncTask2 );
\r
548 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
553 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
558 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
563 /* Set this task's sync bit. */
\r
564 uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */
\r
565 ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */
\r
566 ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */
\r
567 portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */
\r
569 /* A sync with a max delay should only exit when all the synchronise
\r
570 bits are set...check that is the case. */
\r
571 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
576 /* ...but now the sync bits should be clear again. */
\r
577 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
583 /* The other tasks should now all be suspended again, ready for the next
\r
584 synchronisation. */
\r
585 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
590 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
595 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
601 /* Sync again - but this time set the last necessary bit as the
\r
602 highest priority task, rather than the lowest priority task. Unsuspend
\r
603 the other tasks then check they have executed up to the synchronisation
\r
605 vTaskResume( xTestSlaveTaskHandle );
\r
606 vTaskResume( xSyncTask1 );
\r
607 vTaskResume( xSyncTask2 );
\r
609 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
614 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
619 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
624 /* Raise the priority of this task above that of the other tasks. */
\r
625 vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );
\r
627 /* Set this task's sync bit. */
\r
628 uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );
\r
630 /* A sync with a max delay should only exit when all the synchronisation
\r
632 if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )
\r
637 /* ...but now the sync bits should be clear again. */
\r
638 if( xEventGroupGetBits( xEventGroup ) != 0 )
\r
644 /* The other tasks should now all be in the ready state again, but not
\r
645 executed yet as this task still has a higher relative priority. */
\r
646 if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )
\r
651 if( eTaskGetState( xSyncTask1 ) != eReady )
\r
656 if( eTaskGetState( xSyncTask2 ) != eReady )
\r
662 /* Reset the priority of this task back to its original value. */
\r
663 vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );
\r
665 /* Now all the other tasks should have reblocked on the event bits
\r
666 to test the behaviour when the event bits are deleted. */
\r
667 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
672 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
677 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
684 /*-----------------------------------------------------------*/
\r
686 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )
\r
688 EventBits_t uxBits;
\r
690 /* Resume the other task. It will block, pending a single bit from
\r
691 within ebCOMBINED_BITS. */
\r
692 vTaskResume( xTestSlaveTaskHandle );
\r
694 /* Ensure the other task is blocked on the task. */
\r
695 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
700 /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only
\r
701 blocked waiting for one of them. */
\r
702 xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );
\r
704 /* The 'test slave' task should now have executed, clearing ebBIT_1 (the
\r
705 bit it was blocked on), then re-entered the Blocked state to wait for
\r
706 all the other bits in ebCOMBINED_BITS to be set again. First check
\r
707 ebBIT_1 is clear. */
\r
708 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
710 if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )
\r
715 /* Ensure the other task is still in the blocked state. */
\r
716 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
721 /* Set all the bits other than ebBIT_1 - which is the bit that must be
\r
722 set before the other task unblocks. */
\r
723 xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );
\r
725 /* Ensure all the expected bits are still set. */
\r
726 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
728 if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )
\r
733 /* Ensure the other task is still in the blocked state. */
\r
734 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
739 /* Now also set ebBIT_1, which should unblock the other task, which will
\r
740 then suspend itself. */
\r
741 xEventGroupSetBits( xEventGroup, ebBIT_1 );
\r
743 /* Ensure the other task is suspended. */
\r
744 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
749 /* The other task should not have cleared the bits - so all the bits
\r
750 should still be set. */
\r
751 if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )
\r
756 /* Clear ebBIT_1 again. */
\r
757 if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )
\r
762 /* Resume the other task - which will wait on all the ebCOMBINED_BITS
\r
763 again - this time clearing the bits when it is unblocked. */
\r
764 vTaskResume( xTestSlaveTaskHandle );
\r
766 /* Ensure the other task is blocked once again. */
\r
767 if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )
\r
772 /* Set the bit the other task is waiting for. */
\r
773 xEventGroupSetBits( xEventGroup, ebBIT_1 );
\r
775 /* Ensure the other task is suspended once again. */
\r
776 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )
\r
781 /* The other task should have cleared the bits in ebCOMBINED_BITS.
\r
782 Clear the remaining bits. */
\r
783 uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );
\r
785 if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
790 /* Clear all bits ready for the sync with the other three tasks. The
\r
791 value returned is the value prior to the bits being cleared. */
\r
792 if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )
\r
797 /* The bits should be clear now. */
\r
798 if( xEventGroupGetBits( xEventGroup ) != 0x00 )
\r
805 /*-----------------------------------------------------------*/
\r
807 static void prvSelectiveBitsTestSlaveFunction( void )
\r
809 EventBits_t uxPendBits, uxReturned;
\r
811 /* Used in a test that blocks two tasks on various different bits within an
\r
812 event group - then sets each bit in turn and checks that the correct tasks
\r
813 unblock at the correct times.
\r
815 This function is called by two different tasks - each of which will use a
\r
816 different bit. Check the task handle to see which task the function was
\r
818 if( xTaskGetCurrentTaskHandle() == xSyncTask1 )
\r
820 uxPendBits = ebSELECTIVE_BITS_1;
\r
824 uxPendBits = ebSELECTIVE_BITS_2;
\r
829 /* Wait until it is time to perform the next cycle of the test. The
\r
830 task is unsuspended by the tests implemented in the
\r
831 prvSelectiveBitsTestMasterFunction() function. */
\r
832 vTaskSuspend( NULL );
\r
833 uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );
\r
835 if( uxReturned == ( EventBits_t ) 0 )
\r
841 /*-----------------------------------------------------------*/
\r
843 static BaseType_t prvSelectiveBitsTestMasterFunction( void )
\r
845 BaseType_t xError = pdFALSE;
\r
848 /* Used in a test that blocks two tasks on various different bits within an
\r
849 event group - then sets each bit in turn and checks that the correct tasks
\r
850 unblock at the correct times. The two other tasks (xSyncTask1 and
\r
851 xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in
\r
854 Both other tasks should start in the suspended state. */
\r
855 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
860 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
865 /* Test each bit in the byte individually. */
\r
866 for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )
\r
868 /* Resume both tasks. */
\r
869 vTaskResume( xSyncTask1 );
\r
870 vTaskResume( xSyncTask2 );
\r
872 /* Now both tasks should be blocked on the event group. */
\r
873 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
878 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
884 xEventGroupSetBits( xEventGroup, uxBit );
\r
886 /* Is the bit set in the first set of selective bits? If so the first
\r
887 sync task should have unblocked and returned to the suspended state. */
\r
888 if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )
\r
890 /* Task should not have unblocked. */
\r
891 if( eTaskGetState( xSyncTask1 ) != eBlocked )
\r
898 /* Task should have unblocked and returned to the suspended state. */
\r
899 if( eTaskGetState( xSyncTask1 ) != eSuspended )
\r
905 /* Same checks for the second sync task. */
\r
906 if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )
\r
908 /* Task should not have unblocked. */
\r
909 if( eTaskGetState( xSyncTask2 ) != eBlocked )
\r
916 /* Task should have unblocked and returned to the suspended state. */
\r
917 if( eTaskGetState( xSyncTask2 ) != eSuspended )
\r
924 /* Ensure both tasks are blocked on the event group again, then delete the
\r
925 event group so the other tasks leave this portion of the test. */
\r
926 vTaskResume( xSyncTask1 );
\r
927 vTaskResume( xSyncTask2 );
\r
929 /* Deleting the event group is the signal that the two other tasks should
\r
930 leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main
\r
931 part of their functionality. */
\r
932 vEventGroupDelete( xEventGroup );
\r
936 /*-----------------------------------------------------------*/
\r
938 void vPeriodicEventGroupsProcessing( void )
\r
940 static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;
\r
941 const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;
\r
942 const EventBits_t uxBitsToSet = 0x12U;
\r
943 EventBits_t uxReturned;
\r
944 BaseType_t xMessagePosted;
\r
946 /* Called periodically from the tick hook to exercise the "FromISR"
\r
951 if( xCallCount == xSetBitCount )
\r
953 /* All the event bits should start clear. */
\r
954 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
\r
955 if( uxReturned != 0x00 )
\r
957 xISRTestError = pdTRUE;
\r
961 /* Set the bits. This is called from the tick hook so it is not
\r
962 necessary to use the last parameter to ensure a context switch
\r
963 occurs immediately. */
\r
964 xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );
\r
965 if( xMessagePosted != pdPASS )
\r
967 xISRTestError = pdTRUE;
\r
971 else if( xCallCount == xGetBitsCount )
\r
973 /* Check the bits were set as expected. */
\r
974 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );
\r
975 if( uxReturned != uxBitsToSet )
\r
977 xISRTestError = pdTRUE;
\r
980 else if( xCallCount == xClearBitsCount )
\r
982 /* Clear the bits again. */
\r
983 uxReturned = ( EventBits_t ) xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );
\r
985 /* Check the message was posted. */
\r
986 if( uxReturned != pdPASS )
\r
988 xISRTestError = pdTRUE;
\r
991 /* Go back to the start. */
\r
994 /* If no errors have been detected then increment the count of test
\r
996 if( xISRTestError == pdFALSE )
\r
1003 /* Nothing else to do. */
\r
1007 /*-----------------------------------------------------------*/
\r
1008 /* This is called to check that all the created tasks are still running. */
\r
1009 BaseType_t xAreEventGroupTasksStillRunning( void )
\r
1011 static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;
\r
1012 BaseType_t xStatus = pdPASS;
\r
1014 /* Check the tasks are still cycling without finding any errors. */
\r
1015 if( ulPreviousSetBitCycles == ulTestMasterCycles )
\r
1019 ulPreviousSetBitCycles = ulTestMasterCycles;
\r
1021 if( ulPreviousWaitBitCycles == ulTestSlaveCycles )
\r
1025 ulPreviousWaitBitCycles = ulTestSlaveCycles;
\r
1027 if( ulPreviousISRCycles == ulISRCycles )
\r
1031 ulPreviousISRCycles = ulISRCycles;
\r