]> begriffs open source - cmsis-freertos/blob - Demo/Common/Minimal/TimerDemo.c
Updated pack to FreeRTOS 10.4.6
[cmsis-freertos] / Demo / Common / Minimal / TimerDemo.c
1 /*
2  * FreeRTOS V202111.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26
27
28 /*
29  * Tests the behaviour of timers.  Some timers are created before the scheduler
30  * is started, and some after.
31  */
32
33 /* Standard includes. */
34 #include <string.h>
35
36 /* Scheduler include files. */
37 #include "FreeRTOS.h"
38 #include "task.h"
39 #include "timers.h"
40
41 /* Demo program include files. */
42 #include "TimerDemo.h"
43
44 #if ( configTIMER_TASK_PRIORITY < 1 )
45     #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly.
46 #endif
47
48 #define tmrdemoDONT_BLOCK                    ( ( TickType_t ) 0 )
49 #define tmrdemoONE_SHOT_TIMER_PERIOD         ( xBasePeriod * ( TickType_t ) 3 )
50 #define tmrdemoNUM_TIMER_RESETS              ( ( uint8_t ) 10 )
51
52 #ifndef tmrTIMER_TEST_TASK_STACK_SIZE
53     #define tmrTIMER_TEST_TASK_STACK_SIZE    configMINIMAL_STACK_SIZE
54 #endif
55
56 /*-----------------------------------------------------------*/
57
58 /* The callback functions used by the timers.  These each increment a counter
59  * to indicate which timer has expired.  The auto-reload timers that are used by
60  * the test task (as opposed to being used from an ISR) all share the same
61  * prvAutoReloadTimerCallback() callback function, and use the ID of the
62  * pxExpiredTimer parameter passed into that function to know which counter to
63  * increment.  The other timers all have their own unique callback function and
64  * simply increment their counters without using the callback function parameter. */
65 static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer );
66 static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer );
67 static void prvTimerTestTask( void * pvParameters );
68 static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer );
69 static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer );
70
71 /* The test functions used by the timer test task.  These manipulate the auto
72  * reload and one-shot timers in various ways, then delay, then inspect the timers
73  * to ensure they have behaved as expected. */
74 static void prvTest1_CreateTimersWithoutSchedulerRunning( void );
75 static void prvTest2_CheckTaskAndTimersInitialState( void );
76 static void prvTest3_CheckAutoReloadExpireRates( void );
77 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void );
78 static void prvTest5_CheckBasicOneShotTimerBehaviour( void );
79 static void prvTest6_CheckAutoReloadResetBehaviour( void );
80 static void prvTest7_CheckBacklogBehaviour( void );
81 static void prvResetStartConditionsForNextIteration( void );
82
83 /*-----------------------------------------------------------*/
84
85 /* Flag that will be latched to pdFAIL should any unexpected behaviour be
86  * detected in any of the demo tests. */
87 static volatile BaseType_t xTestStatus = pdPASS;
88
89 /* Flag indicating whether the testing includes the backlog demo.  The backlog
90  * demo can be disruptive to other demos because the timer backlog is created by
91  * calling xTaskCatchUpTicks(). */
92 static uint8_t ucIsBacklogDemoEnabled = ( uint8_t ) pdFALSE;
93
94 /* Counter that is incremented on each cycle of a test.  This is used to
95  * detect a stalled task - a test that is no longer running. */
96 static volatile uint32_t ulLoopCounter = 0;
97
98 /* A set of auto-reload timers - each of which use the same callback function.
99  * The callback function uses the timer ID to index into, and then increment, a
100  * counter in the ucAutoReloadTimerCounters[] array.  The callback function stops
101  * xAutoReloadTimers[0] during its callback if ucIsStopNeededInTimerZeroCallback is
102  * pdTRUE.  The auto-reload timers referenced from xAutoReloadTimers[] are used by
103  * the prvTimerTestTask task. */
104 static TimerHandle_t xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };
105 static uint8_t ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };
106 static uint8_t ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE;
107
108 /* The one-shot timer is configured to use a callback function that increments
109  * ucOneShotTimerCounter each time it gets called. */
110 static TimerHandle_t xOneShotTimer = NULL;
111 static uint8_t ucOneShotTimerCounter = ( uint8_t ) 0;
112
113 /* The ISR reload timer is controlled from the tick hook to exercise the timer
114  * API functions that can be used from an ISR.  It is configured to increment
115  * ucISRReloadTimerCounter each time its callback function is executed. */
116 static TimerHandle_t xISRAutoReloadTimer = NULL;
117 static uint8_t ucISRAutoReloadTimerCounter = ( uint8_t ) 0;
118
119 /* The ISR one-shot timer is controlled from the tick hook to exercise the timer
120  * API functions that can be used from an ISR.  It is configured to increment
121  * ucISRReloadTimerCounter each time its callback function is executed. */
122 static TimerHandle_t xISROneShotTimer = NULL;
123 static uint8_t ucISROneShotTimerCounter = ( uint8_t ) 0;
124
125 /* The period of all the timers are a multiple of the base period.  The base
126  * period is configured by the parameter to vStartTimerDemoTask(). */
127 static TickType_t xBasePeriod = 0;
128
129 /*-----------------------------------------------------------*/
130
131 void vStartTimerDemoTask( TickType_t xBasePeriodIn )
132 {
133     /* Start with the timer and counter arrays clear - this is only necessary
134      * where the compiler does not clear them automatically on start up. */
135     memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) );
136     memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) );
137
138     /* Store the period from which all the timer periods will be generated from
139      * (multiples of). */
140     xBasePeriod = xBasePeriodIn;
141
142     /* Create a set of timers for use by this demo/test. */
143     prvTest1_CreateTimersWithoutSchedulerRunning();
144
145     /* Create the task that will control and monitor the timers.  This is
146      * created at a lower priority than the timer service task to ensure, as
147      * far as it is concerned, commands on timers are acted on immediately
148      * (sending a command to the timer service task will unblock the timer service
149      * task, which will then preempt this task). */
150     if( xTestStatus != pdFAIL )
151     {
152         xTaskCreate( prvTimerTestTask, "Tmr Tst", tmrTIMER_TEST_TASK_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL );
153     }
154 }
155 /*-----------------------------------------------------------*/
156
157 void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests )
158 {
159     ucIsBacklogDemoEnabled = ( uint8_t ) includeBacklogTests;
160 }
161 /*-----------------------------------------------------------*/
162
163 static void prvTimerTestTask( void * pvParameters )
164 {
165     ( void ) pvParameters;
166
167     /* Create a one-shot timer for use later on in this test.  For test purposes it
168      * is created as an auto-reload timer then converted to a one-shot timer. */
169     xOneShotTimer = xTimerCreate( "Oneshot Timer",              /* Text name to facilitate debugging.  The kernel does not use this itself. */
170                                   tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */
171                                   pdFALSE,                      /* Autoreload is false, so created as a one-shot timer. */
172                                   ( void * ) 0,                 /* The timer identifier.  Initialise to 0, then increment each time it is called. */
173                                   prvOneShotTimerCallback );    /* The callback to be called when the timer expires. */
174
175     if( xOneShotTimer == NULL )
176     {
177         xTestStatus = pdFAIL;
178         configASSERT( xTestStatus );
179     }
180
181     /* Purely for test coverage purposes - change and query the reload mode to
182      * auto-reload then back to one-shot. */
183
184     /* Change timer to auto-reload. */
185     vTimerSetReloadMode( xOneShotTimer, pdTRUE );
186
187     /* Timer should now be auto-reload. */
188     configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdTRUE );
189
190     /* Change timer to one-shot, which is what is needed for this test. */
191     vTimerSetReloadMode( xOneShotTimer, pdFALSE );
192
193     /* Check change to one-shot was successful. */
194     configASSERT( uxTimerGetReloadMode( xOneShotTimer ) == pdFALSE );
195
196     /* Ensure all the timers are in their expected initial state.  This
197      * depends on the timer service task having a higher priority than this task. */
198     prvTest2_CheckTaskAndTimersInitialState();
199
200     for( ; ; )
201     {
202         /* Check the auto-reload timers expire at the expected/correct rates. */
203         prvTest3_CheckAutoReloadExpireRates();
204
205         /* Check the auto-reload timers can be stopped correctly, and correctly
206          * report their state. */
207         prvTest4_CheckAutoReloadTimersCanBeStopped();
208
209         /* Check the one-shot timer only calls its callback once after it has been
210          * started, and that it reports its state correctly. */
211         prvTest5_CheckBasicOneShotTimerBehaviour();
212
213         /* Check timer reset behaviour. */
214         prvTest6_CheckAutoReloadResetBehaviour();
215
216         /* Check timer behaviour when the timer task gets behind in its work. */
217         if( ucIsBacklogDemoEnabled == ( uint8_t ) pdTRUE )
218         {
219             prvTest7_CheckBacklogBehaviour();
220         }
221
222         /* Start the timers again to restart all the tests over again. */
223         prvResetStartConditionsForNextIteration();
224     }
225 }
226 /*-----------------------------------------------------------*/
227
228 /* This is called to check that the created task is still running and has not
229  * detected any errors. */
230 BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency )
231 {
232     static uint32_t ulLastLoopCounter = 0UL;
233     TickType_t xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax;
234     static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCycleFrequency;
235
236     if( xLastCycleFrequency != xCycleFrequency )
237     {
238         /* The cycle frequency has probably become much faster due to an error
239          * elsewhere.  Start counting Iterations again. */
240         xIterationsWithoutCounterIncrement = ( TickType_t ) 0;
241         xLastCycleFrequency = xCycleFrequency;
242     }
243
244     /* Calculate the maximum number of times that it is permissible for this
245      * function to be called without ulLoopCounter being incremented.  This is
246      * necessary because the tests in this file block for extended periods, and the
247      * block period might be longer than the time between calls to this function. */
248     xMaxBlockTimeUsedByTheseTests = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;
249     xLoopCounterIncrementTimeMax = ( xMaxBlockTimeUsedByTheseTests / xCycleFrequency ) + 1;
250
251     /* If the demo task is still running then the loop counter is expected to
252      * have incremented every xLoopCounterIncrementTimeMax calls. */
253     if( ulLastLoopCounter == ulLoopCounter )
254     {
255         xIterationsWithoutCounterIncrement++;
256
257         if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax )
258         {
259             /* The tests appear to be no longer running (stalled). */
260             xTestStatus = pdFAIL;
261         }
262     }
263     else
264     {
265         /* ulLoopCounter changed, so the count of times this function was called
266          * without a change can be reset to zero. */
267         xIterationsWithoutCounterIncrement = ( TickType_t ) 0;
268     }
269
270     ulLastLoopCounter = ulLoopCounter;
271
272     /* Errors detected in the task itself will have latched xTestStatus
273      * to pdFAIL. */
274
275     return xTestStatus;
276 }
277 /*-----------------------------------------------------------*/
278
279 static void prvTest1_CreateTimersWithoutSchedulerRunning( void )
280 {
281     TickType_t xTimer;
282
283     for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )
284     {
285         /* As the timer queue is not yet full, it should be possible to both
286          * create and start a timer.  These timers are being started before the
287          * scheduler has been started, so their block times should get set to zero
288          * within the timer API itself. */
289         xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer",                                      /* Text name to facilitate debugging.  The kernel does not use this itself. */
290                                                     ( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ), /* The period for the timer.  The plus 1 ensures a period of zero is not specified. */
291                                                     pdTRUE,                                          /* Auto-reload is set to true. */
292                                                     ( void * ) xTimer,                               /* An identifier for the timer as all the auto-reload timers use the same callback. */
293                                                     prvAutoReloadTimerCallback );                    /* The callback to be called when the timer expires. */
294
295         if( xAutoReloadTimers[ xTimer ] == NULL )
296         {
297             xTestStatus = pdFAIL;
298             configASSERT( xTestStatus );
299         }
300         else
301         {
302             configASSERT( strcmp( pcTimerGetName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 );
303
304             /* The scheduler has not yet started, so the block period of
305              * portMAX_DELAY should just get set to zero in xTimerStart().  Also,
306              * the timer queue is not yet full so xTimerStart() should return
307              * pdPASS. */
308             if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS )
309             {
310                 xTestStatus = pdFAIL;
311                 configASSERT( xTestStatus );
312             }
313         }
314     }
315
316     /* The timers queue should now be full, so it should be possible to create
317      * another timer, but not possible to start it (the timer queue will not get
318      * drained until the scheduler has been started. */
319     xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer",                                 /* Text name to facilitate debugging.  The kernel does not use this itself. */
320                                                                   ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */
321                                                                   pdTRUE,                                     /* Auto-reload is set to true. */
322                                                                   ( void * ) xTimer,                          /* An identifier for the timer as all the auto-reload timers use the same callback. */
323                                                                   prvAutoReloadTimerCallback );               /* The callback executed when the timer expires. */
324
325     if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL )
326     {
327         xTestStatus = pdFAIL;
328         configASSERT( xTestStatus );
329     }
330     else
331     {
332         if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS )
333         {
334             /* This time it would not be expected that the timer could be
335              * started at this point. */
336             xTestStatus = pdFAIL;
337             configASSERT( xTestStatus );
338         }
339     }
340
341     /* Create the timers that are used from the tick interrupt to test the timer
342      * API functions that can be called from an ISR. */
343     xISRAutoReloadTimer = xTimerCreate( "ISR AR",                        /* The text name given to the timer. */
344                                         0xffff,                          /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */
345                                         pdTRUE,                          /* This is an auto-reload timer. */
346                                         ( void * ) NULL,                 /* The identifier is not required. */
347                                         prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */
348
349     xISROneShotTimer = xTimerCreate( "ISR OS",                           /* The text name given to the timer. */
350                                      0xffff,                             /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */
351                                      pdFALSE,                            /* This is a one-shot timer. */
352                                      ( void * ) NULL,                    /* The identifier is not required. */
353                                      prvISROneShotTimerCallback );       /* The callback that is executed when the timer expires. */
354
355     if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) )
356     {
357         xTestStatus = pdFAIL;
358         configASSERT( xTestStatus );
359     }
360 }
361 /*-----------------------------------------------------------*/
362
363 static void prvTest2_CheckTaskAndTimersInitialState( void )
364 {
365     uint8_t ucTimer;
366
367     /* Ensure all the timers are in their expected initial state.  This depends
368      * on the timer service task having a higher priority than this task.
369      *
370      * auto-reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active,
371      * and auto-reload timer configTIMER_QUEUE_LENGTH should not yet be active (it
372      * could not be started prior to the scheduler being started when it was
373      * created). */
374     for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
375     {
376         if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )
377         {
378             xTestStatus = pdFAIL;
379             configASSERT( xTestStatus );
380         }
381     }
382
383     if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE )
384     {
385         xTestStatus = pdFAIL;
386         configASSERT( xTestStatus );
387     }
388 }
389 /*-----------------------------------------------------------*/
390
391 static void prvTest3_CheckAutoReloadExpireRates( void )
392 {
393     uint8_t ucMaxAllowableValue, ucMinAllowableValue, ucTimer;
394     TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber;
395     UBaseType_t uxOriginalPriority;
396
397     /* Check the auto-reload timers expire at the expected rates.  Do this at a
398      * high priority for maximum accuracy.  This is ok as most of the time is spent
399      * in the Blocked state. */
400     uxOriginalPriority = uxTaskPriorityGet( NULL );
401     vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) );
402
403     /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow
404      * all the auto-reload timers to expire at least once. */
405     xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;
406     vTaskDelay( xBlockPeriod );
407
408     /* Check that all the auto-reload timers have called their callback
409      * function the expected number of times. */
410     for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
411     {
412         /* The expected number of expires is equal to the block period divided
413          * by the timer period. */
414         xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod );
415         xExpectedNumber = xBlockPeriod / xTimerPeriod;
416
417         ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber );
418         ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */
419
420         if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) ||
421             ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue )
422             )
423         {
424             xTestStatus = pdFAIL;
425             configASSERT( xTestStatus );
426         }
427     }
428
429     /* Return to the original priority. */
430     vTaskPrioritySet( NULL, uxOriginalPriority );
431
432     if( xTestStatus == pdPASS )
433     {
434         /* No errors have been reported so increment the loop counter so the
435          * check task knows this task is still running. */
436         ulLoopCounter++;
437     }
438 }
439 /*-----------------------------------------------------------*/
440
441 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void )
442 {
443     uint8_t ucTimer;
444
445     /* Check the auto-reload timers can be stopped correctly, and correctly
446      * report their state. */
447
448     /* Stop all the active timers. */
449     for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
450     {
451         /* The timer has not been stopped yet! */
452         if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )
453         {
454             xTestStatus = pdFAIL;
455             configASSERT( xTestStatus );
456         }
457
458         /* Now stop the timer.  This will appear to happen immediately to
459          * this task because this task is running at a priority below the
460          * timer service task. */
461         xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );
462
463         /* The timer should now be inactive. */
464         if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )
465         {
466             xTestStatus = pdFAIL;
467             configASSERT( xTestStatus );
468         }
469     }
470
471     taskENTER_CRITICAL();
472     {
473         /* The timer in array position configTIMER_QUEUE_LENGTH should not
474          * be active.  The critical section is used to ensure the timer does
475          * not call its callback between the next line running and the array
476          * being cleared back to zero, as that would mask an error condition. */
477         if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( uint8_t ) 0 )
478         {
479             xTestStatus = pdFAIL;
480             configASSERT( xTestStatus );
481         }
482
483         /* Clear the timer callback count. */
484         memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) );
485     }
486     taskEXIT_CRITICAL();
487
488     /* The timers are now all inactive, so this time, after delaying, none
489      * of the callback counters should have incremented. */
490     vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );
491
492     for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
493     {
494         if( ucAutoReloadTimerCounters[ ucTimer ] != ( uint8_t ) 0 )
495         {
496             xTestStatus = pdFAIL;
497             configASSERT( xTestStatus );
498         }
499     }
500
501     if( xTestStatus == pdPASS )
502     {
503         /* No errors have been reported so increment the loop counter so
504          * the check task knows this task is still running. */
505         ulLoopCounter++;
506     }
507 }
508 /*-----------------------------------------------------------*/
509
510 static void prvTest5_CheckBasicOneShotTimerBehaviour( void )
511 {
512     /* Check the one-shot timer only calls its callback once after it has been
513      * started, and that it reports its state correctly. */
514
515     /* The one-shot timer should not be active yet. */
516     if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )
517     {
518         xTestStatus = pdFAIL;
519         configASSERT( xTestStatus );
520     }
521
522     if( ucOneShotTimerCounter != ( uint8_t ) 0 )
523     {
524         xTestStatus = pdFAIL;
525         configASSERT( xTestStatus );
526     }
527
528     /* Start the one-shot timer and check that it reports its state correctly. */
529     xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );
530
531     if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )
532     {
533         xTestStatus = pdFAIL;
534         configASSERT( xTestStatus );
535     }
536
537     /* Delay for three times as long as the one-shot timer period, then check
538      * to ensure it has only called its callback once, and is now not in the
539      * active state. */
540     vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( TickType_t ) 3 );
541
542     if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )
543     {
544         xTestStatus = pdFAIL;
545         configASSERT( xTestStatus );
546     }
547
548     if( ucOneShotTimerCounter != ( uint8_t ) 1 )
549     {
550         xTestStatus = pdFAIL;
551         configASSERT( xTestStatus );
552     }
553     else
554     {
555         /* Reset the one-shot timer callback count. */
556         ucOneShotTimerCounter = ( uint8_t ) 0;
557     }
558
559     if( xTestStatus == pdPASS )
560     {
561         /* No errors have been reported so increment the loop counter so the
562          * check task knows this task is still running. */
563         ulLoopCounter++;
564     }
565 }
566 /*-----------------------------------------------------------*/
567
568 static void prvTest6_CheckAutoReloadResetBehaviour( void )
569 {
570     uint8_t ucTimer;
571
572     /* Check timer reset behaviour. */
573
574     /* Restart the one-shot timer and check it reports its status correctly. */
575     xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );
576
577     if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )
578     {
579         xTestStatus = pdFAIL;
580         configASSERT( xTestStatus );
581     }
582
583     /* Restart one of the auto-reload timers and check that it reports its
584      * status correctly. */
585     xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );
586
587     if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )
588     {
589         xTestStatus = pdFAIL;
590         configASSERT( xTestStatus );
591     }
592
593     for( ucTimer = 0; ucTimer < tmrdemoNUM_TIMER_RESETS; ucTimer++ )
594     {
595         /* Delay for half as long as the one-shot timer period, then reset it.
596          * It should never expire while this is done, so its callback count should
597          * never increment. */
598         vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 );
599
600         /* Check both running timers are still active, but have not called their
601          * callback functions. */
602         if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )
603         {
604             xTestStatus = pdFAIL;
605             configASSERT( xTestStatus );
606         }
607
608         if( ucOneShotTimerCounter != ( uint8_t ) 0 )
609         {
610             xTestStatus = pdFAIL;
611             configASSERT( xTestStatus );
612         }
613
614         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )
615         {
616             xTestStatus = pdFAIL;
617             configASSERT( xTestStatus );
618         }
619
620         if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( uint8_t ) 0 )
621         {
622             xTestStatus = pdFAIL;
623             configASSERT( xTestStatus );
624         }
625
626         /* Reset both running timers. */
627         xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );
628         xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );
629
630         if( xTestStatus == pdPASS )
631         {
632             /* No errors have been reported so increment the loop counter so
633              * the check task knows this task is still running. */
634             ulLoopCounter++;
635         }
636     }
637
638     /* Finally delay long enough for both running timers to expire. */
639     vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );
640
641     /* The timers were not reset during the above delay period so should now
642      * both have called their callback functions. */
643     if( ucOneShotTimerCounter != ( uint8_t ) 1 )
644     {
645         xTestStatus = pdFAIL;
646         configASSERT( xTestStatus );
647     }
648
649     if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 )
650     {
651         xTestStatus = pdFAIL;
652         configASSERT( xTestStatus );
653     }
654
655     /* The one-shot timer should no longer be active, while the auto-reload
656      * timer should still be active. */
657     if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )
658     {
659         xTestStatus = pdFAIL;
660         configASSERT( xTestStatus );
661     }
662
663     if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE )
664     {
665         xTestStatus = pdFAIL;
666         configASSERT( xTestStatus );
667     }
668
669     /* Stop the auto-reload timer again. */
670     xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );
671
672     if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )
673     {
674         xTestStatus = pdFAIL;
675         configASSERT( xTestStatus );
676     }
677
678     /* Clear the timer callback counts, ready for another iteration of these
679      * tests. */
680     ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( uint8_t ) 0;
681     ucOneShotTimerCounter = ( uint8_t ) 0;
682
683     if( xTestStatus == pdPASS )
684     {
685         /* No errors have been reported so increment the loop counter so the check
686          * task knows this task is still running. */
687         ulLoopCounter++;
688     }
689 }
690 /*-----------------------------------------------------------*/
691
692 static void prvTest7_CheckBacklogBehaviour( void )
693 {
694     /* Use the first auto-reload timer to test stopping a timer from a
695      * backlogged callback. */
696
697     /* The timer has not been started yet! */
698     if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE )
699     {
700         xTestStatus = pdFAIL;
701         configASSERT( xTestStatus );
702     }
703
704     /* Prompt the callback function to stop the timer. */
705     ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdTRUE;
706
707     /* Now start the timer.  This will appear to happen immediately to
708      * this task because this task is running at a priority below the timer
709      * service task.  Use a timer period of one tick so the call to
710      * xTaskCatchUpTicks() below has minimal impact on other tests that might
711      * be running. */
712 #define tmrdemoBACKLOG_TIMER_PERIOD    ( ( TickType_t ) 1 )
713     xTimerChangePeriod( xAutoReloadTimers[ 0 ], tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK );
714
715     /* The timer should now be active. */
716     if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) == pdFALSE )
717     {
718         xTestStatus = pdFAIL;
719         configASSERT( xTestStatus );
720     }
721
722     /* Arrange for the callback to execute late enough that it will execute
723      * twice, back-to-back.  The timer must handle the stop request properly
724      * in spite of the backlog of callbacks. */
725 #define tmrdemoEXPECTED_BACKLOG_EXPIRES    ( ( TickType_t ) 2 )
726     xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD * tmrdemoEXPECTED_BACKLOG_EXPIRES );
727
728     /* The timer should now be inactive. */
729     if( xTimerIsTimerActive( xAutoReloadTimers[ 0 ] ) != pdFALSE )
730     {
731         xTestStatus = pdFAIL;
732         configASSERT( xTestStatus );
733     }
734
735     /* Restore the standard timer period, and leave the timer inactive. */
736     xTimerChangePeriod( xAutoReloadTimers[ 0 ], xBasePeriod, tmrdemoDONT_BLOCK );
737     xTimerStop( xAutoReloadTimers[ 0 ], tmrdemoDONT_BLOCK );
738
739     /* Clear the reload count for the timer used in this test. */
740     ucAutoReloadTimerCounters[ 0 ] = ( uint8_t ) 0;
741
742     if( xTestStatus == pdPASS )
743     {
744         /* No errors have been reported so increment the loop counter so the check
745          * task knows this task is still running. */
746         ulLoopCounter++;
747     }
748 }
749 /*-----------------------------------------------------------*/
750
751 static void prvResetStartConditionsForNextIteration( void )
752 {
753     uint8_t ucTimer;
754
755     /* Start the timers again to start all the tests over again. */
756
757     /* Start the timers again. */
758     for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ )
759     {
760         /* The timer has not been started yet! */
761         if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )
762         {
763             xTestStatus = pdFAIL;
764             configASSERT( xTestStatus );
765         }
766
767         /* Now start the timer.  This will appear to happen immediately to
768          * this task because this task is running at a priority below the timer
769          * service task. */
770         xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );
771
772         /* The timer should now be active. */
773         if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )
774         {
775             xTestStatus = pdFAIL;
776             configASSERT( xTestStatus );
777         }
778     }
779
780     if( xTestStatus == pdPASS )
781     {
782         /* No errors have been reported so increment the loop counter so the
783          * check task knows this task is still running. */
784         ulLoopCounter++;
785     }
786 }
787 /*-----------------------------------------------------------*/
788
789 void vTimerPeriodicISRTests( void )
790 {
791     static TickType_t uxTick = ( TickType_t ) -1;
792
793     #if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) )
794
795         /* The timer service task is not the highest priority task, so it cannot
796          * be assumed that timings will be exact.  Timers should never call their
797          * callback before their expiry time, but a margin is permissible for calling
798          * their callback after their expiry time.  If exact timing is required then
799          * configTIMER_TASK_PRIORITY must be set to ensure the timer service task
800          * is the highest priority task in the system.
801          *
802          * This function is called from the tick hook.  The tick hook is called
803          * even when the scheduler is suspended.  Therefore it is possible that the
804          * uxTick count maintained in this function is temporarily ahead of the tick
805          * count maintained by the kernel.  When this is the case a message posted from
806          * this function will assume a time stamp in advance of the real time stamp,
807          * which can result in a timer being processed before this function expects it
808          * to.  For example, if the kernel's tick count was 100, and uxTick was 102,
809          * then this function will not expect the timer to have expired until the
810          * kernel's tick count is (102 + xBasePeriod), whereas in reality the timer
811          * will expire when the kernel's tick count is (100 + xBasePeriod).  For this
812          * reason xMargin is used as an allowable margin for premature timer expires
813          * as well as late timer expires. */
814         #ifdef _WINDOWS_
815             /* Windows is not real real time. */
816             const TickType_t xMargin = 20;
817         #else
818             const TickType_t xMargin = 6;
819         #endif /* _WINDOWS_ */
820     #else
821         #ifdef _WINDOWS_
822             /* Windows is not real real time. */
823             const TickType_t xMargin = 20;
824         #else
825             const TickType_t xMargin = 4;
826         #endif /* _WINDOWS_ */
827     #endif /* if ( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) */
828
829
830     uxTick++;
831
832     if( uxTick == 0 )
833     {
834         /* The timers will have been created, but not started.  Start them now
835          * by setting their period. */
836         ucISRAutoReloadTimerCounter = 0;
837         ucISROneShotTimerCounter = 0;
838
839         /* It is possible that the timer task has not yet made room in the
840          * timer queue.  If the timers cannot be started then reset uxTick so
841          * another attempt is made later. */
842         uxTick = ( TickType_t ) -1;
843
844         /* Try starting first timer. */
845         if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, NULL ) == pdPASS )
846         {
847             /* First timer was started, try starting the second timer. */
848             if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS )
849             {
850                 /* Both timers were started, so set the uxTick back to its
851                  * proper value. */
852                 uxTick = 0;
853             }
854             else
855             {
856                 /* Second timer could not be started, so stop the first one
857                  * again. */
858                 xTimerStopFromISR( xISRAutoReloadTimer, NULL );
859             }
860         }
861     }
862     else if( uxTick == ( xBasePeriod - xMargin ) )
863     {
864         /* Neither timer should have expired yet. */
865         if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) )
866         {
867             xTestStatus = pdFAIL;
868             configASSERT( xTestStatus );
869         }
870     }
871     else if( uxTick == ( xBasePeriod + xMargin ) )
872     {
873         /* Both timers should now have expired once.  The auto-reload timer will
874          * still be active, but the one-shot timer should now have stopped. */
875         if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )
876         {
877             xTestStatus = pdFAIL;
878             configASSERT( xTestStatus );
879         }
880     }
881     else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) )
882     {
883         /* The auto-reload timer will still be active, but the one-shot timer
884          * should now have stopped - however, at this time neither of the timers
885          * should have expired again since the last test. */
886         if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )
887         {
888             xTestStatus = pdFAIL;
889             configASSERT( xTestStatus );
890         }
891     }
892     else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) )
893     {
894         /* The auto-reload timer will still be active, but the one-shot timer
895          * should now have stopped.  At this time the auto-reload timer should have
896          * expired again, but the one-shot timer count should not have changed. */
897         if( ucISRAutoReloadTimerCounter != 2 )
898         {
899             xTestStatus = pdFAIL;
900             configASSERT( xTestStatus );
901         }
902
903         if( ucISROneShotTimerCounter != 1 )
904         {
905             xTestStatus = pdFAIL;
906             configASSERT( xTestStatus );
907         }
908     }
909     else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( TickType_t ) 2U ) ) )
910     {
911         /* The auto-reload timer will still be active, but the one-shot timer
912          * should now have stopped.  Again though, at this time, neither timer call
913          * back should have been called since the last test. */
914         if( ucISRAutoReloadTimerCounter != 2 )
915         {
916             xTestStatus = pdFAIL;
917             configASSERT( xTestStatus );
918         }
919
920         if( ucISROneShotTimerCounter != 1 )
921         {
922             xTestStatus = pdFAIL;
923             configASSERT( xTestStatus );
924         }
925     }
926     else if( uxTick == ( 3 * xBasePeriod ) )
927     {
928         /* Start the one-shot timer again. */
929         xTimerStartFromISR( xISROneShotTimer, NULL );
930     }
931     else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) )
932     {
933         /* The auto-reload timer and one-shot timer will be active.  At
934          * this time the auto-reload timer should have  expired again, but the one
935          * shot timer count should not have changed yet. */
936         if( ucISRAutoReloadTimerCounter != 3 )
937         {
938             xTestStatus = pdFAIL;
939             configASSERT( xTestStatus );
940         }
941
942         if( ucISROneShotTimerCounter != 1 )
943         {
944             xTestStatus = pdFAIL;
945             configASSERT( xTestStatus );
946         }
947
948         /* Now stop the auto-reload timer.  The one-shot timer was started
949          * a few ticks ago. */
950         xTimerStopFromISR( xISRAutoReloadTimer, NULL );
951     }
952     else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) )
953     {
954         /* The auto-reload timer is now stopped, and the one-shot timer is
955          * active, but at this time neither timer should have expired since the
956          * last test. */
957         if( ucISRAutoReloadTimerCounter != 3 )
958         {
959             xTestStatus = pdFAIL;
960             configASSERT( xTestStatus );
961         }
962
963         if( ucISROneShotTimerCounter != 1 )
964         {
965             xTestStatus = pdFAIL;
966             configASSERT( xTestStatus );
967         }
968     }
969     else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) )
970     {
971         /* The auto-reload timer is now stopped, and the one-shot timer is
972          * active.  The one-shot timer should have expired again, but the auto
973          * reload timer should not have executed its callback. */
974         if( ucISRAutoReloadTimerCounter != 3 )
975         {
976             xTestStatus = pdFAIL;
977             configASSERT( xTestStatus );
978         }
979
980         if( ucISROneShotTimerCounter != 2 )
981         {
982             xTestStatus = pdFAIL;
983             configASSERT( xTestStatus );
984         }
985     }
986     else if( uxTick == ( 8 * xBasePeriod ) )
987     {
988         /* The auto-reload timer is now stopped, and the one-shot timer has
989          * already expired and then stopped itself.  Both callback counters should
990          * not have incremented since the last test. */
991         if( ucISRAutoReloadTimerCounter != 3 )
992         {
993             xTestStatus = pdFAIL;
994             configASSERT( xTestStatus );
995         }
996
997         if( ucISROneShotTimerCounter != 2 )
998         {
999             xTestStatus = pdFAIL;
1000             configASSERT( xTestStatus );
1001         }
1002
1003         /* Now reset the one-shot timer. */
1004         xTimerResetFromISR( xISROneShotTimer, NULL );
1005     }
1006     else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) )
1007     {
1008         /* Only the one-shot timer should be running, but it should not have
1009          * expired since the last test.  Check the callback counters have not
1010          * incremented, then reset the one-shot timer again. */
1011         if( ucISRAutoReloadTimerCounter != 3 )
1012         {
1013             xTestStatus = pdFAIL;
1014             configASSERT( xTestStatus );
1015         }
1016
1017         if( ucISROneShotTimerCounter != 2 )
1018         {
1019             xTestStatus = pdFAIL;
1020             configASSERT( xTestStatus );
1021         }
1022
1023         xTimerResetFromISR( xISROneShotTimer, NULL );
1024     }
1025     else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) )
1026     {
1027         /* Only the one-shot timer should be running, but it should not have
1028          * expired since the last test.  Check the callback counters have not
1029          * incremented, then reset the one-shot timer again. */
1030         if( ucISRAutoReloadTimerCounter != 3 )
1031         {
1032             xTestStatus = pdFAIL;
1033             configASSERT( xTestStatus );
1034         }
1035
1036         if( ucISROneShotTimerCounter != 2 )
1037         {
1038             xTestStatus = pdFAIL;
1039             configASSERT( xTestStatus );
1040         }
1041
1042         xTimerResetFromISR( xISROneShotTimer, NULL );
1043     }
1044     else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) )
1045     {
1046         /* Only the one-shot timer should be running, but it should not have
1047          * expired since the last test.  Check the callback counters have not
1048          * incremented, then reset the one-shot timer once again. */
1049         if( ucISRAutoReloadTimerCounter != 3 )
1050         {
1051             xTestStatus = pdFAIL;
1052             configASSERT( xTestStatus );
1053         }
1054
1055         if( ucISROneShotTimerCounter != 2 )
1056         {
1057             xTestStatus = pdFAIL;
1058             configASSERT( xTestStatus );
1059         }
1060
1061         xTimerResetFromISR( xISROneShotTimer, NULL );
1062     }
1063     else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) )
1064     {
1065         /* Only the one-shot timer should have been running and this time it
1066          * should have  expired.  Check its callback count has been incremented.
1067          * The auto-reload      timer is still not running so should still have the same
1068          * count value.  This time the one-shot timer is not reset so should not
1069          * restart from its expiry period again. */
1070         if( ucISRAutoReloadTimerCounter != 3 )
1071         {
1072             xTestStatus = pdFAIL;
1073             configASSERT( xTestStatus );
1074         }
1075
1076         if( ucISROneShotTimerCounter != 3 )
1077         {
1078             xTestStatus = pdFAIL;
1079             configASSERT( xTestStatus );
1080         }
1081     }
1082     else if( uxTick == ( 15 * xBasePeriod ) )
1083     {
1084         /* Neither timer should be running now.  Check neither callback count
1085          * has incremented, then go back to the start to run these tests all
1086          * over again. */
1087         if( ucISRAutoReloadTimerCounter != 3 )
1088         {
1089             xTestStatus = pdFAIL;
1090             configASSERT( xTestStatus );
1091         }
1092
1093         if( ucISROneShotTimerCounter != 3 )
1094         {
1095             xTestStatus = pdFAIL;
1096             configASSERT( xTestStatus );
1097         }
1098
1099         uxTick = ( TickType_t ) -1;
1100     }
1101 }
1102 /*-----------------------------------------------------------*/
1103
1104 /*** Timer callback functions are defined below here. ***/
1105
1106 static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer )
1107 {
1108     size_t uxTimerID;
1109
1110     uxTimerID = ( size_t ) pvTimerGetTimerID( pxExpiredTimer );
1111
1112     if( uxTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) )
1113     {
1114         ( ucAutoReloadTimerCounters[ uxTimerID ] )++;
1115
1116         /* Stop timer ID 0 if requested. */
1117         if( ( uxTimerID == ( size_t ) 0 ) && ( ucIsStopNeededInTimerZeroCallback == ( uint8_t ) pdTRUE ) )
1118         {
1119             xTimerStop( pxExpiredTimer, tmrdemoDONT_BLOCK );
1120             ucIsStopNeededInTimerZeroCallback = ( uint8_t ) pdFALSE;
1121         }
1122     }
1123     else
1124     {
1125         /* The timer ID appears to be unexpected (invalid). */
1126         xTestStatus = pdFAIL;
1127         configASSERT( xTestStatus );
1128     }
1129 }
1130 /*-----------------------------------------------------------*/
1131
1132 static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer )
1133 {
1134 /* A count is kept of the number of times this callback function is executed.
1135  * The count is stored as the timer's ID.  This is only done to test the
1136  * vTimerSetTimerID() function. */
1137     static size_t uxCallCount = 0;
1138     size_t uxLastCallCount;
1139
1140     /* Obtain the timer's ID, which should be a count of the number of times
1141      * this callback function has been executed. */
1142     uxLastCallCount = ( size_t ) pvTimerGetTimerID( pxExpiredTimer );
1143     configASSERT( uxLastCallCount == uxCallCount );
1144
1145     /* Increment the call count, then save it back as the timer's ID.  This is
1146      * only done to test the vTimerSetTimerID() API function. */
1147     uxLastCallCount++;
1148     vTimerSetTimerID( pxExpiredTimer, ( void * ) uxLastCallCount );
1149     uxCallCount++;
1150
1151     ucOneShotTimerCounter++;
1152 }
1153 /*-----------------------------------------------------------*/
1154
1155 static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer )
1156 {
1157     /* The parameter is not used in this case as only one timer uses this
1158      * callback function. */
1159     ( void ) pxExpiredTimer;
1160
1161     ucISRAutoReloadTimerCounter++;
1162 }
1163 /*-----------------------------------------------------------*/
1164
1165 static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer )
1166 {
1167     /* The parameter is not used in this case as only one timer uses this
1168      * callback function. */
1169     ( void ) pxExpiredTimer;
1170
1171     ucISROneShotTimerCounter++;
1172 }
1173 /*-----------------------------------------------------------*/