]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/EventGroupsDemo.c
f84bb42e929ce600da684f05b20ecc412fbe0b4a
[freertos] / FreeRTOS / Demo / Common / Minimal / EventGroupsDemo.c
1 /*\r
2     FreeRTOS V8.2.0rc1 - Copyright (C) 2014 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
12 \r
13     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
14     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
15     >>!   obliged to provide the source code for proprietary components     !<<\r
16     >>!   outside of the FreeRTOS kernel.                                   !<<\r
17 \r
18     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
19     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
20     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
21     link: http://www.freertos.org/a00114.html\r
22 \r
23     1 tab == 4 spaces!\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    Having a problem?  Start by reading the FAQ "My application does   *\r
28      *    not run, what could be wrong?".  Have you defined configASSERT()?  *\r
29      *                                                                       *\r
30      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
31      *                                                                       *\r
32     ***************************************************************************\r
33 \r
34     ***************************************************************************\r
35      *                                                                       *\r
36      *    FreeRTOS provides completely free yet professionally developed,    *\r
37      *    robust, strictly quality controlled, supported, and cross          *\r
38      *    platform software that is more than just the market leader, it     *\r
39      *    is the industry's de facto standard.                               *\r
40      *                                                                       *\r
41      *    Help yourself get started quickly while simultaneously helping     *\r
42      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
43      *    tutorial book, reference manual, or both:                          *\r
44      *    http://www.FreeRTOS.org/Documentation                              *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     ***************************************************************************\r
49      *                                                                       *\r
50      *   Investing in training allows your team to be as productive as       *\r
51      *   possible as early as possible, lowering your overall development    *\r
52      *   cost, and enabling you to bring a more robust product to market     *\r
53      *   earlier than would otherwise be possible.  Richard Barry is both    *\r
54      *   the architect and key author of FreeRTOS, and so also the world's   *\r
55      *   leading authority on what is the world's most popular real time     *\r
56      *   kernel for deeply embedded MCU designs.  Obtaining your training    *\r
57      *   from Richard ensures your team will gain directly from his in-depth *\r
58      *   product knowledge and years of usage experience.  Contact Real Time *\r
59      *   Engineers Ltd to enquire about the FreeRTOS Masterclass, presented  *\r
60      *   by Richard Barry:  http://www.FreeRTOS.org/contact\r
61      *                                                                       *\r
62     ***************************************************************************\r
63 \r
64     ***************************************************************************\r
65      *                                                                       *\r
66      *    You are receiving this top quality software for free.  Please play *\r
67      *    fair and reciprocate by reporting any suspected issues and         *\r
68      *    participating in the community forum:                              *\r
69      *    http://www.FreeRTOS.org/support                                    *\r
70      *                                                                       *\r
71      *    Thank you!                                                         *\r
72      *                                                                       *\r
73     ***************************************************************************\r
74 \r
75     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
76     license and Real Time Engineers Ltd. contact details.\r
77 \r
78     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
79     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
80     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
81 \r
82     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
83     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
84 \r
85     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
86     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
87     licenses offer ticketed support, indemnification and commercial middleware.\r
88 \r
89     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
90     engineered and independently SIL3 certified version for use in safety and\r
91     mission critical applications that require provable dependability.\r
92 \r
93     1 tab == 4 spaces!\r
94 */\r
95 \r
96 \r
97 \r
98 /*\r
99 * This file contains fairly comprehensive checks on the behaviour of event\r
100 * groups.  It is not intended to be a user friendly demonstration of the\r
101 * event groups API.\r
102 *\r
103 * NOTE:  The tests implemented in this file are informal 'sanity' tests\r
104 * only and are not part of the module tests that make use of the\r
105 * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
106 */\r
107 \r
108 \r
109 /* Scheduler include files. */\r
110 #include "FreeRTOS.h"\r
111 #include "task.h"\r
112 #include "event_groups.h"\r
113 \r
114 /* Demo app includes. */\r
115 #include "EventGroupsDemo.h"\r
116 \r
117 #if( INCLUDE_eTaskGetState != 1 )\r
118         #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file.\r
119 #endif\r
120 \r
121 /* Priorities used by the tasks. */\r
122 #define ebSET_BIT_TASK_PRIORITY         ( tskIDLE_PRIORITY )\r
123 #define ebWAIT_BIT_TASK_PRIORITY        ( tskIDLE_PRIORITY + 1 )\r
124 \r
125 /* Generic bit definitions. */\r
126 #define ebBIT_0         ( 0x01UL )\r
127 #define ebBIT_1         ( 0x02UL )\r
128 #define ebBIT_2         ( 0x04UL )\r
129 #define ebBIT_3         ( 0x08UL )\r
130 #define ebBIT_4         ( 0x10UL )\r
131 #define ebBIT_5         ( 0x20UL )\r
132 #define ebBIT_6         ( 0x40UL )\r
133 #define ebBIT_7         ( 0x80UL )\r
134 \r
135 /* Combinations of bits used in the demo. */\r
136 #define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 )\r
137 #define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 )\r
138 \r
139 /* Associate a bit to each task.  These bits are used to identify all the tasks\r
140 that synchronise with the xEventGroupSync() function. */\r
141 #define ebSET_BIT_TASK_SYNC_BIT                 ebBIT_0\r
142 #define ebWAIT_BIT_TASK_SYNC_BIT                ebBIT_1\r
143 #define ebRENDESVOUS_TASK_1_SYNC_BIT    ebBIT_2\r
144 #define ebRENDESVOUS_TASK_2_SYNC_BIT    ebBIT_3\r
145 #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
146 \r
147 /* A block time of zero simply means "don't block". */\r
148 #define ebDONT_BLOCK    ( 0 )\r
149 \r
150 /* A 5ms delay. */\r
151 #define ebSHORT_DELAY   ( 5 / portTICK_PERIOD_MS )\r
152 \r
153 /* Used in the selective bits test which checks no, one or both tasks blocked on\r
154 event bits in a group are unblocked as appropriate as different bits get set. */\r
155 #define ebSELECTIVE_BITS_1              0x03\r
156 #define ebSELECTIVE_BITS_2              0x05\r
157 \r
158 /*-----------------------------------------------------------*/\r
159 \r
160 /*\r
161  * NOTE:  The tests implemented in this function are informal 'sanity' tests\r
162  * only and are not part of the module tests that make use of the\r
163  * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
164  *\r
165  * The master test task.  This task:\r
166  *\r
167  * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two\r
168  *    tasks are blocked on different bits in an event group.  The counterpart of\r
169  *    this test is implemented by the prvSelectiveBitsTestSlaveFunction()\r
170  *    function (which is called by the two tasks that block on the event group).\r
171  *\r
172  * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when\r
173  *    just one task is blocked on various combinations of bits within an event\r
174  *    group.  The counterpart of this test is implemented within the 'test\r
175  *    slave' task.\r
176  *\r
177  * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour.\r
178  */\r
179 static void prvTestMasterTask( void *pvParameters );\r
180 \r
181 /*\r
182  * A helper task that enables the 'test master' task to perform several\r
183  * behavioural tests.  See the comments above the prvTestMasterTask() prototype\r
184  * above.\r
185  */\r
186 static void prvTestSlaveTask( void *pvParameters );\r
187 \r
188 /*\r
189  * The part of the test that is performed between the 'test master' task and the\r
190  * 'test slave' task to test the behaviour when the slave blocks on various\r
191  * event bit combinations.\r
192  */\r
193 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );\r
194 \r
195 /*\r
196  * The part of the test that uses all the tasks to test the task synchronisation\r
197  * behaviour.\r
198  */\r
199 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle );\r
200 \r
201 /*\r
202  * Two instances of prvSyncTask() are created.  They start by calling\r
203  * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is\r
204  * executing the prvSelectiveBitsTestMasterFunction() function.  They then loop\r
205  * to test the task synchronisation (rendezvous) behaviour.\r
206  */\r
207 static void prvSyncTask( void *pvParameters );\r
208 \r
209 /*\r
210  * Functions used in a test that blocks two tasks on various different bits\r
211  * within an event group - then sets each bit in turn and checks that the\r
212  * correct tasks unblock at the correct times.\r
213  */\r
214 static BaseType_t prvSelectiveBitsTestMasterFunction( void );\r
215 static void prvSelectiveBitsTestSlaveFunction( void );\r
216 \r
217 /*-----------------------------------------------------------*/\r
218 \r
219 /* Variables that are incremented by the tasks on each cycle provided no errors\r
220 have been found.  Used to detect an error or stall in the test cycling. */\r
221 static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0;\r
222 \r
223 /* The event group used by all the task based tests. */\r
224 static EventGroupHandle_t xEventGroup = NULL;\r
225 \r
226 /* The event group used by the interrupt based tests. */\r
227 static EventGroupHandle_t xISREventGroup = NULL;\r
228 \r
229 /* Handles to the tasks that only take part in the synchronisation calls. */\r
230 static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL;\r
231 \r
232 /*-----------------------------------------------------------*/\r
233 \r
234 void vStartEventGroupTasks( void )\r
235 {\r
236 TaskHandle_t xTestSlaveTaskHandle;\r
237 \r
238         /*\r
239          * This file contains fairly comprehensive checks on the behaviour of event\r
240          * groups.  It is not intended to be a user friendly demonstration of the\r
241          * event groups API.\r
242          *\r
243          * NOTE:  The tests implemented in this file are informal 'sanity' tests\r
244          * only and are not part of the module tests that make use of the\r
245          * mtCOVERAGE_TEST_MARKER macro within the event groups implementation.\r
246          *\r
247          * Create the test tasks as described at the top of this file.\r
248          */\r
249         xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle );\r
250         xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL );\r
251         xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 );\r
252         xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 );\r
253 \r
254         /* If the last task was created then the others will have been too. */\r
255         configASSERT( xSyncTask2 );\r
256 \r
257         /* Create the event group used by the ISR tests.  The event group used by\r
258         the tasks is created by the tasks themselves. */\r
259         xISREventGroup = xEventGroupCreate();\r
260         configASSERT( xISREventGroup );\r
261 }\r
262 /*-----------------------------------------------------------*/\r
263 \r
264 static void prvTestMasterTask( void *pvParameters )\r
265 {\r
266 BaseType_t xError;\r
267 \r
268 /* The handle to the slave task is passed in as the task parameter. */\r
269 TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters;\r
270 \r
271         /* Avoid compiler warnings. */\r
272         ( void ) pvParameters;\r
273 \r
274         /* Create the event group used by the tasks ready for the initial tests. */\r
275         xEventGroup = xEventGroupCreate();\r
276         configASSERT( xEventGroup );\r
277 \r
278         /* Perform the tests that block two tasks on different combinations of bits,\r
279         then set each bit in turn and check the correct tasks unblock at the correct\r
280         times. */\r
281         xError = prvSelectiveBitsTestMasterFunction();\r
282 \r
283         for( ;; )\r
284         {\r
285                 /* Recreate the event group ready for the next cycle. */\r
286                 xEventGroup = xEventGroupCreate();\r
287                 configASSERT( xEventGroup );\r
288 \r
289                 /* Perform the tests that check the behaviour when a single task is\r
290                 blocked on various combinations of event bits. */\r
291                 xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle );\r
292 \r
293                 /* Perform the task synchronisation tests. */\r
294                 xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle );\r
295 \r
296                 /* Delete the event group. */\r
297                 vEventGroupDelete( xEventGroup );\r
298 \r
299                 /* Now all the other tasks should have completed and suspended\r
300                 themselves ready for the next go around the loop. */\r
301                 if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
302                 {\r
303                         xError = pdTRUE;\r
304                 }\r
305 \r
306                 if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
307                 {\r
308                         xError = pdTRUE;\r
309                 }\r
310 \r
311                 if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
312                 {\r
313                         xError = pdTRUE;\r
314                 }\r
315 \r
316                 /* Only increment the cycle variable if no errors have been detected. */\r
317                 if( xError == pdFALSE )\r
318                 {\r
319                         ulTestMasterCycles++;\r
320                 }\r
321 \r
322                 configASSERT( xError == pdFALSE );\r
323         }\r
324 }\r
325 /*-----------------------------------------------------------*/\r
326 \r
327 static void prvSyncTask( void *pvParameters )\r
328 {\r
329 EventBits_t uxSynchronisationBit, uxReturned;\r
330 \r
331         /* A few tests that check the behaviour when two tasks are blocked on\r
332         various different bits within an event group are performed before this task\r
333         enters its infinite loop to carry out its main demo function. */\r
334         prvSelectiveBitsTestSlaveFunction();\r
335 \r
336         /* The bit to use to indicate this task is at the synchronisation point is\r
337         passed in as the task parameter. */\r
338         uxSynchronisationBit = ( EventBits_t ) pvParameters;\r
339 \r
340         for( ;; )\r
341         {\r
342                 /* Now this task takes part in a task synchronisation - sometimes known\r
343                 as a 'rendezvous'.  Its execution pattern is controlled by the 'test\r
344                 master' task, which is responsible for taking this task out of the\r
345                 Suspended state when it is time to test the synchronisation behaviour.\r
346                 See: http://www.freertos.org/xEventGroupSync.html. */\r
347                 vTaskSuspend( NULL );\r
348 \r
349                 /* Set the bit that indicates this task is at the synchronisation\r
350                 point.  The first time this is done the 'test master' task has a lower\r
351                 priority than this task so this task will get to the sync point before\r
352                 the set bits task. */\r
353                 uxReturned = xEventGroupSync( xEventGroup,      /* The event group used for the synchronisation. */\r
354                                                                         uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */\r
355                                                                         ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */\r
356                                                                         portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */\r
357 \r
358                 /* A max delay was used, so this task should only exit the above\r
359                 function call when the sync condition is met.  Check this is the\r
360                 case. */\r
361                 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );\r
362 \r
363                 /* Remove compiler warning if configASSERT() is not defined. */\r
364                 ( void ) uxReturned;\r
365 \r
366                 /* Wait until the 'test master' task unsuspends this task again. */\r
367                 vTaskSuspend( NULL );\r
368 \r
369                 /* Set the bit that indicates this task is at the synchronisation\r
370                 point again.  This time the 'test master' task has a higher priority\r
371                 than this task so will get to the sync point before this task. */\r
372                 uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY );\r
373 \r
374                 /* Again a max delay was used, so this task should only exit the above\r
375                 function call when the sync condition is met.  Check this is the\r
376                 case. */\r
377                 configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS );\r
378 \r
379                 /* Block on the event group again.  This time the event group is going\r
380                 to be deleted while this task is blocked on it so it is expected that 0\r
381                 be returned. */\r
382                 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
383                 configASSERT( uxReturned == 0 );\r
384         }\r
385 }\r
386 /*-----------------------------------------------------------*/\r
387 \r
388 static void prvTestSlaveTask( void *pvParameters )\r
389 {\r
390 EventBits_t uxReturned;\r
391 BaseType_t xError = pdFALSE;\r
392 \r
393         /* Avoid compiler warnings. */\r
394         ( void ) pvParameters;\r
395 \r
396         for( ;; )\r
397         {\r
398                 /**********************************************************************\r
399                 * Part 1:  This section is the counterpart to the\r
400                 * prvBitCombinationTestMasterFunction() function which is called by the\r
401                 * test master task.\r
402                 ***********************************************************************\r
403 \r
404                 This task is controller by the 'test master' task (which is\r
405                 implemented by prvTestMasterTask()).  Suspend until resumed by the\r
406                 'test master' task. */\r
407                 vTaskSuspend( NULL );\r
408 \r
409                 /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get\r
410                 set.  Clear the bit on exit. */\r
411                 uxReturned = xEventGroupWaitBits( xEventGroup,  /* The event group that contains the event bits being queried. */\r
412                                                                                  ebBIT_1,               /* The bit to wait for. */\r
413                                                                                  pdTRUE,                /* Clear the bit on exit. */\r
414                                                                                  pdTRUE,                /* Wait for all the bits (only one in this case anyway). */\r
415                                                                                  portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */\r
416 \r
417                 /* The 'test master' task set all the bits defined by ebCOMBINED_BITS,\r
418                 only one of which was being waited for by this task.  The return value\r
419                 shows the state of the event bits when the task was unblocked, however\r
420                 because the task was waiting for ebBIT_1 and 'clear on exit' was set to\r
421                 the current state of the event bits will have ebBIT_1 clear.  */\r
422                 if( uxReturned != ebCOMBINED_BITS )\r
423                 {\r
424                         xError = pdTRUE;\r
425                 }\r
426 \r
427                 /* Now call xEventGroupWaitBits() again, this time waiting for all the\r
428                 bits in ebCOMBINED_BITS to be set.  This call should block until the\r
429                 'test master' task sets ebBIT_1 - which was the bit cleared in the call\r
430                 to xEventGroupWaitBits() above. */\r
431                 uxReturned = xEventGroupWaitBits( xEventGroup,\r
432                                                                                  ebCOMBINED_BITS, /* The bits being waited on. */\r
433                                                                                  pdFALSE,                 /* Don't clear the bits on exit. */\r
434                                                                                  pdTRUE,                  /* All the bits must be set to unblock. */\r
435                                                                                  portMAX_DELAY );\r
436 \r
437                 /* Were all the bits set? */\r
438                 if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS )\r
439                 {\r
440                         xError = pdTRUE;\r
441                 }\r
442 \r
443                 /* Suspend again to wait for the 'test master' task. */\r
444                 vTaskSuspend( NULL );\r
445 \r
446                 /* Now call xEventGroupWaitBits() again, again waiting for all the bits\r
447                 in ebCOMBINED_BITS to be set, but this time clearing the bits when the\r
448                 task is unblocked. */\r
449                 uxReturned = xEventGroupWaitBits( xEventGroup,\r
450                                                                          ebCOMBINED_BITS, /* The bits being waited on. */\r
451                                                                          pdTRUE,                  /* Clear the bits on exit. */\r
452                                                                          pdTRUE,                  /* All the bits must be set to unblock. */\r
453                                                                          portMAX_DELAY );\r
454 \r
455                 /* The 'test master' task set all the bits in the event group, so that\r
456                 is the value that should have been returned.  The bits defined by\r
457                 ebCOMBINED_BITS will have been clear again in the current value though\r
458                 as 'clear on exit' was set to pdTRUE. */\r
459                 if( uxReturned != ebALL_BITS )\r
460                 {\r
461                         xError = pdTRUE;\r
462                 }\r
463 \r
464 \r
465 \r
466 \r
467 \r
468                 /**********************************************************************\r
469                 * Part 2:  This section is the counterpart to the\r
470                 * prvPerformTaskSyncTests() function which is called by the\r
471                 * test master task.\r
472                 ***********************************************************************\r
473 \r
474 \r
475                 Once again wait for the 'test master' task to unsuspend this task\r
476                 when it is time for the next test. */\r
477                 vTaskSuspend( NULL );\r
478 \r
479                 /* Now peform a synchronisation with all the other tasks.  At this point\r
480                 the 'test master' task has the lowest priority so will get to the sync\r
481                 point after all the other synchronising tasks. */\r
482                 uxReturned = xEventGroupSync( xEventGroup,              /* The event group used for the sync. */\r
483                                                                         ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */\r
484                                                                         ebALL_SYNC_BITS,        /* The bits to wait for.  These bits are set by the other tasks taking part in the sync. */\r
485                                                                         portMAX_DELAY );        /* The maximum time to wait for the sync condition to be met before giving up. */\r
486 \r
487                 /* A sync with a max delay should only exit when all the synchronisation\r
488                 bits are set... */\r
489                 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
490                 {\r
491                         xError = pdTRUE;\r
492                 }\r
493 \r
494                 /* ...but now the synchronisation bits should be clear again.  Read back\r
495                 the current value of the bits within the event group to check that is\r
496                 the case.  Setting the bits to zero will return the bits previous value\r
497                 then leave all the bits clear. */\r
498                 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )\r
499                 {\r
500                         xError = pdTRUE;\r
501                 }\r
502 \r
503                 /* Check the bits are indeed 0 now by simply reading then. */\r
504                 if( xEventGroupGetBits( xEventGroup ) != 0 )\r
505                 {\r
506                         xError = pdTRUE;\r
507                 }\r
508 \r
509                 if( xError == pdFALSE )\r
510                 {\r
511                         /* This task is still cycling without finding an error. */\r
512                         ulTestSlaveCycles++;\r
513                 }\r
514 \r
515                 vTaskSuspend( NULL );\r
516 \r
517                 /* This time sync when the 'test master' task has the highest priority\r
518                 at the point where it sets its sync bit - so this time the 'test master'\r
519                 task will get to the sync point before this task. */\r
520                 uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
521 \r
522                 /* A sync with a max delay should only exit when all the synchronisation\r
523                 bits are set... */\r
524                 if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
525                 {\r
526                         xError = pdTRUE;\r
527                 }\r
528 \r
529                 /* ...but now the sync bits should be clear again. */\r
530                 if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 )\r
531                 {\r
532                         xError = pdTRUE;\r
533                 }\r
534 \r
535                 /* Block on the event group again.  This time the event group is going\r
536                 to be deleted while this task is blocked on it, so it is expected that 0\r
537                 will be returned. */\r
538                 uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY );\r
539 \r
540                 if( uxReturned != 0 )\r
541                 {\r
542                         xError = pdTRUE;\r
543                 }\r
544 \r
545                 if( xError == pdFALSE )\r
546                 {\r
547                         /* This task is still cycling without finding an error. */\r
548                         ulTestSlaveCycles++;\r
549                 }\r
550 \r
551                 configASSERT( xError == pdFALSE );\r
552         }\r
553 }\r
554 /*-----------------------------------------------------------*/\r
555 \r
556 static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )\r
557 {\r
558 EventBits_t uxBits;\r
559 \r
560         /* The three tasks that take part in the synchronisation (rendezvous) are\r
561         expected to be in the suspended state at the start of the test. */\r
562         if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
563         {\r
564                 xError = pdTRUE;\r
565         }\r
566 \r
567         if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
568         {\r
569                 xError = pdTRUE;\r
570         }\r
571 \r
572         if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
573         {\r
574                 xError = pdTRUE;\r
575         }\r
576 \r
577         /* Try a synch with no other tasks involved.  First set all the bits other\r
578         than this task's bit. */\r
579         xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );\r
580 \r
581         /* Then wait on just one bit - the bit that is being set. */\r
582         uxBits = xEventGroupSync( xEventGroup,                  /* The event group used for the synchronisation. */\r
583                                                         ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */\r
584                                                         ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */\r
585                                                         portMAX_DELAY );                /* The maximum time to wait for the sync condition to be met. */\r
586 \r
587         /* A sync with a max delay should only exit when all the synchronise\r
588         bits are set...check that is the case.  In this case there is only one\r
589         sync bit anyway. */\r
590         if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT )\r
591         {\r
592                 xError = pdTRUE;\r
593         }\r
594 \r
595         /* ...but now the sync bits should be clear again, leaving all the other\r
596         bits set (as only one bit was being waited for). */\r
597         if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) )\r
598         {\r
599                 xError = pdTRUE;\r
600         }\r
601 \r
602         /* Clear all the bits to zero again. */\r
603         xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) );\r
604         if( xEventGroupGetBits( xEventGroup ) != 0 )\r
605         {\r
606                 xError = pdTRUE;\r
607         }\r
608 \r
609         /* Unsuspend the other tasks then check they have executed up to the\r
610         synchronisation point. */\r
611         vTaskResume( xTestSlaveTaskHandle );\r
612         vTaskResume( xSyncTask1 );\r
613         vTaskResume( xSyncTask2 );\r
614 \r
615         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
616         {\r
617                 xError = pdTRUE;\r
618         }\r
619 \r
620         if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
621         {\r
622                 xError = pdTRUE;\r
623         }\r
624 \r
625         if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
626         {\r
627                 xError = pdTRUE;\r
628         }\r
629 \r
630         /* Set this task's sync bit. */\r
631         uxBits = xEventGroupSync( xEventGroup,                  /* The event group used for the synchronisation. */\r
632                                                         ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */\r
633                                                         ebALL_SYNC_BITS,                /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */\r
634                                                         portMAX_DELAY );                /* The maximum time to wait for the sync condition to be met. */\r
635 \r
636         /* A sync with a max delay should only exit when all the synchronise\r
637         bits are set...check that is the case. */\r
638         if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
639         {\r
640                 xError = pdTRUE;\r
641         }\r
642 \r
643         /* ...but now the sync bits should be clear again. */\r
644         if( xEventGroupGetBits( xEventGroup ) != 0 )\r
645         {\r
646                 xError = pdTRUE;\r
647         }\r
648 \r
649 \r
650         /* The other tasks should now all be suspended again, ready for the next\r
651         synchronisation. */\r
652         if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
653         {\r
654                 xError = pdTRUE;\r
655         }\r
656 \r
657         if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
658         {\r
659                 xError = pdTRUE;\r
660         }\r
661 \r
662         if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
663         {\r
664                 xError = pdTRUE;\r
665         }\r
666 \r
667 \r
668         /* Sync again - but this time set the last necessary bit as the\r
669         highest priority task, rather than the lowest priority task.  Unsuspend\r
670         the other tasks then check they have executed up to the synchronisation\r
671         point. */\r
672         vTaskResume( xTestSlaveTaskHandle );\r
673         vTaskResume( xSyncTask1 );\r
674         vTaskResume( xSyncTask2 );\r
675 \r
676         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
677         {\r
678                 xError = pdTRUE;\r
679         }\r
680 \r
681         if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
682         {\r
683                 xError = pdTRUE;\r
684         }\r
685 \r
686         if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
687         {\r
688                 xError = pdTRUE;\r
689         }\r
690 \r
691         /* Raise the priority of this task above that of the other tasks. */\r
692         vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 );\r
693 \r
694         /* Set this task's sync bit. */\r
695         uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY );\r
696 \r
697         /* A sync with a max delay should only exit when all the synchronisation\r
698         bits are set... */\r
699         if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS )\r
700         {\r
701                 xError = pdTRUE;\r
702         }\r
703 \r
704         /* ...but now the sync bits should be clear again. */\r
705         if( xEventGroupGetBits( xEventGroup ) != 0 )\r
706         {\r
707                 xError = pdTRUE;\r
708         }\r
709 \r
710 \r
711         /* The other tasks should now all be in the ready state again, but not\r
712         executed yet as this task still has a higher relative priority. */\r
713         if( eTaskGetState( xTestSlaveTaskHandle ) != eReady )\r
714         {\r
715                 xError = pdTRUE;\r
716         }\r
717 \r
718         if( eTaskGetState( xSyncTask1 ) != eReady )\r
719         {\r
720                 xError = pdTRUE;\r
721         }\r
722 \r
723         if( eTaskGetState( xSyncTask2 ) != eReady )\r
724         {\r
725                 xError = pdTRUE;\r
726         }\r
727 \r
728 \r
729         /* Reset the priority of this task back to its original value. */\r
730         vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY );\r
731 \r
732         /* Now all the other tasks should have reblocked on the event bits\r
733         to test the behaviour when the event bits are deleted. */\r
734         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
735         {\r
736                 xError = pdTRUE;\r
737         }\r
738 \r
739         if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
740         {\r
741                 xError = pdTRUE;\r
742         }\r
743 \r
744         if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
745         {\r
746                 xError = pdTRUE;\r
747         }\r
748 \r
749         return xError;\r
750 }\r
751 /*-----------------------------------------------------------*/\r
752 \r
753 static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle )\r
754 {\r
755 EventBits_t uxBits;\r
756 \r
757         /* Resume the other task.  It will block, pending a single bit from\r
758         within ebCOMBINED_BITS. */\r
759         vTaskResume( xTestSlaveTaskHandle );\r
760 \r
761         /* Ensure the other task is blocked on the task. */\r
762         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
763         {\r
764                 xError = pdTRUE;\r
765         }\r
766 \r
767         /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only\r
768         blocked waiting for one of them. */\r
769         xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS );\r
770 \r
771         /* The 'test slave' task should now have executed, clearing ebBIT_1 (the\r
772         bit it was blocked on), then re-entered the Blocked state to wait for\r
773         all the other bits in ebCOMBINED_BITS to be set again.  First check\r
774         ebBIT_1 is clear. */\r
775         uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
776 \r
777         if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) )\r
778         {\r
779                 xError = pdTRUE;\r
780         }\r
781 \r
782         /* Ensure the other task is still in the blocked state. */\r
783         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
784         {\r
785                 xError = pdTRUE;\r
786         }\r
787 \r
788         /* Set all the bits other than ebBIT_1 - which is the bit that must be\r
789         set before the other task unblocks. */\r
790         xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 );\r
791 \r
792         /* Ensure all the expected bits are still set. */\r
793         uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
794 \r
795         if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) )\r
796         {\r
797                 xError = pdTRUE;\r
798         }\r
799 \r
800         /* Ensure the other task is still in the blocked state. */\r
801         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
802         {\r
803                 xError = pdTRUE;\r
804         }\r
805 \r
806         /* Now also set ebBIT_1, which should unblock the other task, which will\r
807         then suspend itself. */\r
808         xEventGroupSetBits( xEventGroup, ebBIT_1 );\r
809 \r
810         /* Ensure the other task is suspended. */\r
811         if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
812         {\r
813                 xError = pdTRUE;\r
814         }\r
815 \r
816         /* The other task should not have cleared the bits - so all the bits\r
817         should still be set. */\r
818         if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS )\r
819         {\r
820                 xError = pdTRUE;\r
821         }\r
822 \r
823         /* Clear ebBIT_1 again. */\r
824         if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS )\r
825         {\r
826                 xError = pdTRUE;\r
827         }\r
828 \r
829         /* Resume the other task - which will wait on all the ebCOMBINED_BITS\r
830         again - this time clearing the bits when it is unblocked. */\r
831         vTaskResume( xTestSlaveTaskHandle );\r
832 \r
833         /* Ensure the other task is blocked once again. */\r
834         if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked )\r
835         {\r
836                 xError = pdTRUE;\r
837         }\r
838 \r
839         /* Set the bit the other task is waiting for. */\r
840         xEventGroupSetBits( xEventGroup, ebBIT_1 );\r
841 \r
842         /* Ensure the other task is suspended once again. */\r
843         if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended )\r
844         {\r
845                 xError = pdTRUE;\r
846         }\r
847 \r
848         /* The other task should have cleared the bits in ebCOMBINED_BITS.\r
849         Clear the remaining bits. */\r
850         uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK );\r
851 \r
852         if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
853         {\r
854                 xError = pdTRUE;\r
855         }\r
856 \r
857         /* Clear all bits ready for the sync with the other three tasks.  The\r
858         value returned is the value prior to the bits being cleared. */\r
859         if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) )\r
860         {\r
861                 xError = pdTRUE;\r
862         }\r
863 \r
864         /* The bits should be clear now. */\r
865         if( xEventGroupGetBits( xEventGroup ) != 0x00 )\r
866         {\r
867                 xError = pdTRUE;\r
868         }\r
869 \r
870         return xError;\r
871 }\r
872 /*-----------------------------------------------------------*/\r
873 \r
874 static void prvSelectiveBitsTestSlaveFunction( void )\r
875 {\r
876 EventBits_t uxPendBits, uxReturned;\r
877 \r
878         /* Used in a test that blocks two tasks on various different bits within an\r
879         event group - then sets each bit in turn and checks that the correct tasks\r
880         unblock at the correct times.\r
881 \r
882         This function is called by two different tasks - each of which will use a\r
883         different bit.  Check the task handle to see which task the function was\r
884         called by. */\r
885         if( xTaskGetCurrentTaskHandle() == xSyncTask1 )\r
886         {\r
887                 uxPendBits = ebSELECTIVE_BITS_1;\r
888         }\r
889         else\r
890         {\r
891                 uxPendBits = ebSELECTIVE_BITS_2;\r
892         }\r
893 \r
894         for( ;; )\r
895         {\r
896                 /* Wait until it is time to perform the next cycle of the test.  The\r
897                 task is unsuspended by the tests implemented in the\r
898                 prvSelectiveBitsTestMasterFunction() function. */\r
899                 vTaskSuspend( NULL );\r
900                 uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY );\r
901 \r
902                 if( uxReturned == ( EventBits_t ) 0 )\r
903                 {\r
904                         break;\r
905                 }\r
906         }\r
907 }\r
908 /*-----------------------------------------------------------*/\r
909 \r
910 static BaseType_t prvSelectiveBitsTestMasterFunction( void )\r
911 {\r
912 BaseType_t xError = pdFALSE;\r
913 EventBits_t uxBit;\r
914 \r
915         /* Used in a test that blocks two tasks on various different bits within an\r
916         event group - then sets each bit in turn and checks that the correct tasks\r
917         unblock at the correct times.  The two other tasks (xSyncTask1 and\r
918         xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in\r
919         this test.\r
920 \r
921         Both other tasks should start in the suspended state. */\r
922         if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
923         {\r
924                 xError = pdTRUE;\r
925         }\r
926 \r
927         if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
928         {\r
929                 xError = pdTRUE;\r
930         }\r
931 \r
932         /* Test each bit in the byte individually. */\r
933         for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 )\r
934         {\r
935                 /* Resume both tasks. */\r
936                 vTaskResume( xSyncTask1 );\r
937                 vTaskResume( xSyncTask2 );\r
938 \r
939                 /* Now both tasks should be blocked on the event group. */\r
940                 if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
941                 {\r
942                         xError = pdTRUE;\r
943                 }\r
944 \r
945                 if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
946                 {\r
947                         xError = pdTRUE;\r
948                 }\r
949 \r
950                 /* Set one bit. */\r
951                 xEventGroupSetBits( xEventGroup, uxBit );\r
952 \r
953                 /* Is the bit set in the first set of selective bits?  If so the first\r
954                 sync task should have unblocked and returned to the suspended state. */\r
955                 if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 )\r
956                 {\r
957                         /* Task should not have unblocked. */\r
958                         if( eTaskGetState( xSyncTask1 ) != eBlocked )\r
959                         {\r
960                                 xError = pdTRUE;\r
961                         }\r
962                 }\r
963                 else\r
964                 {\r
965                         /* Task should have unblocked and returned to the suspended state. */\r
966                         if( eTaskGetState( xSyncTask1 ) != eSuspended )\r
967                         {\r
968                                 xError = pdTRUE;\r
969                         }\r
970                 }\r
971 \r
972                 /* Same checks for the second sync task. */\r
973                 if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 )\r
974                 {\r
975                         /* Task should not have unblocked. */\r
976                         if( eTaskGetState( xSyncTask2 ) != eBlocked )\r
977                         {\r
978                                 xError = pdTRUE;\r
979                         }\r
980                 }\r
981                 else\r
982                 {\r
983                         /* Task should have unblocked and returned to the suspended state. */\r
984                         if( eTaskGetState( xSyncTask2 ) != eSuspended )\r
985                         {\r
986                                 xError = pdTRUE;\r
987                         }\r
988                 }\r
989         }\r
990 \r
991         /* Ensure both tasks are blocked on the event group again, then delete the\r
992         event group so the other tasks leave this portion of the test. */\r
993         vTaskResume( xSyncTask1 );\r
994         vTaskResume( xSyncTask2 );\r
995 \r
996         /* Deleting the event group is the signal that the two other tasks should\r
997         leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main\r
998         part of their functionality. */\r
999         vEventGroupDelete( xEventGroup );\r
1000 \r
1001         return xError;\r
1002 }\r
1003 /*-----------------------------------------------------------*/\r
1004 \r
1005 void vPeriodicEventGroupsProcessing( void )\r
1006 {\r
1007 static BaseType_t xCallCount = 0, xISRTestError = pdFALSE;\r
1008 const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300;\r
1009 const EventBits_t uxBitsToSet = 0x12U;\r
1010 EventBits_t uxReturned;\r
1011 BaseType_t xMessagePosted;\r
1012 \r
1013         /* Called periodically from the tick hook to exercise the "FromISR"\r
1014         functions. */\r
1015 \r
1016         xCallCount++;\r
1017 \r
1018         if( xCallCount == xSetBitCount )\r
1019         {\r
1020                 /* All the event bits should start clear. */\r
1021                 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );\r
1022                 if( uxReturned != 0x00 )\r
1023                 {\r
1024                         xISRTestError = pdTRUE;\r
1025                 }\r
1026                 else\r
1027                 {\r
1028                         /* Set the bits.  This is called from the tick hook so it is not\r
1029                         necessary to use the last parameter to ensure a context switch\r
1030                         occurs immediately. */\r
1031                         xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL );\r
1032                         if( xMessagePosted != pdPASS )\r
1033                         {\r
1034                                 xISRTestError = pdTRUE;\r
1035                         }\r
1036                 }\r
1037         }\r
1038         else if( xCallCount == xGetBitsCount )\r
1039         {\r
1040                 /* Check the bits were set as expected. */\r
1041                 uxReturned = xEventGroupGetBitsFromISR( xISREventGroup );\r
1042                 if( uxReturned != uxBitsToSet )\r
1043                 {\r
1044                         xISRTestError = pdTRUE;\r
1045                 }\r
1046         }\r
1047         else if( xCallCount == xClearBitsCount )\r
1048         {\r
1049                 /* Clear the bits again. */\r
1050                 uxReturned = xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet );\r
1051 \r
1052                 /* Check the message was posted. */\r
1053                 if( uxReturned != pdPASS )\r
1054                 {\r
1055                         xISRTestError = pdTRUE;\r
1056                 }\r
1057 \r
1058                 /* Go back to the start. */\r
1059                 xCallCount = 0;\r
1060 \r
1061                 /* If no errors have been detected then increment the count of test\r
1062                 cycles. */\r
1063                 if( xISRTestError == pdFALSE )\r
1064                 {\r
1065                         ulISRCycles++;\r
1066                 }\r
1067         }\r
1068         else\r
1069         {\r
1070                 /* Nothing else to do. */\r
1071         }\r
1072 }\r
1073 \r
1074 /*-----------------------------------------------------------*/\r
1075 /* This is called to check that all the created tasks are still running. */\r
1076 BaseType_t xAreEventGroupTasksStillRunning( void )\r
1077 {\r
1078 static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0;\r
1079 BaseType_t xStatus = pdPASS;\r
1080 \r
1081         /* Check the tasks are still cycling without finding any errors. */\r
1082         if( ulPreviousSetBitCycles == ulTestMasterCycles )\r
1083         {\r
1084                 xStatus = pdFAIL;\r
1085         }\r
1086         ulPreviousSetBitCycles = ulTestMasterCycles;\r
1087 \r
1088         if( ulPreviousWaitBitCycles == ulTestSlaveCycles )\r
1089         {\r
1090                 xStatus = pdFAIL;\r
1091         }\r
1092         ulPreviousWaitBitCycles = ulTestSlaveCycles;\r
1093 \r
1094         if( ulPreviousISRCycles == ulISRCycles )\r
1095         {\r
1096                 xStatus = pdFAIL;\r
1097         }\r
1098         ulPreviousISRCycles = ulISRCycles;\r
1099 \r
1100         return xStatus;\r
1101 }\r
1102 \r
1103 \r
1104 \r