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