]> git.sur5r.net Git - freertos/blob
0f3b60adff4f108d54dfae2c477b95606db369f4
[freertos] /
1 #ifndef TIMER_TEST_H\r
2 #define TIMER_TEST_H\r
3 \r
4 #define tmrtestNUM_TIMERS 15\r
5 \r
6 \r
7 extern portTickType xTickCount;\r
8 extern xTaskHandle pxCurrentTCB;\r
9 extern portTickType xNumOfOverflows;\r
10 \r
11 static void vTimerTest_Initialise( void );\r
12 static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void );\r
13 portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier );\r
14 \r
15 static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed );\r
16 \r
17 static void prvTestFailed( void );\r
18 \r
19 xTIMER *xAutoReloadTimers[ tmrtestNUM_TIMERS ];\r
20 unsigned portBASE_TYPE uxAutoReloadTimerCounters[ tmrtestNUM_TIMERS ];\r
21 portBASE_TYPE xTestStatus = pdPASS;\r
22 xTaskHandle xTestTask1 = NULL, xTestTask2 = NULL;\r
23 \r
24 struct xTestData\r
25 {\r
26         portTickType xStartTickCount;\r
27         portTickType xTimerPeriod;\r
28         portTickType xTickIncrementBetweenCommandAndProcessing;\r
29         portTickType xExpectedCalculatedExpiryTime;\r
30         xList * pxExpectedList;\r
31         unsigned portBASE_TYPE uxExpectedCallbackCount;\r
32 };\r
33 \r
34 const struct xTestData xTestCase[] =\r
35 {\r
36         /* xStartTickCount,             xTimerPeriod,           Tck Inc,        Expected Expire Time,           Expected list,   Expected callback count, Second tick inc */\r
37 \r
38         /* Test cases when the command to start a timer and the processing of the\r
39         start command execute without the tick count incrementing in between. */\r
40         { portMAX_DELAY - 8,    2,                                      0,              ( portMAX_DELAY - 8 ) + 2,                      &xActiveTimerList1, 0 },                /* Expire before an overflow. */\r
41         { portMAX_DELAY - 8,    8,                                      0,              ( portMAX_DELAY - 8 ) + 8,                      &xActiveTimerList1, 0 },                /* Expire immediately before and overflow. */\r
42         { portMAX_DELAY - 8,    9,                                      0,              0,                                                                      &xActiveTimerList2, 0 },                /* Expire on an overflow. */\r
43         { portMAX_DELAY - 8,    portMAX_DELAY,          0,              ( ( portMAX_DELAY - 8 ) - 1 ),          &xActiveTimerList2, 0 },                /* Delay for the longest possible time. */\r
44         { portMAX_DELAY,                portMAX_DELAY,          0,              ( portMAX_DELAY - 1 ),                          &xActiveTimerList2, 0 },                /* Delay for the longest possible time starting from the maximum tick count. */\r
45         { 0,                                    portMAX_DELAY,          0,              ( portMAX_DELAY ),                                      &xActiveTimerList1, 0 },                /* Delay for the maximum ticks, starting with from the minimum tick count. */\r
46 \r
47         /* Test cases when the command to start a timer and the processing of the\r
48         start command execute at different tick count values. */\r
49         { portMAX_DELAY - 8,    2,                                      1,              ( portMAX_DELAY - 8 ) + 2,                      &xActiveTimerList1, 0 },                /* The expire time does not overflow, and the tick count does not overflow between the command and processing the command. */\r
50         { portMAX_DELAY - 8,    8,                                      2,              ( portMAX_DELAY - 8 ) + 8,                      &xActiveTimerList1, 0 },                /* The expire time does not overflow but is on the portMAX_DELAY limit, and the tick count does not overflow between the command and processing the command. */\r
51         { portMAX_DELAY - 8,    9,                                      3,              0,                                                                      &xActiveTimerList2, 0 },                /* The expire time overflows to 0, and the tick count does not overflow between the command and processing the command. */\r
52         { portMAX_DELAY - 2,    9,                                      1,              ( portMAX_DELAY - 2 ) + 9,                      &xActiveTimerList2, 0 },                /* The expire time overflows, but the tick count does not overflow between the command and processing the command. */\r
53         { portMAX_DELAY - 2,    9,                                      3,              ( portMAX_DELAY - 2 ) + 9,                      &xActiveTimerList2, 0 },                /* The timer overflows between the command and processing the command.  The expire time also overflows. */\r
54 \r
55         /* Add tests where the timer should have expired by the time the command is processed. */\r
56         { 10,                                   9,                                      10,             ( 10 + ( 2 * 9 ) ),                                     &xActiveTimerList1, 1 },                /* Nothing overflows, but the time between the timer being set and the command being processed is greater than the timers expiry time.  The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded. */\r
57         { portMAX_DELAY - 2,    9,                                      10,             ( portMAX_DELAY - 2 ) + ( 2 * 9 ),      &xActiveTimerList2, 1 },                /* The timer overflows between the command and processing the command.  The expire time also overflows and the number of ticks that occur between the command and the processing exceeds the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
58         { portMAX_DELAY - 2,    9,                                      9,              ( portMAX_DELAY - 2 ) + ( 2 * 9 ),      &xActiveTimerList2, 1 },                /* The timer overflows between the command and processing the command.  The expire time also overflows and the number of ticks between command and processing equals the timer expiry period. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
59 \r
60         { portMAX_DELAY - 20,   9,                                      21,             ( portMAX_DELAY - 20 ) + ( 3 * 9 ),     &xActiveTimerList2, 2 },                /* The tick count has overflowed but the timer expire time has not overflowed.  The tick count overflows to 0.  The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
61         { portMAX_DELAY - 20,   9,                                      22,             ( portMAX_DELAY - 20 ) + ( 3 * 9 ),     &xActiveTimerList2, 2 },                /* The tick count has overflowed but the timer expire time has not overflowed.  The tick count overflows to greater than 0. The timer should get processed immediately, so the expected expire time is twice the period as the timer will get auto-reloaded.*/\r
62         { portMAX_DELAY - 5,    2,                                      20,             ( portMAX_DELAY - 5 ) + ( 11 * 2 ),     &xActiveTimerList2, 10 },               /* The tick and expire time overflow, but the first expire time overflow results in a time that is less than the tick count. */\r
63 };\r
64 \r
65 typedef struct tskTaskControlBlockx\r
66 {\r
67         volatile portSTACK_TYPE *pxTopOfStack;          /*< Points to the location of the last item placed on the tasks stack.  THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
68 \r
69         #if ( portUSING_MPU_WRAPPERS == 1 )\r
70                 xMPU_SETTINGS xMPUSettings;                             /*< The MPU settings are defined as part of the port layer.  THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
71         #endif  \r
72         \r
73         xListItem                               xGenericListItem;       /*< List item used to place the TCB in ready and blocked queues. */\r
74         xListItem                               xEventListItem;         /*< List item used to place the TCB in event lists. */\r
75         unsigned portBASE_TYPE  uxPriority;                     /*< The priority of the task where 0 is the lowest priority. */\r
76         portSTACK_TYPE                  *pxStack;                       /*< Points to the start of the stack. */\r
77         signed char                             pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */\r
78 \r
79         #if ( portSTACK_GROWTH > 0 )\r
80                 portSTACK_TYPE *pxEndOfStack;                   /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
81         #endif\r
82 \r
83         #if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
84                 unsigned portBASE_TYPE uxCriticalNesting;\r
85         #endif\r
86 \r
87         #if ( configUSE_TRACE_FACILITY == 1 )\r
88                 unsigned portBASE_TYPE  uxTCBNumber;    /*< This is used for tracing the scheduler and making debugging easier only. */\r
89         #endif\r
90 \r
91         #if ( configUSE_MUTEXES == 1 )\r
92                 unsigned portBASE_TYPE uxBasePriority;  /*< The priority last assigned to the task - used by the priority inheritance mechanism. */\r
93         #endif\r
94 \r
95         #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
96                 pdTASK_HOOK_CODE pxTaskTag;\r
97         #endif\r
98 \r
99         #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
100                 unsigned long ulRunTimeCounter;         /*< Used for calculating how much CPU time each task is utilising. */\r
101         #endif\r
102 \r
103 } tskTCBx;\r
104 \r
105 /*-----------------------------------------------------------*/\r
106 \r
107 static void vAutoReloadTimerCallback( xTIMER *pxTimer )\r
108 {\r
109 portBASE_TYPE xTimerID = ( portBASE_TYPE ) pxTimer->pvTimerID;\r
110 \r
111         if( xTimerID < tmrtestNUM_TIMERS )\r
112         {\r
113                 ( uxAutoReloadTimerCounters[ xTimerID ] )++;\r
114         }\r
115         else\r
116         {\r
117                 prvTestFailed();\r
118         }\r
119 }\r
120 /*-----------------------------------------------------------*/\r
121 \r
122 static void vTimerTest_Initialise( void )\r
123 {\r
124 portBASE_TYPE xTimerNumber;\r
125 extern void prvInitialiseTaskLists( void );\r
126 extern portBASE_TYPE xSchedulerRunning;\r
127 \r
128         prvInitialiseTaskLists();\r
129         xTimerQueue = NULL;\r
130         xSchedulerRunning = pdTRUE;\r
131 \r
132         for( xTimerNumber = 0; xTimerNumber < tmrtestNUM_TIMERS; xTimerNumber++ )\r
133         {\r
134                 /* Delete any existing timers. */\r
135                 if( xAutoReloadTimers[ xTimerNumber ] != NULL )\r
136                 {\r
137                         vPortFree( xAutoReloadTimers[ xTimerNumber ] );\r
138                 }\r
139 \r
140                 /* Create new autoreload timers. */\r
141                 xAutoReloadTimers[ xTimerNumber ] = xTimerCreate( "Timer", 0xffff, pdTRUE, ( void * ) xTimerNumber, vAutoReloadTimerCallback );\r
142                 uxAutoReloadTimerCounters[ xTimerNumber ] = 0;\r
143                 if( xAutoReloadTimers == NULL )\r
144                 {\r
145                         prvTestFailed();\r
146                 }\r
147         }\r
148 \r
149         /* Initialise lists so they are empty. */\r
150         vListInitialise( &xActiveTimerList1 );\r
151         vListInitialise( &xActiveTimerList2 );\r
152 \r
153         /* Call prvSampleTimeNow with a tick count of zero so it sets its \r
154         internal static "last time" variable to zero. */\r
155         xTickCount = 0;\r
156         xNumOfOverflows = 0;\r
157         prvSampleTimeNow( &xTimerNumber );\r
158 \r
159         /* Initialise the list pointers in case prvSampleTimeNow() changed them. */\r
160         pxCurrentTimerList = &xActiveTimerList1;\r
161         pxOverflowTimerList = &xActiveTimerList2;\r
162 \r
163 //      if( xTestTask1 == NULL )\r
164         {\r
165                 xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1",  configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask1 );\r
166         }\r
167 \r
168 //      if( xTestTask2 == NULL )\r
169         {\r
170                 xTaskCreate( (pdTASK_CODE)prvTestFailed, "Task1",  configMINIMAL_STACK_SIZE, NULL, 0, &xTestTask2 );\r
171         }\r
172 \r
173         pxCurrentTCB = xTestTask1;\r
174 }\r
175 /*-----------------------------------------------------------*/\r
176 \r
177 static void prvTestFailed( void )\r
178 {\r
179 static unsigned long ulFailures = 0;\r
180 \r
181         ulFailures++;\r
182         xTestStatus = pdFAIL;\r
183 }\r
184 /*-----------------------------------------------------------*/\r
185 \r
186 static void prvCheckServiceTaskBehaviour( portBASE_TYPE x, portBASE_TYPE xExpireTimeHasOverflowed, portBASE_TYPE xTickCountOverflowed )\r
187 {\r
188 portBASE_TYPE xListWasEmpty;\r
189 portTickType xNextExpireTime;\r
190 extern xList * volatile pxOverflowDelayedTaskList, *pxDelayedTaskList;\r
191 extern xList pxReadyTasksLists[];\r
192 \r
193         xListWasEmpty = portMAX_DELAY;\r
194         xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
195 \r
196         /* If the timer expire time has overflowed it should be present in the overflow \r
197         list of active timers, unless the tick count has also overflowed and the expire\r
198         time has not passed.  If the expire time has not overflowed it should be \r
199         present in the current list of active timers.  Either way, its expire time should \r
200         equal the expected expire time. */\r
201         if( ( xExpireTimeHasOverflowed == pdTRUE ) && ( xTickCountOverflowed == pdFALSE ) )\r
202         {       \r
203                 /* The timer will be in the overflow list, so prvGetNextExpireTime()\r
204                 should not have found it, but instead returned an expire time that\r
205                 will ensure the timer service task will unblock when the lists need\r
206                 switching. */\r
207                 if( ( xNextExpireTime != 0 ) || ( xListWasEmpty == pdFALSE ) )\r
208                 {\r
209                         prvTestFailed();\r
210                 }\r
211         }\r
212         else\r
213         {\r
214                 if( ( xNextExpireTime != xTestCase[ x ].xExpectedCalculatedExpiryTime ) || ( xListWasEmpty != pdFALSE ) )\r
215                 {\r
216                         prvTestFailed();\r
217                 }\r
218         }\r
219 \r
220         prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
221 \r
222         /* Has the timer expired the expected number of times? */\r
223         if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
224         {\r
225                 prvTestFailed();\r
226         }\r
227 \r
228         /* The task should now be blocked.  It should only appear in the overflow\r
229         delayed task list if xNextExpireTime is equal to 0. */\r
230         if( xNextExpireTime == 0 )\r
231         {\r
232                 if( listIS_CONTAINED_WITHIN( pxOverflowDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
233                 {\r
234                         prvTestFailed();\r
235                 }\r
236 \r
237                 if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != 0 )\r
238                 {\r
239                         prvTestFailed();\r
240                 }\r
241         }\r
242         else\r
243         {\r
244                 if( listIS_CONTAINED_WITHIN( pxDelayedTaskList, &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
245                 {\r
246                         prvTestFailed();\r
247                 }\r
248 \r
249                 if( listGET_LIST_ITEM_VALUE( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
250                 {\r
251                         prvTestFailed();\r
252                 }\r
253         }\r
254 \r
255         /* The timer should have be re-loaded, and still be referenced from one\r
256         or other of the active lists. */\r
257         if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
258         {\r
259                 prvTestFailed();\r
260         }\r
261         if( listIS_CONTAINED_WITHIN( NULL, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdTRUE )\r
262         {\r
263                 prvTestFailed();\r
264         }\r
265 \r
266         /* Move the task back to the ready list from the delayed list. */\r
267         vListRemove( &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
268         vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) );\r
269 }\r
270 /*-----------------------------------------------------------*/\r
271 \r
272 static portBASE_TYPE xTimerTest1_xTimeStartAndResetWakeTimeCalculation( void )\r
273 {\r
274 portBASE_TYPE x, xListWasEmpty;\r
275 portTickType xNextExpireTime;\r
276 \r
277         if( sizeof( portTickType ) != 2 )\r
278         {\r
279                 /* This test should be performed using 16bit ticks. */\r
280                 prvTestFailed();\r
281         }\r
282 \r
283         for( x = 0; x < ( sizeof( xTestCase ) / sizeof( struct xTestData ) ); x++ )\r
284         {\r
285                 /* Set everything back to its start condition. */\r
286                 vTimerTest_Initialise();\r
287 \r
288                 /* Load the tick count with the test case data. */\r
289                 xTickCount = xTestCase[ x ].xStartTickCount;\r
290 \r
291                 /* Query the timers list to see if it contains any timers, and if so,\r
292                 obtain the time at which the next timer will expire.  The list should be\r
293                 empty, so 0 should be returned (to cause the task to unblock when a\r
294                 tick overflow occurs.  Likewise xListWasEmpty should be set to pdTRUE. */\r
295                 xListWasEmpty = portMAX_DELAY;\r
296                 xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
297 \r
298                 if( ( xListWasEmpty != pdTRUE ) || ( xNextExpireTime != ( portTickType ) 0 ) )\r
299                 {\r
300                         prvTestFailed();\r
301                 }\r
302 \r
303 \r
304 \r
305                 /* Call prvProcessReceivedCommands() just so the code under test knows\r
306                 what the tick count is in the pre-condition state. */\r
307                 prvProcessReceivedCommands();\r
308 \r
309                 xAutoReloadTimers[ 0 ]->xTimerPeriodInTicks = xTestCase[ x ].xTimerPeriod;\r
310                 xTimerStart( xAutoReloadTimers[ 0 ], 0 );\r
311 \r
312                 /* Move the tick count on to the time at which the command should be \r
313                 processed. */\r
314                 xTickCount += xTestCase[ x ].xTickIncrementBetweenCommandAndProcessing;\r
315 \r
316                 /* Process the sent command with the updated tick count. */\r
317                 prvProcessReceivedCommands();\r
318 \r
319                 if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
320                 {\r
321                         prvTestFailed();\r
322                 }\r
323                 if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
324                 {\r
325                         prvTestFailed();\r
326                 }\r
327                 if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
328                 {\r
329                         prvTestFailed();\r
330                 }\r
331 \r
332                 if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
333                 {\r
334                         if(  xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
335                         {\r
336                                 if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed  */\r
337                                 {\r
338                                         /* The expire time should never have passed when here is\r
339                                         reached because the timer whould have been processed enough\r
340                                         times to make the expire time catch up. */\r
341                                         prvTestFailed();\r
342                                 }\r
343                                 else /* The timer expire time has not passed. */\r
344                                 {\r
345                                         prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
346                                 }\r
347                         }\r
348                         else /* The timer expire time has not overflowed. */\r
349                         {\r
350                                 /* If the timer expire time has not overflowed but the tick count has \r
351                                 overflowed, then the timer expire time must have been passed.  The \r
352                                 expire time should never have passed when here is reached because \r
353                                 the timer whould have been processed enough     times to make the expire \r
354                                 time catch up. */\r
355                                 prvTestFailed();\r
356                         }\r
357                 }\r
358                 else /* The tick count has not overflowed. */\r
359                 {\r
360                         if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
361                         {\r
362                                 /* If the expire time has overflowed, but the tick count has not\r
363                                 overflowed, then the timer expire time cannot have been passed. */\r
364                                 prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
365                         }\r
366                         else /* The timer expire time has not overflowed. */\r
367                         {\r
368                                 if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
369                                 {\r
370                                         /* The expire time should never have passed when here is\r
371                                         reached because the timer whould have been processed enough\r
372                                         times to make the expire time catch up. */\r
373                                         prvTestFailed();\r
374                                 }\r
375                                 else /* The timer expire time has not passed. */\r
376                                 {\r
377                                         prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
378                                 }\r
379                         }\r
380                 }\r
381         }\r
382 \r
383         return xTestStatus;\r
384 }\r
385 /*-----------------------------------------------------------*/\r
386 \r
387 portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
388 {\r
389 unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
390 const unsigned portBASE_TYPE uxMaxIterations = 0x1fffff;\r
391 extern xList pxReadyTasksLists[];\r
392 portTickType xNextExpireTime;\r
393 portBASE_TYPE xListWasEmpty;\r
394 extern xTaskHandle pxCurrentTCB;\r
395 \r
396         if( sizeof( portTickType ) != 2 )\r
397         {\r
398                 /* This test should be performed using 16bit ticks. */\r
399                 prvTestFailed();\r
400         }\r
401 \r
402         /* Initialise the test.  This will create tmrtestNUM_TIMERS timers. */\r
403         vTimerTest_Initialise();\r
404 \r
405         /* Give each timer a period, then start it running. */\r
406         for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
407         {\r
408                 uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
409                 xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
410                 xTimerStart( xAutoReloadTimers[ x ], 0 );\r
411                 prvProcessReceivedCommands();\r
412         }\r
413 \r
414         xTickCount = 1;\r
415         x = 1;\r
416 \r
417         /* Simulate the task running. */\r
418         while( x <= uxMaxIterations )\r
419         {\r
420                 /* Query the timers list to see if it contains any timers, and if so,\r
421                 obtain the time at which the next timer will expire. */\r
422                 xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
423 \r
424                 /* It is legitimate for tick increments to occur here. */\r
425                 if( ( uxMix < 2 ) && ( x < uxMaxIterations - 5 ) )\r
426                 {\r
427                         vTaskIncrementTick();\r
428                         x++;\r
429                         vTaskIncrementTick();\r
430                         x++;\r
431                         vTaskIncrementTick();\r
432                         x++;\r
433                 }\r
434 \r
435                 /* If a timer has expired, process it.  Otherwise, block this task\r
436                 until either a timer does expire, or a command is received. */\r
437                 prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
438                 \r
439                 /* If the task blocked, increment the tick until it unblocks. */\r
440                 while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
441                 {\r
442                         if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
443                         {\r
444                                 vTaskIncrementTick();\r
445                                 x++;\r
446                                 vTaskIncrementTick();\r
447                                 x++;\r
448                                 vTaskIncrementTick();\r
449                                 x++;\r
450                         }\r
451                         if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
452                         {\r
453                                 vTaskIncrementTick();\r
454                                 x++;\r
455                                 vTaskIncrementTick();\r
456                                 x++;\r
457                         }\r
458                         else\r
459                         {\r
460                                 vTaskIncrementTick();\r
461                                 x++;\r
462                         }\r
463                 }\r
464 \r
465                 uxMix++;\r
466                 if( uxMix > 8 )\r
467                 {\r
468                         uxMix = 0;\r
469                 }\r
470 \r
471                 /* Make sure time does not go past that expected. */\r
472                 if( x > uxMaxIterations )\r
473                 {\r
474                         xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
475                 }\r
476 \r
477                 /* Empty the command queue. */\r
478                 prvProcessReceivedCommands();           \r
479         }\r
480 \r
481         /* Catch up with the tick count, if it was incremented more than once in one\r
482         go. */\r
483         xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
484         prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
485                 \r
486         /* This time, if the task blocked, there is nothing left to do.  If it didn't\r
487         block then empty the command queue for good measure. */\r
488         if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
489         {\r
490                 /* Empty the command queue. */\r
491                 prvProcessReceivedCommands();           \r
492         }\r
493 \r
494         /* Check each timer has incremented the expected number of times. */\r
495         for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
496         {\r
497                 uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
498                 uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
499         \r
500                 if( ( uxExpectedIncrements - uxAutoReloadTimerCounters[ x ] ) > 1 )\r
501                 {\r
502                         prvTestFailed();\r
503                 }\r
504         }\r
505 \r
506         return xTestStatus;\r
507 }\r
508 \r
509 /*-----------------------------------------------------------*/\r
510 \r
511 void vRunTimerModuleTests( void )\r
512 {\r
513 unsigned long x;\r
514 \r
515         xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
516 \r
517         for( x = 1; x < 1000; x++ )\r
518         {\r
519                 xTimerTest2_xTestFreeRunningBehaviour( x );\r
520         }\r
521 \r
522         for( ;; );\r
523 }\r
524 \r
525 #endif TIMER_TEST_H\r
526 \r