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