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