]> git.sur5r.net Git - freertos/blob - Demo/Common/Minimal/TimerDemo.c
A bit of modularisation performed on the TimerDemo.c file - still a work in progress.
[freertos] / Demo / Common / Minimal / TimerDemo.c
1 /*\r
2     FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
3 \r
4     ***************************************************************************\r
5     *                                                                         *\r
6     * If you are:                                                             *\r
7     *                                                                         *\r
8     *    + New to FreeRTOS,                                                   *\r
9     *    + Wanting to learn FreeRTOS or multitasking in general quickly       *\r
10     *    + Looking for basic training,                                        *\r
11     *    + Wanting to improve your FreeRTOS skills and productivity           *\r
12     *                                                                         *\r
13     * then take a look at the FreeRTOS books - available as PDF or paperback  *\r
14     *                                                                         *\r
15     *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *\r
16     *                  http://www.FreeRTOS.org/Documentation                  *\r
17     *                                                                         *\r
18     * A pdf reference manual is also available.  Both are usually delivered   *\r
19     * to your inbox within 20 minutes to two hours when purchased between 8am *\r
20     * and 8pm GMT (although please allow up to 24 hours in case of            *\r
21     * exceptional circumstances).  Thank you for your support!                *\r
22     *                                                                         *\r
23     ***************************************************************************\r
24 \r
25     This file is part of the FreeRTOS distribution.\r
26 \r
27     FreeRTOS is free software; you can redistribute it and/or modify it under\r
28     the terms of the GNU General Public License (version 2) as published by the\r
29     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
30     ***NOTE*** The exception to the GPL is included to allow you to distribute\r
31     a combined work that includes FreeRTOS without being obliged to provide the\r
32     source code for proprietary components outside of the FreeRTOS kernel.\r
33     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
34     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
35     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
36     more details. You should have received a copy of the GNU General Public\r
37     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
38     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
39     by writing to Richard Barry, contact details for whom are available on the\r
40     FreeRTOS WEB site.\r
41 \r
42     1 tab == 4 spaces!\r
43 \r
44     http://www.FreeRTOS.org - Documentation, latest information, license and\r
45     contact details.\r
46 \r
47     http://www.SafeRTOS.com - A version that is certified for use in safety\r
48     critical systems.\r
49 \r
50     http://www.OpenRTOS.com - Commercial support, development, porting,\r
51     licensing and training services.\r
52 */\r
53 \r
54 \r
55 /*\r
56  * Tests the behaviour of timers.  Some timers are created before hte scheudler\r
57  * is started, and some after.\r
58  */\r
59 \r
60 /* Standard includes. */\r
61 #include <string.h>\r
62 \r
63 /* Scheduler include files. */\r
64 #include "FreeRTOS.h"\r
65 #include "task.h"\r
66 #include "timers.h"\r
67 \r
68 /* Demo program include files. */\r
69 #include "TimerDemo.h"\r
70 \r
71 #if configTIMER_TASK_PRIORITY < 1\r
72         #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly.\r
73 #endif\r
74 \r
75 #define tmrdemoDONT_BLOCK                               ( ( portTickType ) 0 )\r
76 #define tmrdemoONE_SHOT_TIMER_PERIOD    ( xBasePeriod * ( portTickType ) 3 )\r
77 #define trmdemoNUM_TIMER_RESETS                 ( ( unsigned char ) 10 )\r
78 \r
79 /*-----------------------------------------------------------*/\r
80 \r
81 static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer );\r
82 static void prvTimerControlTask( void *pvParameters );\r
83 \r
84 static void prvTest1_CreateTimersWithoutSchedulerRunning( void );\r
85 static void     prvTest3_CheckAutoReloadExpireRates( void );\r
86 static void prvTest2_CheckTaskAndTimersInitialState( void );\r
87 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void );\r
88 static void prvTest5_CheckBasicOneShotTimerBehaviour( void );\r
89 static void prvTest6_CheckAutoReloadResetBehaviour( void );\r
90 static void prvResetStartConditionsForNextIteration( void );\r
91 \r
92 /*-----------------------------------------------------------*/\r
93 \r
94 /* Flag that will be latched to pdFAIL should any unexpected behaviour be\r
95 detected in any of the demo tests. */\r
96 static volatile portBASE_TYPE xTestStatus = pdPASS;\r
97 \r
98 /* Counter that is incremented on each cycle of a test.  This is used to\r
99 detect a stalled task - a test that is no longer running. */\r
100 static volatile unsigned portLONG ulLoopCounter = 0;\r
101 \r
102 static xTimerHandle xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
103 static unsigned char ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
104 static unsigned char ucOneShotTimerCounter = ( unsigned char ) 0;\r
105 \r
106 static xTimerHandle xOneShotTimer = NULL;\r
107 \r
108 static portTickType xBasePeriod = 0;\r
109 \r
110 /*-----------------------------------------------------------*/\r
111 \r
112 void vStartTimerDemoTask( portTickType xBasePeriodIn )\r
113 {\r
114         /* Store the period from which all the timer periods will be generated from\r
115         (multiples of). */\r
116         xBasePeriod = xBasePeriodIn;\r
117 \r
118         /* Create a set of timers for use by this demo/test. */\r
119         prvTest1_CreateTimersWithoutSchedulerRunning();\r
120 \r
121         /* Create the task that will control and monitor the timers.  This is\r
122         created at a lower priority than the timer service task to ensure, as\r
123         far as it is concerned, commands on timers are actioned immediately\r
124         (sending a command to the timer service task will unblock the timer service\r
125         task, which will then preempt this task). */\r
126         if( xTestStatus != pdFAIL )\r
127         {\r
128                 xTaskCreate( prvTimerControlTask, ( signed portCHAR * ) "Tmr Ctl", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL );\r
129         }\r
130 }\r
131 /*-----------------------------------------------------------*/\r
132 \r
133 static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer )\r
134 {\r
135 portBASE_TYPE xTimerID;\r
136 \r
137         xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( pxExpiredTimer );\r
138         if( xTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) )\r
139         {\r
140                 ( ucAutoReloadTimerCounters[ xTimerID ] )++;\r
141         }\r
142         else\r
143         {\r
144                 /* The timer ID appears to be unexpected (invalid). */\r
145                 xTestStatus = pdFAIL;\r
146         }\r
147 }\r
148 /*-----------------------------------------------------------*/\r
149 \r
150 static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
151 {\r
152         /* The parameter is not used in this case as only one timer uses this\r
153         callback function. */\r
154         ( void ) pxExpiredTimer;\r
155 \r
156         ucOneShotTimerCounter++;\r
157 }\r
158 /*-----------------------------------------------------------*/\r
159 \r
160 static void prvTimerControlTask( void *pvParameters )\r
161 {\r
162         ( void ) pvParameters;\r
163 \r
164         /* Create a one-shot timer for use later on in this test. */\r
165         xOneShotTimer = xTimerCreate(   "Oneshot Timer",                                /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
166                                                                         tmrdemoONE_SHOT_TIMER_PERIOD,/* The period for the timer. */\r
167                                                                         pdFALSE,                                                /* Don't autoreload - hence a one shot timer. */\r
168                                                                         ( void * ) 0,                                   /* The timer identifier.  In this case this is not used as the timer has its own callback. */\r
169                                                                         prvOneShotTimerCallback );              /* The callback to be called when the timer expires. */\r
170 \r
171         if( xOneShotTimer == NULL )\r
172         {\r
173                 xTestStatus = pdFAIL;\r
174         }\r
175 \r
176 \r
177         /* Ensure all the timers are in their expected initial state.  This\r
178         depends on the timer service task having a higher priority than this task. */\r
179         prvTest2_CheckTaskAndTimersInitialState();\r
180 \r
181         for( ;; )\r
182         {\r
183                 /* Check the auto reload timers expire at the expected/correct rates. */\r
184                 prvTest3_CheckAutoReloadExpireRates();\r
185 \r
186                 /* Check the auto reload timers can be stopped correctly, and correctly\r
187                 report their state. */\r
188                 prvTest4_CheckAutoReloadTimersCanBeStopped();\r
189                                 \r
190                 /* Check the one shot timer only calls its callback once after it has been \r
191                 started, and that it reports its state correctly. */\r
192                 prvTest5_CheckBasicOneShotTimerBehaviour();\r
193 \r
194                 /* Check timer reset behaviour. */\r
195                 prvTest6_CheckAutoReloadResetBehaviour();\r
196 \r
197                 /* Start the timers again to restart all the tests over again. */\r
198                 prvResetStartConditionsForNextIteration();\r
199         }\r
200 }\r
201 /*-----------------------------------------------------------*/\r
202 \r
203 /* This is called to check that the created task is still running and has not\r
204 detected any errors. */\r
205 portBASE_TYPE xAreTimerDemoTasksStillRunning( void )\r
206 {\r
207 static unsigned portLONG ulLastLoopCounter = 0;\r
208 \r
209         /* If the demo task is still running then we expect the loopcounter to\r
210         have incremented since this function was last called. */\r
211         if( ulLastLoopCounter == ulLoopCounter )\r
212         {\r
213                 xTestStatus = pdFAIL;\r
214         }\r
215 \r
216         ulLastLoopCounter = ulLoopCounter;\r
217 \r
218         /* Errors detected in the task itself will have latched xTestStatus\r
219         to pdFAIL. */\r
220 \r
221         return xTestStatus;\r
222 }\r
223 /*-----------------------------------------------------------*/\r
224 \r
225 static void prvTest1_CreateTimersWithoutSchedulerRunning( void )\r
226 {\r
227 portBASE_TYPE xTimer;\r
228 \r
229         for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )\r
230         {\r
231                 /* As the timer queue is not yet full, it should be possible to both create\r
232                 and start a timer.  These timers are being started before the scheduler has\r
233                 been started, so their block times should get set to zero within the timer\r
234                 API itself. */\r
235                 xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer",                                         /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
236                                                                                                         ( ( xTimer + 1 ) * xBasePeriod ),/* The period for the timer.  The plus 1 ensures a period of zero is not specified. */\r
237                                                                                                         pdTRUE,                                                         /* Autoreload is set to true. */\r
238                                                                                                         ( void * ) xTimer,                                      /* An identifier for the timer as all the auto reload timers use the same callback. */\r
239                                                                                                         prvAutoReloadTimerCallback );           /* The callback to be called when the timer expires. */\r
240 \r
241                 if( xAutoReloadTimers[ xTimer ] == NULL )\r
242                 {\r
243                         xTestStatus = pdFAIL;\r
244                 }\r
245                 else\r
246                 {\r
247                         /* The scheduler has not yet started, so the block period of\r
248                         portMAX_DELAY should just get set to zero in xTimerStart().  Also,\r
249                         the timer queue is not yet full so xTimerStart() should return\r
250                         pdPASS. */\r
251                         if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS )\r
252                         {\r
253                                 xTestStatus = pdFAIL;\r
254                         }\r
255                 }\r
256         }\r
257 \r
258         /* The timers queue should now be full, so it should be possible to create\r
259         another timer, but not possible to start it (the timer queue will not get\r
260         drained until the scheduler has been started. */\r
261         xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer",               /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
262                                                                                                         ( configTIMER_QUEUE_LENGTH * xBasePeriod ),     /* The period for the timer. */\r
263                                                                                                         pdTRUE,                                                 /* Autoreload is set to true. */\r
264                                                                                                         ( void * ) xTimer,                              /* An identifier for the timer as all the auto reload timers use the same callback. */\r
265                                                                                                         prvAutoReloadTimerCallback );   /* The callback to be called when the timer expires. */\r
266 \r
267         if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL )\r
268         {\r
269                 xTestStatus = pdFAIL;\r
270         }\r
271         else\r
272         {\r
273                 if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS )\r
274                 {\r
275                         /* This time it would not be expected that the timer could be\r
276                         started at this point. */\r
277                         xTestStatus = pdFAIL;\r
278                 }\r
279         }\r
280 }\r
281 /*-----------------------------------------------------------*/\r
282 \r
283 static void prvTest2_CheckTaskAndTimersInitialState( void )\r
284 {\r
285 unsigned char ucTimer;\r
286 \r
287         /* Ensure all the timers are in their expected initial state.  This     depends \r
288         on the timer service task having a higher priority than this task.\r
289 \r
290         auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active,\r
291         and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it \r
292         could not be started prior to the scheduler being started when it was \r
293         created). */\r
294         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
295         {\r
296                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
297                 {\r
298                         xTestStatus = pdFAIL;\r
299                 }\r
300         }\r
301 \r
302         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE )\r
303         {\r
304                 xTestStatus = pdFAIL;\r
305         }\r
306 }\r
307 /*-----------------------------------------------------------*/\r
308 \r
309 static void     prvTest3_CheckAutoReloadExpireRates( void )\r
310 {\r
311 unsigned char ucMaxAllowableValue, ucMinAllowableValue, ucTimer;\r
312 portTickType xNextWakeTime;\r
313 \r
314         /* Check the auto reload timers expire at the expcted rates. */\r
315 \r
316         /* Initialise the next wake time value before the call to vTaskDelayUntil() \r
317         as this is not really a periodic task. */\r
318         xNextWakeTime = xTaskGetTickCount();\r
319 \r
320         /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow \r
321         all the auto reload timers to expire at least once. */\r
322         vTaskDelayUntil( &xNextWakeTime, ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
323 \r
324         /* Check that all the auto reload timers have called their callback     \r
325         function the expected number of times. */\r
326         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
327         {\r
328                 /* The timer in array position 0 should elapse every xBasePeriod ticks, \r
329                 the timer in array position 1 should elapse every ( 2 * xBasePeriod ) \r
330                 ticks, etc.  This task blocked for configTIMER_QUEUE_LENGTH * xBasePeriod, \r
331                 so the timer in array position 0 should have elapsed \r
332                 configTIMER_QUEUE_LENGTH times, the     timer in array possition 1 should \r
333                 have elapsed ( configTIMER_QUEUE_LENGTH - 1 ) times, etc. */\r
334                 ucMaxAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer );\r
335                 ucMinAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer ) - 1;\r
336 \r
337                 if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) ||\r
338                         ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue )\r
339                         )\r
340                 {\r
341                         xTestStatus = pdFAIL;\r
342                 }\r
343         }\r
344 \r
345         if( xTestStatus == pdPASS )\r
346         {\r
347                 /* No errors have been reported so increment the loop counter so the \r
348                 check task knows this task is still running. */\r
349                 ulLoopCounter++;\r
350         }\r
351 }\r
352 /*-----------------------------------------------------------*/\r
353 \r
354 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void )\r
355 {               \r
356 unsigned char ucTimer;\r
357 \r
358         /* Check the auto reload timers can be stopped correctly, and correctly \r
359         report their state. */\r
360 \r
361         /* Stop all the active timers. */\r
362         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
363         {\r
364                 /* The timer has not been stopped yet! */\r
365                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
366                 {\r
367                         xTestStatus = pdFAIL;\r
368                 }\r
369 \r
370                 /* Now stop the timer.  This will appear to happen immediately to\r
371                 this task because this task is running at a priority below the\r
372                 timer service task. */\r
373                 xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
374 \r
375                 /* The timer should now be inactive. */\r
376                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
377                 {\r
378                         xTestStatus = pdFAIL;\r
379                 }\r
380         }\r
381 \r
382         taskENTER_CRITICAL();\r
383         {\r
384                 /* The timer in array position configTIMER_QUEUE_LENGTH should not\r
385                 be active.  The critical section is used to ensure the timer does\r
386                 not call its callback between the next line running and the array\r
387                 being cleared back to zero, as that would mask an error condition. */\r
388                 if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( unsigned char ) 0 )\r
389                 {\r
390                         xTestStatus = pdFAIL;\r
391                 }\r
392 \r
393                 /* Clear the timer callback count. */\r
394                 memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) );\r
395         }\r
396         taskEXIT_CRITICAL();\r
397 \r
398         /* The timers are now all inactive, so this time, after delaying, none\r
399         of the callback counters should have incremented. */\r
400         vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
401         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
402         {\r
403                 if( ucAutoReloadTimerCounters[ ucTimer ] != ( unsigned char ) 0 )\r
404                 {\r
405                         xTestStatus = pdFAIL;\r
406                 }\r
407         }\r
408 \r
409         if( xTestStatus == pdPASS )\r
410         {\r
411                 /* No errors have been reported so increment the loop counter so\r
412                 the check task knows this task is still running. */\r
413                 ulLoopCounter++;\r
414         }\r
415 }\r
416 /*-----------------------------------------------------------*/\r
417 \r
418 static void prvTest5_CheckBasicOneShotTimerBehaviour( void )\r
419 {\r
420         /* Check the one shot timer only calls its callback once after it has been \r
421         started, and that it reports its state correctly. */\r
422 \r
423         /* The one shot timer should not be active yet. */\r
424         if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
425         {\r
426                 xTestStatus = pdFAIL;\r
427         }\r
428 \r
429         if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
430         {\r
431                 xTestStatus = pdFAIL;\r
432         }\r
433 \r
434         /* Start the one shot timer and check that it reports its state correctly. */\r
435         xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
436         if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
437         {\r
438                 xTestStatus = pdFAIL;\r
439         }\r
440 \r
441         /* Delay for three times as long as the one shot timer period, then check \r
442         to ensure it has only called its callback once, and is now not in the \r
443         active state. */\r
444         vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( portTickType ) 3 );\r
445 \r
446         if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
447         {\r
448                 xTestStatus = pdFAIL;\r
449         }\r
450 \r
451         if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
452         {\r
453                 xTestStatus = pdFAIL;\r
454         }\r
455         else\r
456         {\r
457                 /* Reset the one shot timer callback count. */\r
458                 ucOneShotTimerCounter = ( unsigned char ) 0;\r
459         }\r
460 \r
461         if( xTestStatus == pdPASS )\r
462         {\r
463                 /* No errors have been reported so increment the loop counter so the \r
464                 check task knows this task is still running. */\r
465                 ulLoopCounter++;\r
466         }\r
467 }\r
468 /*-----------------------------------------------------------*/\r
469 \r
470 static void prvTest6_CheckAutoReloadResetBehaviour( void )\r
471 {\r
472 unsigned char ucTimer;\r
473 \r
474         /* Check timer reset behaviour. */\r
475 \r
476         /* Restart the one shot timer and check it reports its status correctly. */\r
477         xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
478         if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
479         {\r
480                 xTestStatus = pdFAIL;\r
481         }\r
482 \r
483         /* Restart one of the auto reload timers and check that it reports its\r
484         status correctly. */\r
485         xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
486         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
487         {\r
488                 xTestStatus = pdFAIL;\r
489         }\r
490 \r
491         for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ )\r
492         {\r
493                 /* Delay for half as long as the one shot timer period, then reset it.  \r
494                 It should never expire while this is done, so its callback count should \r
495                 never increment. */\r
496                 vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 );\r
497 \r
498                 /* Check both running timers are still active, but have not called their\r
499                 callback functions. */\r
500                 if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
501                 {\r
502                         xTestStatus = pdFAIL;\r
503                 }\r
504 \r
505                 if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
506                 {\r
507                         xTestStatus = pdFAIL;\r
508                 }\r
509 \r
510                 if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
511                 {\r
512                         xTestStatus = pdFAIL;\r
513                 }\r
514 \r
515                 if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( unsigned char ) 0 )\r
516                 {\r
517                         xTestStatus = pdFAIL;\r
518                 }\r
519 \r
520                 /* Reset both running timers. */\r
521                 xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );\r
522                 xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
523 \r
524                 if( xTestStatus == pdPASS )\r
525                 {\r
526                         /* No errors have been reported so increment the loop counter so \r
527                         the check task knows this task is still running. */\r
528                         ulLoopCounter++;\r
529                 }\r
530         }\r
531 \r
532         /* Finally delay long enough for both running timers to expire. */\r
533         vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
534 \r
535         /* The timers were not reset during the above delay period so should now\r
536         both have called their callback functions. */\r
537         if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
538         {\r
539                 xTestStatus = pdFAIL;\r
540         }\r
541 \r
542         if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 )\r
543         {\r
544                 xTestStatus = pdFAIL;\r
545         }\r
546 \r
547         /* The one shot timer should no longer be active, while the auto reload\r
548         timer should still be active. */\r
549         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
550         {\r
551                 xTestStatus = pdFAIL;\r
552         }\r
553 \r
554         if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE )\r
555         {\r
556                 xTestStatus = pdFAIL;\r
557         }\r
558 \r
559         /* Stop the auto reload timer again. */\r
560         xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
561 \r
562         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )\r
563         {\r
564                 xTestStatus = pdFAIL;\r
565         }\r
566 \r
567         /* Clear the timer callback counts, ready for another iteration of these\r
568         tests. */\r
569         ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( unsigned char ) 0;\r
570         ucOneShotTimerCounter = ( unsigned char ) 0;\r
571 \r
572         if( xTestStatus == pdPASS )\r
573         {\r
574                 /* No errors have been reported so increment the loop counter so the check \r
575                 task knows this task is still running. */\r
576                 ulLoopCounter++;\r
577         }\r
578 }\r
579 /*-----------------------------------------------------------*/\r
580 \r
581 static void prvResetStartConditionsForNextIteration( void )\r
582 {\r
583 unsigned char ucTimer;\r
584 \r
585         /* Start the timers again to start all the tests over again. */\r
586 \r
587         /* Start the timers again. */\r
588         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
589         {\r
590                 /* The timer has not been started yet! */\r
591                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
592                 {\r
593                         xTestStatus = pdFAIL;\r
594                 }\r
595 \r
596                 /* Now start the timer.  This will appear to happen immediately to\r
597                 this task because this task is running at a priority below the timer \r
598                 service task. */\r
599                 xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
600 \r
601                 /* The timer should now be active. */\r
602                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
603                 {\r
604                         xTestStatus = pdFAIL;\r
605                 }\r
606         }\r
607 \r
608         if( xTestStatus == pdPASS )\r
609         {\r
610                 /* No errors have been reported so increment the loop counter so the \r
611                 check task knows this task is still running. */\r
612                 ulLoopCounter++;\r
613         }\r
614 }\r
615 /*-----------------------------------------------------------*/\r
616 \r