]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Minimal/TimerDemo.c
Add additional critical section to the default tickless implementations.
[freertos] / FreeRTOS / Demo / Common / Minimal / TimerDemo.c
1 /*\r
2     FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
5 \r
6     ***************************************************************************\r
7      *                                                                       *\r
8      *    FreeRTOS provides completely free yet professionally developed,    *\r
9      *    robust, strictly quality controlled, supported, and cross          *\r
10      *    platform software that has become a de facto standard.             *\r
11      *                                                                       *\r
12      *    Help yourself get started quickly and support the FreeRTOS         *\r
13      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
14      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
15      *                                                                       *\r
16      *    Thank you!                                                         *\r
17      *                                                                       *\r
18     ***************************************************************************\r
19 \r
20     This file is part of the FreeRTOS distribution.\r
21 \r
22     FreeRTOS is free software; you can redistribute it and/or modify it under\r
23     the terms of the GNU General Public License (version 2) as published by the\r
24     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
25 \r
26     >>! NOTE: The modification to the GPL is included to allow you to distribute\r
27     >>! a combined work that includes FreeRTOS without being obliged to provide\r
28     >>! the source code for proprietary components outside of the FreeRTOS\r
29     >>! kernel.\r
30 \r
31     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
32     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
33     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
34     link: http://www.freertos.org/a00114.html\r
35 \r
36     1 tab == 4 spaces!\r
37 \r
38     ***************************************************************************\r
39      *                                                                       *\r
40      *    Having a problem?  Start by reading the FAQ "My application does   *\r
41      *    not run, what could be wrong?"                                     *\r
42      *                                                                       *\r
43      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
44      *                                                                       *\r
45     ***************************************************************************\r
46 \r
47     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
48     license and Real Time Engineers Ltd. contact details.\r
49 \r
50     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
51     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
52     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
53 \r
54     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
55     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
56     licenses offer ticketed support, indemnification and middleware.\r
57 \r
58     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
59     engineered and independently SIL3 certified version for use in safety and\r
60     mission critical applications that require provable dependability.\r
61 \r
62     1 tab == 4 spaces!\r
63 */\r
64 \r
65 \r
66 /*\r
67  * Tests the behaviour of timers.  Some timers are created before the scheduler\r
68  * is started, and some after.\r
69  */\r
70 \r
71 /* Standard includes. */\r
72 #include <string.h>\r
73 \r
74 /* Scheduler include files. */\r
75 #include "FreeRTOS.h"\r
76 #include "task.h"\r
77 #include "timers.h"\r
78 \r
79 /* Demo program include files. */\r
80 #include "TimerDemo.h"\r
81 \r
82 #if ( configTIMER_TASK_PRIORITY < 1 )\r
83         #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly.\r
84 #endif\r
85 \r
86 #define tmrdemoDONT_BLOCK                               ( ( portTickType ) 0 )\r
87 #define tmrdemoONE_SHOT_TIMER_PERIOD    ( xBasePeriod * ( portTickType ) 3 )\r
88 #define trmdemoNUM_TIMER_RESETS                 ( ( unsigned char ) 10 )\r
89 \r
90 /*-----------------------------------------------------------*/\r
91 \r
92 /* The callback functions used by the timers.  These each increment a counter\r
93 to indicate which timer has expired.  The auto-reload timers that are used by\r
94 the test task (as opposed to being used from an ISR) all share the same\r
95 prvAutoReloadTimerCallback() callback function, and use the ID of the\r
96 pxExpiredTimer parameter passed into that function to know which counter to\r
97 increment.  The other timers all have their own unique callback function and\r
98 simply increment their counters without using the callback function parameter. */\r
99 static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer );\r
100 static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer );\r
101 static void prvTimerTestTask( void *pvParameters );\r
102 static void prvISRAutoReloadTimerCallback( xTimerHandle pxExpiredTimer );\r
103 static void prvISROneShotTimerCallback( xTimerHandle pxExpiredTimer );\r
104 \r
105 /* The test functions used by the timer test task.  These manipulate the auto\r
106 reload and one shot timers in various ways, then delay, then inspect the timers\r
107 to ensure they have behaved as expected. */\r
108 static void prvTest1_CreateTimersWithoutSchedulerRunning( void );\r
109 static void prvTest2_CheckTaskAndTimersInitialState( void );\r
110 static void     prvTest3_CheckAutoReloadExpireRates( void );\r
111 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void );\r
112 static void prvTest5_CheckBasicOneShotTimerBehaviour( void );\r
113 static void prvTest6_CheckAutoReloadResetBehaviour( void );\r
114 static void prvResetStartConditionsForNextIteration( void );\r
115 \r
116 /*-----------------------------------------------------------*/\r
117 \r
118 /* Flag that will be latched to pdFAIL should any unexpected behaviour be\r
119 detected in any of the demo tests. */\r
120 static volatile portBASE_TYPE xTestStatus = pdPASS;\r
121 \r
122 /* Counter that is incremented on each cycle of a test.  This is used to\r
123 detect a stalled task - a test that is no longer running. */\r
124 static volatile unsigned long ulLoopCounter = 0;\r
125 \r
126 /* A set of auto reload timers - each of which use the same callback function.\r
127 The callback function uses the timer ID to index into, and then increment, a\r
128 counter in the ucAutoReloadTimerCounters[] array.  The auto reload timers\r
129 referenced from xAutoReloadTimers[] are used by the prvTimerTestTask task. */\r
130 static xTimerHandle xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
131 static unsigned char ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
132 \r
133 /* The one shot timer is configured to use a callback function that increments\r
134 ucOneShotTimerCounter each time it gets called. */\r
135 static xTimerHandle xOneShotTimer = NULL;\r
136 static unsigned char ucOneShotTimerCounter = ( unsigned char ) 0;\r
137 \r
138 /* The ISR reload timer is controlled from the tick hook to exercise the timer\r
139 API functions that can be used from an ISR.  It is configured to increment\r
140 ucISRReloadTimerCounter each time its callback function is executed. */\r
141 static xTimerHandle xISRAutoReloadTimer = NULL;\r
142 static unsigned char ucISRAutoReloadTimerCounter = ( unsigned char ) 0;\r
143 \r
144 /* The ISR one shot timer is controlled from the tick hook to exercise the timer\r
145 API functions that can be used from an ISR.  It is configured to increment\r
146 ucISRReloadTimerCounter each time its callback function is executed. */\r
147 static xTimerHandle xISROneShotTimer = NULL;\r
148 static unsigned char ucISROneShotTimerCounter = ( unsigned char ) 0;\r
149 \r
150 /* The period of all the timers are a multiple of the base period.  The base\r
151 period is configured by the parameter to vStartTimerDemoTask(). */\r
152 static portTickType xBasePeriod = 0;\r
153 \r
154 /*-----------------------------------------------------------*/\r
155 \r
156 void vStartTimerDemoTask( portTickType xBasePeriodIn )\r
157 {\r
158         /* Start with the timer and counter arrays clear - this is only necessary\r
159         where the compiler does not clear them automatically on start up. */\r
160         memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) );\r
161         memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) );\r
162 \r
163         /* Store the period from which all the timer periods will be generated from\r
164         (multiples of). */\r
165         xBasePeriod = xBasePeriodIn;\r
166 \r
167         /* Create a set of timers for use by this demo/test. */\r
168         prvTest1_CreateTimersWithoutSchedulerRunning();\r
169 \r
170         /* Create the task that will control and monitor the timers.  This is\r
171         created at a lower priority than the timer service task to ensure, as\r
172         far as it is concerned, commands on timers are actioned immediately\r
173         (sending a command to the timer service task will unblock the timer service\r
174         task, which will then preempt this task). */\r
175         if( xTestStatus != pdFAIL )\r
176         {\r
177                 xTaskCreate( prvTimerTestTask, ( signed portCHAR * ) "Tmr Tst", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL );\r
178         }\r
179 }\r
180 /*-----------------------------------------------------------*/\r
181 \r
182 static void prvTimerTestTask( void *pvParameters )\r
183 {\r
184         ( void ) pvParameters;\r
185 \r
186         /* Create a one-shot timer for use later on in this test. */\r
187         xOneShotTimer = xTimerCreate(   ( const signed char * ) "Oneshot Timer",/* Text name to facilitate debugging.  The kernel does not use this itself. */\r
188                                                                         tmrdemoONE_SHOT_TIMER_PERIOD,                   /* The period for the timer. */\r
189                                                                         pdFALSE,                                                                /* Don't auto-reload - hence a one shot timer. */\r
190                                                                         ( void * ) 0,                                                   /* The timer identifier.  In this case this is not used as the timer has its own callback. */\r
191                                                                         prvOneShotTimerCallback );                              /* The callback to be called when the timer expires. */\r
192 \r
193         if( xOneShotTimer == NULL )\r
194         {\r
195                 xTestStatus = pdFAIL;\r
196                 configASSERT( xTestStatus );\r
197         }\r
198 \r
199 \r
200         /* Ensure all the timers are in their expected initial state.  This\r
201         depends on the timer service task having a higher priority than this task. */\r
202         prvTest2_CheckTaskAndTimersInitialState();\r
203 \r
204         for( ;; )\r
205         {\r
206                 /* Check the auto reload timers expire at the expected/correct rates. */\r
207                 prvTest3_CheckAutoReloadExpireRates();\r
208 \r
209                 /* Check the auto reload timers can be stopped correctly, and correctly\r
210                 report their state. */\r
211                 prvTest4_CheckAutoReloadTimersCanBeStopped();\r
212                                 \r
213                 /* Check the one shot timer only calls its callback once after it has been\r
214                 started, and that it reports its state correctly. */\r
215                 prvTest5_CheckBasicOneShotTimerBehaviour();\r
216 \r
217                 /* Check timer reset behaviour. */\r
218                 prvTest6_CheckAutoReloadResetBehaviour();\r
219 \r
220                 /* Start the timers again to restart all the tests over again. */\r
221                 prvResetStartConditionsForNextIteration();\r
222         }\r
223 }\r
224 /*-----------------------------------------------------------*/\r
225 \r
226 /* This is called to check that the created task is still running and has not\r
227 detected any errors. */\r
228 portBASE_TYPE xAreTimerDemoTasksStillRunning( portTickType xCycleFrequency )\r
229 {\r
230 static unsigned long ulLastLoopCounter = 0UL;\r
231 portTickType xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax;\r
232 static portTickType xIterationsWithoutCounterIncrement = ( portTickType ) 0, xLastCycleFrequency;\r
233 \r
234         if( xLastCycleFrequency != xCycleFrequency )\r
235         {\r
236                 /* The cycle frequency has probably become much faster due to an error\r
237                 elsewhere.  Start counting Iterations again. */\r
238                 xIterationsWithoutCounterIncrement = ( portTickType ) 0;\r
239                 xLastCycleFrequency = xCycleFrequency;\r
240         }               \r
241 \r
242         /* Calculate the maximum number of times that it is permissible for this\r
243         function to be called without ulLoopCounter being incremented.  This is\r
244         necessary because the tests in this file block for extended periods, and the\r
245         block period might be longer than the time between calls to this function. */\r
246         xMaxBlockTimeUsedByTheseTests = ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;\r
247         xLoopCounterIncrementTimeMax = xMaxBlockTimeUsedByTheseTests / xCycleFrequency;\r
248 \r
249         /* If the demo task is still running then we expect the loopcounter to\r
250         have incremented every xLoopCounterIncrementTimeMax calls. */\r
251         if( ulLastLoopCounter == ulLoopCounter )\r
252         {\r
253                 xIterationsWithoutCounterIncrement++;\r
254                 if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax )\r
255                 {\r
256                         /* The tests appear to be no longer running (stalled). */\r
257                         xTestStatus = pdFAIL;\r
258                         configASSERT( xTestStatus );\r
259                 }\r
260         }\r
261         else\r
262         {\r
263                 /* ulLoopCounter changed, so the count of times this function was called\r
264                 without a change can be reset to zero. */\r
265                 xIterationsWithoutCounterIncrement = ( portTickType ) 0;\r
266         }\r
267 \r
268         ulLastLoopCounter = ulLoopCounter;\r
269 \r
270         /* Errors detected in the task itself will have latched xTestStatus\r
271         to pdFAIL. */\r
272 \r
273         return xTestStatus;\r
274 }\r
275 /*-----------------------------------------------------------*/\r
276 \r
277 static void prvTest1_CreateTimersWithoutSchedulerRunning( void )\r
278 {\r
279 unsigned portBASE_TYPE xTimer;\r
280 \r
281         for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )\r
282         {\r
283                 /* As the timer queue is not yet full, it should be possible to both create\r
284                 and start a timer.  These timers are being started before the scheduler has\r
285                 been started, so their block times should get set to zero within the timer\r
286                 API itself. */\r
287                 xAutoReloadTimers[ xTimer ] = xTimerCreate( ( const signed char * )"FR Timer",  /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
288                                                                                                         ( ( xTimer + ( portTickType ) 1 ) * xBasePeriod ),/* The period for the timer.  The plus 1 ensures a period of zero is not specified. */\r
289                                                                                                         pdTRUE,                                                         /* Auto-reload is set to true. */\r
290                                                                                                         ( void * ) xTimer,                                      /* An identifier for the timer as all the auto reload timers use the same callback. */\r
291                                                                                                         prvAutoReloadTimerCallback );           /* The callback to be called when the timer expires. */\r
292 \r
293                 if( xAutoReloadTimers[ xTimer ] == NULL )\r
294                 {\r
295                         xTestStatus = pdFAIL;\r
296                         configASSERT( xTestStatus );\r
297                 }\r
298                 else\r
299                 {\r
300                         /* The scheduler has not yet started, so the block period of\r
301                         portMAX_DELAY should just get set to zero in xTimerStart().  Also,\r
302                         the timer queue is not yet full so xTimerStart() should return\r
303                         pdPASS. */\r
304                         if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS )\r
305                         {\r
306                                 xTestStatus = pdFAIL;\r
307                                 configASSERT( xTestStatus );\r
308                         }\r
309                 }\r
310         }\r
311 \r
312         /* The timers queue should now be full, so it should be possible to create\r
313         another timer, but not possible to start it (the timer queue will not get\r
314         drained until the scheduler has been started. */\r
315         xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( ( const signed char * ) "FR Timer",       /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
316                                                                                                         ( configTIMER_QUEUE_LENGTH * xBasePeriod ),                     /* The period for the timer. */\r
317                                                                                                         pdTRUE,                                                                                         /* Auto-reload is set to true. */\r
318                                                                                                         ( void * ) xTimer,                                                                      /* An identifier for the timer as all the auto reload timers use the same callback. */\r
319                                                                                                         prvAutoReloadTimerCallback );                                           /* The callback executed when the timer expires. */\r
320 \r
321         if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL )\r
322         {\r
323                 xTestStatus = pdFAIL;\r
324                 configASSERT( xTestStatus );\r
325         }\r
326         else\r
327         {\r
328                 if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS )\r
329                 {\r
330                         /* This time it would not be expected that the timer could be\r
331                         started at this point. */\r
332                         xTestStatus = pdFAIL;\r
333                         configASSERT( xTestStatus );\r
334                 }\r
335         }\r
336         \r
337         /* Create the timers that are used from the tick interrupt to test the timer\r
338         API functions that can be called from an ISR. */\r
339         xISRAutoReloadTimer = xTimerCreate( ( const signed char * ) "ISR AR",   /* The text name given to the timer. */\r
340                                                                                 0xffff,                                                         /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */\r
341                                                                                 pdTRUE,                                                         /* This is an auto reload timer. */\r
342                                                                                 ( void * ) NULL,                                        /* The identifier is not required. */\r
343                                                                                 prvISRAutoReloadTimerCallback );        /* The callback that is executed when the timer expires. */\r
344 \r
345         xISROneShotTimer = xTimerCreate(        ( const signed char * ) "ISR OS",       /* The text name given to the timer. */\r
346                                                                                 0xffff,                                                         /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */\r
347                                                                                 pdFALSE,                                                        /* This is a one shot timer. */\r
348                                                                                 ( void * ) NULL,                                        /* The identifier is not required. */\r
349                                                                                 prvISROneShotTimerCallback );           /* The callback that is executed when the timer expires. */\r
350                                                                                 \r
351         if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) )\r
352         {\r
353                 xTestStatus = pdFAIL;\r
354                 configASSERT( xTestStatus );\r
355         }\r
356 }\r
357 /*-----------------------------------------------------------*/\r
358 \r
359 static void prvTest2_CheckTaskAndTimersInitialState( void )\r
360 {\r
361 unsigned char ucTimer;\r
362 \r
363         /* Ensure all the timers are in their expected initial state.  This     depends\r
364         on the timer service task having a higher priority than this task.\r
365 \r
366         auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active,\r
367         and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it\r
368         could not be started prior to the scheduler being started when it was\r
369         created). */\r
370         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
371         {\r
372                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
373                 {\r
374                         xTestStatus = pdFAIL;\r
375                         configASSERT( xTestStatus );\r
376                 }\r
377         }\r
378 \r
379         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE )\r
380         {\r
381                 xTestStatus = pdFAIL;\r
382                 configASSERT( xTestStatus );\r
383         }\r
384 }\r
385 /*-----------------------------------------------------------*/\r
386 \r
387 static void     prvTest3_CheckAutoReloadExpireRates( void )\r
388 {\r
389 unsigned char ucMaxAllowableValue, ucMinAllowableValue, ucTimer;\r
390 portTickType xBlockPeriod, xTimerPeriod, xExpectedNumber;\r
391 \r
392         /* Check the auto reload timers expire at the expected rates. */\r
393 \r
394         \r
395         /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow\r
396         all the auto reload timers to expire at least once. */\r
397         xBlockPeriod = ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod;\r
398         vTaskDelay( xBlockPeriod );\r
399 \r
400         /* Check that all the auto reload timers have called their callback     \r
401         function the expected number of times. */\r
402         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
403         {\r
404                 /* The expected number of expiries is equal to the block period divided\r
405                 by the timer period. */\r
406                 xTimerPeriod = ( ( ( portTickType ) ucTimer + ( portTickType ) 1 ) * xBasePeriod );\r
407                 xExpectedNumber = xBlockPeriod / xTimerPeriod;\r
408                 \r
409                 ucMaxAllowableValue = ( ( unsigned char ) xExpectedNumber ) ;\r
410                 ucMinAllowableValue = ( ( unsigned char ) xExpectedNumber - ( unsigned char ) 1 );\r
411 \r
412                 if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) ||\r
413                         ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue )\r
414                         )\r
415                 {\r
416                         xTestStatus = pdFAIL;\r
417                         configASSERT( xTestStatus );\r
418                 }\r
419         }\r
420 \r
421         if( xTestStatus == pdPASS )\r
422         {\r
423                 /* No errors have been reported so increment the loop counter so the\r
424                 check task knows this task is still running. */\r
425                 ulLoopCounter++;\r
426         }\r
427 }\r
428 /*-----------------------------------------------------------*/\r
429 \r
430 static void prvTest4_CheckAutoReloadTimersCanBeStopped( void )\r
431 {               \r
432 unsigned char ucTimer;\r
433 \r
434         /* Check the auto reload timers can be stopped correctly, and correctly\r
435         report their state. */\r
436 \r
437         /* Stop all the active timers. */\r
438         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
439         {\r
440                 /* The timer has not been stopped yet! */\r
441                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
442                 {\r
443                         xTestStatus = pdFAIL;\r
444                         configASSERT( xTestStatus );\r
445                 }\r
446 \r
447                 /* Now stop the timer.  This will appear to happen immediately to\r
448                 this task because this task is running at a priority below the\r
449                 timer service task. */\r
450                 xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
451 \r
452                 /* The timer should now be inactive. */\r
453                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
454                 {\r
455                         xTestStatus = pdFAIL;\r
456                         configASSERT( xTestStatus );\r
457                 }\r
458         }\r
459 \r
460         taskENTER_CRITICAL();\r
461         {\r
462                 /* The timer in array position configTIMER_QUEUE_LENGTH should not\r
463                 be active.  The critical section is used to ensure the timer does\r
464                 not call its callback between the next line running and the array\r
465                 being cleared back to zero, as that would mask an error condition. */\r
466                 if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( unsigned char ) 0 )\r
467                 {\r
468                         xTestStatus = pdFAIL;\r
469                         configASSERT( xTestStatus );\r
470                 }\r
471 \r
472                 /* Clear the timer callback count. */\r
473                 memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) );\r
474         }\r
475         taskEXIT_CRITICAL();\r
476 \r
477         /* The timers are now all inactive, so this time, after delaying, none\r
478         of the callback counters should have incremented. */\r
479         vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
480         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
481         {\r
482                 if( ucAutoReloadTimerCounters[ ucTimer ] != ( unsigned char ) 0 )\r
483                 {\r
484                         xTestStatus = pdFAIL;\r
485                         configASSERT( xTestStatus );\r
486                 }\r
487         }\r
488 \r
489         if( xTestStatus == pdPASS )\r
490         {\r
491                 /* No errors have been reported so increment the loop counter so\r
492                 the check task knows this task is still running. */\r
493                 ulLoopCounter++;\r
494         }\r
495 }\r
496 /*-----------------------------------------------------------*/\r
497 \r
498 static void prvTest5_CheckBasicOneShotTimerBehaviour( void )\r
499 {\r
500         /* Check the one shot timer only calls its callback once after it has been\r
501         started, and that it reports its state correctly. */\r
502 \r
503         /* The one shot timer should not be active yet. */\r
504         if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
505         {\r
506                 xTestStatus = pdFAIL;\r
507                 configASSERT( xTestStatus );\r
508         }\r
509 \r
510         if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
511         {\r
512                 xTestStatus = pdFAIL;\r
513                 configASSERT( xTestStatus );\r
514         }\r
515 \r
516         /* Start the one shot timer and check that it reports its state correctly. */\r
517         xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
518         if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
519         {\r
520                 xTestStatus = pdFAIL;\r
521                 configASSERT( xTestStatus );\r
522         }\r
523 \r
524         /* Delay for three times as long as the one shot timer period, then check\r
525         to ensure it has only called its callback once, and is now not in the\r
526         active state. */\r
527         vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( portTickType ) 3 );\r
528 \r
529         if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
530         {\r
531                 xTestStatus = pdFAIL;\r
532                 configASSERT( xTestStatus );\r
533         }\r
534 \r
535         if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
536         {\r
537                 xTestStatus = pdFAIL;\r
538                 configASSERT( xTestStatus );\r
539         }\r
540         else\r
541         {\r
542                 /* Reset the one shot timer callback count. */\r
543                 ucOneShotTimerCounter = ( unsigned char ) 0;\r
544         }\r
545 \r
546         if( xTestStatus == pdPASS )\r
547         {\r
548                 /* No errors have been reported so increment the loop counter so the\r
549                 check task knows this task is still running. */\r
550                 ulLoopCounter++;\r
551         }\r
552 }\r
553 /*-----------------------------------------------------------*/\r
554 \r
555 static void prvTest6_CheckAutoReloadResetBehaviour( void )\r
556 {\r
557 unsigned char ucTimer;\r
558 \r
559         /* Check timer reset behaviour. */\r
560 \r
561         /* Restart the one shot timer and check it reports its status correctly. */\r
562         xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
563         if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
564         {\r
565                 xTestStatus = pdFAIL;\r
566                 configASSERT( xTestStatus );\r
567         }\r
568 \r
569         /* Restart one of the auto reload timers and check that it reports its\r
570         status correctly. */\r
571         xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
572         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
573         {\r
574                 xTestStatus = pdFAIL;\r
575                 configASSERT( xTestStatus );\r
576         }\r
577 \r
578         for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ )\r
579         {\r
580                 /* Delay for half as long as the one shot timer period, then reset it.\r
581                 It should never expire while this is done, so its callback count should\r
582                 never increment. */\r
583                 vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 );\r
584 \r
585                 /* Check both running timers are still active, but have not called their\r
586                 callback functions. */\r
587                 if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
588                 {\r
589                         xTestStatus = pdFAIL;\r
590                         configASSERT( xTestStatus );\r
591                 }\r
592 \r
593                 if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
594                 {\r
595                         xTestStatus = pdFAIL;\r
596                         configASSERT( xTestStatus );\r
597                 }\r
598 \r
599                 if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
600                 {\r
601                         xTestStatus = pdFAIL;\r
602                         configASSERT( xTestStatus );\r
603                 }\r
604 \r
605                 if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( unsigned char ) 0 )\r
606                 {\r
607                         xTestStatus = pdFAIL;\r
608                         configASSERT( xTestStatus );\r
609                 }\r
610 \r
611                 /* Reset both running timers. */\r
612                 xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );\r
613                 xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
614 \r
615                 if( xTestStatus == pdPASS )\r
616                 {\r
617                         /* No errors have been reported so increment the loop counter so\r
618                         the check task knows this task is still running. */\r
619                         ulLoopCounter++;\r
620                 }\r
621         }\r
622 \r
623         /* Finally delay long enough for both running timers to expire. */\r
624         vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod );\r
625 \r
626         /* The timers were not reset during the above delay period so should now\r
627         both have called their callback functions. */\r
628         if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
629         {\r
630                 xTestStatus = pdFAIL;\r
631                 configASSERT( xTestStatus );\r
632         }\r
633 \r
634         if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 )\r
635         {\r
636                 xTestStatus = pdFAIL;\r
637                 configASSERT( xTestStatus );\r
638         }\r
639 \r
640         /* The one shot timer should no longer be active, while the auto reload\r
641         timer should still be active. */\r
642         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
643         {\r
644                 xTestStatus = pdFAIL;\r
645                 configASSERT( xTestStatus );\r
646         }\r
647 \r
648         if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE )\r
649         {\r
650                 xTestStatus = pdFAIL;\r
651                 configASSERT( xTestStatus );\r
652         }\r
653 \r
654         /* Stop the auto reload timer again. */\r
655         xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
656 \r
657         if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )\r
658         {\r
659                 xTestStatus = pdFAIL;\r
660                 configASSERT( xTestStatus );\r
661         }\r
662 \r
663         /* Clear the timer callback counts, ready for another iteration of these\r
664         tests. */\r
665         ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( unsigned char ) 0;\r
666         ucOneShotTimerCounter = ( unsigned char ) 0;\r
667 \r
668         if( xTestStatus == pdPASS )\r
669         {\r
670                 /* No errors have been reported so increment the loop counter so the check\r
671                 task knows this task is still running. */\r
672                 ulLoopCounter++;\r
673         }\r
674 }\r
675 /*-----------------------------------------------------------*/\r
676 \r
677 static void prvResetStartConditionsForNextIteration( void )\r
678 {\r
679 unsigned char ucTimer;\r
680 \r
681         /* Start the timers again to start all the tests over again. */\r
682 \r
683         /* Start the timers again. */\r
684         for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
685         {\r
686                 /* The timer has not been started yet! */\r
687                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE )\r
688                 {\r
689                         xTestStatus = pdFAIL;\r
690                         configASSERT( xTestStatus );\r
691                 }\r
692 \r
693                 /* Now start the timer.  This will appear to happen immediately to\r
694                 this task because this task is running at a priority below the timer\r
695                 service task. */\r
696                 xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
697 \r
698                 /* The timer should now be active. */\r
699                 if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE )\r
700                 {\r
701                         xTestStatus = pdFAIL;\r
702                         configASSERT( xTestStatus );\r
703                 }\r
704         }\r
705 \r
706         if( xTestStatus == pdPASS )\r
707         {\r
708                 /* No errors have been reported so increment the loop counter so the\r
709                 check task knows this task is still running. */\r
710                 ulLoopCounter++;\r
711         }\r
712 }\r
713 /*-----------------------------------------------------------*/\r
714 \r
715 void vTimerPeriodicISRTests( void )\r
716 {\r
717 static portTickType uxTick = ( portTickType ) -1;\r
718 \r
719 /* The xHigherPriorityTaskWoken parameter is not used in this case as this\r
720 function is called from the tick hook anyway.  However the API required it\r
721 to be present. */\r
722 signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
723 portTickType xMargin;\r
724 \r
725         if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) )\r
726         {\r
727                 /* The timer service task is not the highest priority task, so it cannot\r
728                 be assumed that timings will be exact.  Timers should never call their\r
729                 callback before their expiry time, but a margin is permissible for calling\r
730                 their callback after their expiry time.  If exact timing is required then\r
731                 configTIMER_TASK_PRIORITY must be set to ensure the timer service task\r
732                 is the highest priority task in the system. */\r
733                 xMargin = 5;\r
734         }\r
735         else\r
736         {\r
737                 xMargin = 1;\r
738         }\r
739 \r
740         /* This test is called from the tick ISR even when the scheduler is suspended.\r
741         Therefore, it is possible for the xTickCount to be temporarily less than the\r
742         uxTicks count maintained in this function.  That can result in calculated\r
743         unblock times being too short, as this function is not called as missed ticks\r
744         (ticks that occur while the scheduler is suspended) are unwound to re-instate\r
745         the real tick value.  Therefore, if this happens, just abandon the test\r
746         and start again. */\r
747         if( xTaskGetSchedulerState() != taskSCHEDULER_RUNNING )\r
748         {\r
749                 uxTick = ( portTickType ) -1;\r
750         }\r
751         else\r
752         {\r
753                 uxTick++;\r
754         }\r
755 \r
756         if( uxTick == 0 )\r
757         {\r
758                 /* The timers will have been created, but not started.  Start them\r
759                 now by setting their period. */\r
760                 ucISRAutoReloadTimerCounter = 0;\r
761                 ucISROneShotTimerCounter = 0;\r
762                 xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, &xHigherPriorityTaskWoken );\r
763                 xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, &xHigherPriorityTaskWoken );\r
764         }\r
765         else if( uxTick == xBasePeriod )\r
766         {\r
767                 /* Neither timer should have expired yet. */\r
768                 if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) )\r
769                 {\r
770                         xTestStatus = pdFAIL;\r
771                         configASSERT( xTestStatus );\r
772                 }\r
773         }\r
774         else if( uxTick == ( xBasePeriod + xMargin ) )\r
775         {\r
776                 /* Both timers should now have expired once.  The auto reload timer will\r
777                 still be active, but the one shot timer should now have stopped. */\r
778                 if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )\r
779                 {\r
780                         xTestStatus = pdFAIL;\r
781                         configASSERT( xTestStatus );\r
782                 }\r
783         }\r
784         else if( uxTick == ( 2 * xBasePeriod ) )\r
785         {\r
786                 /* The auto reload timer will still be active, but the one shot timer\r
787                 should now have stopped - however, at this time neither of the timers\r
788                 should have expired again since the last test. */\r
789                 if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) )\r
790                 {\r
791                         xTestStatus = pdFAIL;\r
792                         configASSERT( xTestStatus );\r
793                 }               \r
794         }\r
795         else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) )\r
796         {\r
797                 /* The auto reload timer will still be active, but the one shot timer\r
798                 should now have stopped.  At this time the auto reload timer should have\r
799                 expired again, but the one shot timer count should not have changed. */\r
800                 if( ucISRAutoReloadTimerCounter != 2 )\r
801                 {\r
802                         xTestStatus = pdFAIL;\r
803                         configASSERT( xTestStatus );\r
804                 }\r
805                 \r
806                 if( ucISROneShotTimerCounter != 1 )\r
807                 {\r
808                         xTestStatus = pdFAIL;\r
809                         configASSERT( xTestStatus );\r
810                 }\r
811         }\r
812         else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( portTickType ) 2U ) ) )\r
813         {\r
814                 /* The auto reload timer will still be active, but the one shot timer\r
815                 should now have stopped.  Again though, at this time, neither timer call\r
816                 back should have been called since the last test. */\r
817                 if( ucISRAutoReloadTimerCounter != 2 )\r
818                 {\r
819                         xTestStatus = pdFAIL;\r
820                         configASSERT( xTestStatus );\r
821                 }\r
822                 \r
823                 if( ucISROneShotTimerCounter != 1 )\r
824                 {\r
825                         xTestStatus = pdFAIL;\r
826                         configASSERT( xTestStatus );\r
827                 }\r
828         }       \r
829         else if( uxTick == ( 3 * xBasePeriod ) )\r
830         {\r
831                 /* Start the one shot timer again. */\r
832                 xTimerStartFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
833         }\r
834         else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) )\r
835         {\r
836                 /* The auto reload timer and one shot timer will be active.  At\r
837                 this time the auto reload timer should have     expired again, but the one\r
838                 shot timer count should not have changed yet. */\r
839                 if( ucISRAutoReloadTimerCounter != 3 )\r
840                 {\r
841                         xTestStatus = pdFAIL;\r
842                         configASSERT( xTestStatus );\r
843                 }\r
844                 \r
845                 if( ucISROneShotTimerCounter != 1 )\r
846                 {\r
847                         xTestStatus = pdFAIL;\r
848                         configASSERT( xTestStatus );\r
849                 }\r
850                 \r
851                 /* Now stop the auto reload timer.  The one shot timer was started\r
852                 a few ticks ago. */\r
853                 xTimerStopFromISR( xISRAutoReloadTimer, &xHigherPriorityTaskWoken );\r
854         }       \r
855         else if( uxTick == ( 4 * xBasePeriod ) )\r
856         {\r
857                 /* The auto reload timer is now stopped, and the one shot timer is\r
858                 active, but at this time neither timer should have expired since the\r
859                 last test. */\r
860                 if( ucISRAutoReloadTimerCounter != 3 )\r
861                 {\r
862                         xTestStatus = pdFAIL;\r
863                         configASSERT( xTestStatus );\r
864                 }\r
865                 \r
866                 if( ucISROneShotTimerCounter != 1 )\r
867                 {\r
868                         xTestStatus = pdFAIL;\r
869                         configASSERT( xTestStatus );\r
870                 }\r
871         }       \r
872         else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) )\r
873         {\r
874                 /* The auto reload timer is now stopped, and the one shot timer is\r
875                 active.  The one shot timer should have expired again, but the auto\r
876                 reload timer should not have executed its callback. */\r
877                 if( ucISRAutoReloadTimerCounter != 3 )\r
878                 {\r
879                         xTestStatus = pdFAIL;\r
880                         configASSERT( xTestStatus );\r
881                 }\r
882                 \r
883                 if( ucISROneShotTimerCounter != 2 )\r
884                 {\r
885                         xTestStatus = pdFAIL;\r
886                         configASSERT( xTestStatus );\r
887                 }\r
888         }       \r
889         else if( uxTick == ( ( 8 * xBasePeriod ) + xMargin ) )\r
890         {\r
891                 /* The auto reload timer is now stopped, and the one shot timer has\r
892                 already expired and then stopped itself.  Both callback counters should\r
893                 not have incremented since the last test. */\r
894                 if( ucISRAutoReloadTimerCounter != 3 )\r
895                 {\r
896                         xTestStatus = pdFAIL;\r
897                         configASSERT( xTestStatus );\r
898                 }\r
899                 \r
900                 if( ucISROneShotTimerCounter != 2 )\r
901                 {\r
902                         xTestStatus = pdFAIL;\r
903                         configASSERT( xTestStatus );\r
904                 }\r
905                 \r
906                 /* Now reset the one shot timer. */\r
907                 xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
908         }       \r
909         else if( uxTick == ( 9 * xBasePeriod ) )\r
910         {\r
911                 /* Only the one shot timer should be running, but it should not have\r
912                 expired since the last test.  Check the callback counters have not\r
913                 incremented, then reset the one shot timer again. */\r
914                 if( ucISRAutoReloadTimerCounter != 3 )\r
915                 {\r
916                         xTestStatus = pdFAIL;\r
917                         configASSERT( xTestStatus );\r
918                 }\r
919                 \r
920                 if( ucISROneShotTimerCounter != 2 )\r
921                 {\r
922                         xTestStatus = pdFAIL;\r
923                         configASSERT( xTestStatus );\r
924                 }\r
925                 \r
926                 xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
927         }       \r
928         else if( uxTick == ( 10 * xBasePeriod ) )\r
929         {\r
930                 /* Only the one shot timer should be running, but it should not have\r
931                 expired since the last test.  Check the callback counters have not\r
932                 incremented, then reset the one shot timer again. */\r
933                 if( ucISRAutoReloadTimerCounter != 3 )\r
934                 {\r
935                         xTestStatus = pdFAIL;\r
936                         configASSERT( xTestStatus );\r
937                 }\r
938                 \r
939                 if( ucISROneShotTimerCounter != 2 )\r
940                 {\r
941                         xTestStatus = pdFAIL;\r
942                         configASSERT( xTestStatus );\r
943                 }\r
944                 \r
945                 xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
946         }\r
947         else if( uxTick == ( 11 * xBasePeriod ) )\r
948         {\r
949                 /* Only the one shot timer should be running, but it should not have\r
950                 expired since the last test.  Check the callback counters have not\r
951                 incremented, then reset the one shot timer once again. */\r
952                 if( ucISRAutoReloadTimerCounter != 3 )\r
953                 {\r
954                         xTestStatus = pdFAIL;\r
955                         configASSERT( xTestStatus );\r
956                 }\r
957                 \r
958                 if( ucISROneShotTimerCounter != 2 )\r
959                 {\r
960                         xTestStatus = pdFAIL;\r
961                         configASSERT( xTestStatus );\r
962                 }\r
963                 \r
964                 xTimerResetFromISR( xISROneShotTimer, &xHigherPriorityTaskWoken );\r
965         }       \r
966         else if( uxTick == ( ( 12 * xBasePeriod ) + xMargin ) )\r
967         {\r
968                 /* Only the one shot timer should have been running and this time it\r
969                 should have     expired.  Check its callback count has been incremented.\r
970                 The auto reload timer is still not running so should still have the same\r
971                 count value.  This time the one shot timer is not reset so should not\r
972                 restart from its expiry period again. */\r
973                 if( ucISRAutoReloadTimerCounter != 3 )\r
974                 {\r
975                         xTestStatus = pdFAIL;\r
976                         configASSERT( xTestStatus );\r
977                 }\r
978                 \r
979                 if( ucISROneShotTimerCounter != 3 )\r
980                 {\r
981                         xTestStatus = pdFAIL;\r
982                         configASSERT( xTestStatus );\r
983                 }\r
984         }\r
985         else if( uxTick == ( 15 * xBasePeriod ) )\r
986         {\r
987                 /* Neither timer should be running now.  Check neither callback count\r
988                 has incremented, then go back to the start to run these tests all\r
989                 over again. */\r
990                 if( ucISRAutoReloadTimerCounter != 3 )\r
991                 {\r
992                         xTestStatus = pdFAIL;\r
993                         configASSERT( xTestStatus );\r
994                 }\r
995                 \r
996                 if( ucISROneShotTimerCounter != 3 )\r
997                 {\r
998                         xTestStatus = pdFAIL;\r
999                         configASSERT( xTestStatus );\r
1000                 }\r
1001                 \r
1002                 uxTick = ( portTickType ) -1;\r
1003         }       \r
1004 }\r
1005 /*-----------------------------------------------------------*/\r
1006 \r
1007 /*** Timer callback functions are defined below here. ***/\r
1008 \r
1009 static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer )\r
1010 {\r
1011 unsigned long ulTimerID;\r
1012 \r
1013         ulTimerID = ( unsigned long ) pvTimerGetTimerID( pxExpiredTimer );\r
1014         if( ulTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) )\r
1015         {\r
1016                 ( ucAutoReloadTimerCounters[ ulTimerID ] )++;\r
1017         }\r
1018         else\r
1019         {\r
1020                 /* The timer ID appears to be unexpected (invalid). */\r
1021                 xTestStatus = pdFAIL;\r
1022                 configASSERT( xTestStatus );\r
1023         }\r
1024 }\r
1025 /*-----------------------------------------------------------*/\r
1026 \r
1027 static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
1028 {\r
1029         /* The parameter is not used in this case as only one timer uses this\r
1030         callback function. */\r
1031         ( void ) pxExpiredTimer;\r
1032 \r
1033         ucOneShotTimerCounter++;\r
1034 }\r
1035 /*-----------------------------------------------------------*/\r
1036 \r
1037 static void prvISRAutoReloadTimerCallback( xTimerHandle pxExpiredTimer )\r
1038 {\r
1039         /* The parameter is not used in this case as only one timer uses this\r
1040         callback function. */\r
1041         ( void ) pxExpiredTimer;\r
1042 \r
1043         ucISRAutoReloadTimerCounter++;\r
1044 }\r
1045 /*-----------------------------------------------------------*/\r
1046 \r
1047 static void prvISROneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
1048 {\r
1049         /* The parameter is not used in this case as only one timer uses this\r
1050         callback function. */\r
1051         ( void ) pxExpiredTimer;\r
1052 \r
1053         ucISROneShotTimerCounter++;\r
1054 }\r
1055 /*-----------------------------------------------------------*/\r
1056 \r
1057 \r
1058 \r
1059 \r