]> git.sur5r.net Git - freertos/blob
786dfaff6a133cf84a69d9bb1df8d66ef51298ce
[freertos] /
1 #ifndef TIMER_TEST_H\r
2 #define TIMER_TEST_H\r
3 \r
4 #define tmrtestNUM_TIMERS 2\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 */\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 xTickCount += 2;\r
320 \r
321                 if( listGET_LIST_ITEM_VALUE( &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) != xTestCase[ x ].xExpectedCalculatedExpiryTime )\r
322                 {\r
323                         prvTestFailed();\r
324                 }\r
325                 if( listIS_CONTAINED_WITHIN( xTestCase[ x ].pxExpectedList, &( xAutoReloadTimers[ 0 ]->xTimerListItem ) ) == pdFALSE )\r
326                 {\r
327                         prvTestFailed();\r
328                 }\r
329                 if( uxAutoReloadTimerCounters[ 0 ] != xTestCase[ x ].uxExpectedCallbackCount )\r
330                 {\r
331                         prvTestFailed();\r
332                 }\r
333 \r
334                 if( xTickCount < xTestCase[ x ].xStartTickCount ) /* The tick count has overflowed */\r
335                 {\r
336                         if(  xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed. */\r
337                         {\r
338                                 if( xTestCase[ x ].xExpectedCalculatedExpiryTime <= xTickCount ) /* The timer expire time has passed  */\r
339                                 {\r
340                                         /* The expire time should never have passed when here is\r
341                                         reached because the timer whould have been processed enough\r
342                                         times to make the expire time catch up. */\r
343                                         prvTestFailed();\r
344                                 }\r
345                                 else /* The timer expire time has not passed. */\r
346                                 {\r
347                                         prvCheckServiceTaskBehaviour( x, pdTRUE, pdTRUE );\r
348                                 }\r
349                         }\r
350                         else /* The timer expire time has not overflowed. */\r
351                         {\r
352                                 /* If the timer expire time has not overflowed but the tick count has \r
353                                 overflowed, then the timer expire time must have been passed.  The \r
354                                 expire time should never have passed when here is reached because \r
355                                 the timer whould have been processed enough     times to make the expire \r
356                                 time catch up. */\r
357                                 prvTestFailed();\r
358                         }\r
359                 }\r
360                 else /* The tick count has not overflowed. */\r
361                 {\r
362                         if( xTestCase[ x ].pxExpectedList == &xActiveTimerList2 ) /* The timer expire time has overflowed */\r
363                         {\r
364                                 /* If the expire time has overflowed, but the tick count has not\r
365                                 overflowed, then the timer expire time cannot have been passed. */\r
366                                 prvCheckServiceTaskBehaviour( x, pdTRUE, pdFALSE );\r
367                         }\r
368                         else /* The timer expire time has not overflowed. */\r
369                         {\r
370                                 if( xTickCount >= xTestCase[ x ].xExpectedCalculatedExpiryTime ) /* The timer expire time has passed */\r
371                                 {\r
372                                         /* The expire time should never have passed when here is\r
373                                         reached because the timer whould have been processed enough\r
374                                         times to make the expire time catch up. */\r
375                                         prvTestFailed();\r
376                                 }\r
377                                 else /* The timer expire time has not passed. */\r
378                                 {\r
379                                         prvCheckServiceTaskBehaviour( x, pdFALSE, pdFALSE );\r
380                                 }\r
381                         }\r
382                 }\r
383         }\r
384 \r
385         return xTestStatus;\r
386 }\r
387 /*-----------------------------------------------------------*/\r
388 \r
389 portBASE_TYPE xTimerTest2_xTestFreeRunningBehaviour( unsigned portBASE_TYPE uxPeriodMultiplier )\r
390 {\r
391 unsigned portBASE_TYPE uxExpectedIncrements, x, uxMix = 0, uxPeriod;\r
392 const unsigned portBASE_TYPE uxMaxIterations = 0xffff;\r
393 extern xList pxReadyTasksLists[];\r
394 portTickType xNextExpireTime;\r
395 portBASE_TYPE xListWasEmpty;\r
396 extern xTaskHandle pxCurrentTCB;\r
397 \r
398         if( sizeof( portTickType ) != 2 )\r
399         {\r
400                 /* This test should be performed using 16bit ticks. */\r
401                 prvTestFailed();\r
402         }\r
403 \r
404         /* Initialise the test.  This will create tmrtestNUM_TIMERS timers. */\r
405         vTimerTest_Initialise();\r
406 \r
407         /* Give each timer a period, then start it running. */\r
408         for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
409         {\r
410                 uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
411                 xTimerChangePeriod( xAutoReloadTimers[ x ], ( portTickType ) uxPeriod, 0 );\r
412                 xTimerStart( xAutoReloadTimers[ x ], 0 );\r
413                 prvProcessReceivedCommands();\r
414         }\r
415 \r
416         xTickCount = 1;\r
417         x = 1;\r
418 \r
419         /* Simulate the task running. */\r
420         while( x <= uxMaxIterations )\r
421         {\r
422                 /* Query the timers list to see if it contains any timers, and if so,\r
423                 obtain the time at which the next timer will expire. */\r
424                 xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
425 \r
426                 /* It is legitimate for tick increments to occur here. */\r
427                 if( ( uxMix < 2 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
428                 {\r
429                         vTaskIncrementTick();\r
430                         x++;\r
431                         vTaskIncrementTick();\r
432                         x++;\r
433                         vTaskIncrementTick();\r
434                         x++;\r
435                 }\r
436 \r
437                 /* If a timer has expired, process it.  Otherwise, block this task\r
438                 until either a timer does expire, or a command is received. */\r
439                 prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
440                 \r
441                 /* If the task blocked, increment the tick until it unblocks. */\r
442                 while( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) == pdFALSE )\r
443                 {\r
444                         if( ( uxMix == 1 ) && ( x < ( uxMaxIterations + 3 ) ) )\r
445                         {\r
446                                 vTaskIncrementTick();\r
447                                 x++;\r
448                                 vTaskIncrementTick();\r
449                                 x++;\r
450                                 vTaskIncrementTick();\r
451                                 x++;\r
452                         }\r
453                         if( ( uxMix == 2 ) && ( x < ( uxMaxIterations + 2 ) ) )\r
454                         {\r
455                                 vTaskIncrementTick();\r
456                                 x++;\r
457                                 vTaskIncrementTick();\r
458                                 x++;\r
459                         }\r
460                         else\r
461                         {\r
462                                 vTaskIncrementTick();\r
463                                 x++;\r
464                         }\r
465                 }\r
466 \r
467                 uxMix++;\r
468                 if( uxMix > 8 )\r
469                 {\r
470                         uxMix = 0;\r
471                 }\r
472 \r
473                 /* Make sure time does not go past that expected. */\r
474                 if( x > uxMaxIterations )\r
475                 {\r
476                         xTickCount -= ( portTickType ) ( x - uxMaxIterations );\r
477                 }\r
478 \r
479                 /* Empty the command queue. */\r
480                 prvProcessReceivedCommands();           \r
481         }\r
482 \r
483         /* Catch up with the tick count, if it was incremented more than once in one\r
484         go. */\r
485         xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );\r
486         prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
487                 \r
488         /* This time, if the task blocked, there is nothing left to do.  If it didn't\r
489         block then empty the command queue for good measure. */\r
490         if( listIS_CONTAINED_WITHIN( ( xList * ) &( pxReadyTasksLists[ 0 ] ), &( ( ( tskTCBx * ) pxCurrentTCB )->xGenericListItem ) ) != pdFALSE )\r
491         {\r
492                 /* Empty the command queue. */\r
493                 prvProcessReceivedCommands();           \r
494         }\r
495 \r
496         /* Check each timer has incremented the expected number of times. */\r
497         for( x = 0; x < tmrtestNUM_TIMERS; x++ )\r
498         {\r
499                 uxPeriod = ( x + ( unsigned portBASE_TYPE ) 1 ) * uxPeriodMultiplier;\r
500                 uxExpectedIncrements = ( uxMaxIterations / ( unsigned portBASE_TYPE ) uxPeriod );\r
501         \r
502                 if( uxAutoReloadTimerCounters[ x ] != uxExpectedIncrements )\r
503                 {\r
504                         prvTestFailed();\r
505                 }\r
506         }\r
507 \r
508         return xTestStatus;\r
509 }\r
510 \r
511 /*-----------------------------------------------------------*/\r
512 \r
513 void vRunTimerModuleTests( void )\r
514 {\r
515         xTimerTest1_xTimeStartAndResetWakeTimeCalculation();\r
516         xTimerTest2_xTestFreeRunningBehaviour( 1 );\r
517         xTimerTest2_xTestFreeRunningBehaviour( 10 );\r
518         xTimerTest2_xTestFreeRunningBehaviour( 25 );\r
519         xTimerTest2_xTestFreeRunningBehaviour( 50 );\r
520         xTimerTest2_xTestFreeRunningBehaviour( 121 );\r
521 \r
522         for( ;; );\r
523 }\r
524 \r
525 #endif TIMER_TEST_H\r
526 \r