| /* | |
| FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd. | |
| *************************************************************************** | |
| * * | |
| * If you are: * | |
| * * | |
| * + New to FreeRTOS, * | |
| * + Wanting to learn FreeRTOS or multitasking in general quickly * | |
| * + Looking for basic training, * | |
| * + Wanting to improve your FreeRTOS skills and productivity * | |
| * * | |
| * then take a look at the FreeRTOS books - available as PDF or paperback * | |
| * * | |
| * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * | |
| * http://www.FreeRTOS.org/Documentation * | |
| * * | |
| * A pdf reference manual is also available. Both are usually delivered * | |
| * to your inbox within 20 minutes to two hours when purchased between 8am * | |
| * and 8pm GMT (although please allow up to 24 hours in case of * | |
| * exceptional circumstances). Thank you for your support! * | |
| * * | |
| *************************************************************************** | |
| This file is part of the FreeRTOS distribution. | |
| FreeRTOS is free software; you can redistribute it and/or modify it under | |
| the terms of the GNU General Public License (version 2) as published by the | |
| Free Software Foundation AND MODIFIED BY the FreeRTOS exception. | |
| ***NOTE*** The exception to the GPL is included to allow you to distribute | |
| a combined work that includes FreeRTOS without being obliged to provide the | |
| source code for proprietary components outside of the FreeRTOS kernel. | |
| FreeRTOS is distributed in the hope that it will be useful, but WITHOUT | |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| more details. You should have received a copy of the GNU General Public | |
| License and the FreeRTOS license exception along with FreeRTOS; if not it | |
| can be viewed here: http://www.freertos.org/a00114.html and also obtained | |
| by writing to Richard Barry, contact details for whom are available on the | |
| FreeRTOS WEB site. | |
| 1 tab == 4 spaces! | |
| http://www.FreeRTOS.org - Documentation, latest information, license and | |
| contact details. | |
| http://www.SafeRTOS.com - A version that is certified for use in safety | |
| critical systems. | |
| http://www.OpenRTOS.com - Commercial support, development, porting, | |
| licensing and training services. | |
| */ | |
| /* | |
| * Tests the behaviour of timers. Some timers are created before hte scheudler | |
| * is started, and some after. | |
| */ | |
| /* Standard includes. */ | |
| #include <string.h> | |
| /* Scheduler include files. */ | |
| #include "FreeRTOS.h" | |
| #include "task.h" | |
| #include "timers.h" | |
| /* Demo program include files. */ | |
| #include "TimerDemo.h" | |
| #if configTIMER_TASK_PRIORITY < 1 | |
| #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly. | |
| #endif | |
| #define tmrdemoDONT_BLOCK ( ( portTickType ) 0 ) | |
| #define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( portTickType ) 3 ) | |
| #define trmdemoNUM_TIMER_RESETS ( ( unsigned char ) 10 ) | |
| /*-----------------------------------------------------------*/ | |
| static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer ); | |
| static void prvTimerControlTask( void *pvParameters ); | |
| static void prvTest1_CreateTimersWithoutSchedulerRunning( void ); | |
| static void prvTest3_CheckAutoReloadExpireRates( void ); | |
| static void prvTest2_CheckTaskAndTimersInitialState( void ); | |
| static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ); | |
| static void prvTest5_CheckBasicOneShotTimerBehaviour( void ); | |
| static void prvTest6_CheckAutoReloadResetBehaviour( void ); | |
| static void prvResetStartConditionsForNextIteration( void ); | |
| /*-----------------------------------------------------------*/ | |
| /* Flag that will be latched to pdFAIL should any unexpected behaviour be | |
| detected in any of the demo tests. */ | |
| static volatile portBASE_TYPE xTestStatus = pdPASS; | |
| /* Counter that is incremented on each cycle of a test. This is used to | |
| detect a stalled task - a test that is no longer running. */ | |
| static volatile unsigned portLONG ulLoopCounter = 0; | |
| static xTimerHandle xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; | |
| static unsigned char ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; | |
| static unsigned char ucOneShotTimerCounter = ( unsigned char ) 0; | |
| static xTimerHandle xOneShotTimer = NULL; | |
| static portTickType xBasePeriod = 0; | |
| /*-----------------------------------------------------------*/ | |
| void vStartTimerDemoTask( portTickType xBasePeriodIn ) | |
| { | |
| /* Store the period from which all the timer periods will be generated from | |
| (multiples of). */ | |
| xBasePeriod = xBasePeriodIn; | |
| /* Create a set of timers for use by this demo/test. */ | |
| prvTest1_CreateTimersWithoutSchedulerRunning(); | |
| /* Create the task that will control and monitor the timers. This is | |
| created at a lower priority than the timer service task to ensure, as | |
| far as it is concerned, commands on timers are actioned immediately | |
| (sending a command to the timer service task will unblock the timer service | |
| task, which will then preempt this task). */ | |
| if( xTestStatus != pdFAIL ) | |
| { | |
| xTaskCreate( prvTimerControlTask, ( signed portCHAR * ) "Tmr Ctl", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL ); | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvAutoReloadTimerCallback( xTimerHandle pxExpiredTimer ) | |
| { | |
| portBASE_TYPE xTimerID; | |
| xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( pxExpiredTimer ); | |
| if( xTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) ) | |
| { | |
| ( ucAutoReloadTimerCounters[ xTimerID ] )++; | |
| } | |
| else | |
| { | |
| /* The timer ID appears to be unexpected (invalid). */ | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer ) | |
| { | |
| /* The parameter is not used in this case as only one timer uses this | |
| callback function. */ | |
| ( void ) pxExpiredTimer; | |
| ucOneShotTimerCounter++; | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTimerControlTask( void *pvParameters ) | |
| { | |
| ( void ) pvParameters; | |
| /* Create a one-shot timer for use later on in this test. */ | |
| xOneShotTimer = xTimerCreate( "Oneshot Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ | |
| tmrdemoONE_SHOT_TIMER_PERIOD,/* The period for the timer. */ | |
| pdFALSE, /* Don't autoreload - hence a one shot timer. */ | |
| ( void * ) 0, /* The timer identifier. In this case this is not used as the timer has its own callback. */ | |
| prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */ | |
| if( xOneShotTimer == NULL ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Ensure all the timers are in their expected initial state. This | |
| depends on the timer service task having a higher priority than this task. */ | |
| prvTest2_CheckTaskAndTimersInitialState(); | |
| for( ;; ) | |
| { | |
| /* Check the auto reload timers expire at the expected/correct rates. */ | |
| prvTest3_CheckAutoReloadExpireRates(); | |
| /* Check the auto reload timers can be stopped correctly, and correctly | |
| report their state. */ | |
| prvTest4_CheckAutoReloadTimersCanBeStopped(); | |
| /* Check the one shot timer only calls its callback once after it has been | |
| started, and that it reports its state correctly. */ | |
| prvTest5_CheckBasicOneShotTimerBehaviour(); | |
| /* Check timer reset behaviour. */ | |
| prvTest6_CheckAutoReloadResetBehaviour(); | |
| /* Start the timers again to restart all the tests over again. */ | |
| prvResetStartConditionsForNextIteration(); | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| /* This is called to check that the created task is still running and has not | |
| detected any errors. */ | |
| portBASE_TYPE xAreTimerDemoTasksStillRunning( void ) | |
| { | |
| static unsigned portLONG ulLastLoopCounter = 0; | |
| /* If the demo task is still running then we expect the loopcounter to | |
| have incremented since this function was last called. */ | |
| if( ulLastLoopCounter == ulLoopCounter ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| ulLastLoopCounter = ulLoopCounter; | |
| /* Errors detected in the task itself will have latched xTestStatus | |
| to pdFAIL. */ | |
| return xTestStatus; | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest1_CreateTimersWithoutSchedulerRunning( void ) | |
| { | |
| portBASE_TYPE xTimer; | |
| for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ ) | |
| { | |
| /* As the timer queue is not yet full, it should be possible to both create | |
| and start a timer. These timers are being started before the scheduler has | |
| been started, so their block times should get set to zero within the timer | |
| API itself. */ | |
| xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ | |
| ( ( xTimer + 1 ) * xBasePeriod ),/* The period for the timer. The plus 1 ensures a period of zero is not specified. */ | |
| pdTRUE, /* Autoreload is set to true. */ | |
| ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ | |
| prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ | |
| if( xAutoReloadTimers[ xTimer ] == NULL ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| else | |
| { | |
| /* The scheduler has not yet started, so the block period of | |
| portMAX_DELAY should just get set to zero in xTimerStart(). Also, | |
| the timer queue is not yet full so xTimerStart() should return | |
| pdPASS. */ | |
| if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| } | |
| /* The timers queue should now be full, so it should be possible to create | |
| another timer, but not possible to start it (the timer queue will not get | |
| drained until the scheduler has been started. */ | |
| xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ | |
| ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */ | |
| pdTRUE, /* Autoreload is set to true. */ | |
| ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ | |
| prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ | |
| if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| else | |
| { | |
| if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS ) | |
| { | |
| /* This time it would not be expected that the timer could be | |
| started at this point. */ | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest2_CheckTaskAndTimersInitialState( void ) | |
| { | |
| unsigned char ucTimer; | |
| /* Ensure all the timers are in their expected initial state. This depends | |
| on the timer service task having a higher priority than this task. | |
| auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active, | |
| and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it | |
| could not be started prior to the scheduler being started when it was | |
| created). */ | |
| for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ ) | |
| { | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest3_CheckAutoReloadExpireRates( void ) | |
| { | |
| unsigned char ucMaxAllowableValue, ucMinAllowableValue, ucTimer; | |
| portTickType xNextWakeTime; | |
| /* Check the auto reload timers expire at the expcted rates. */ | |
| /* Initialise the next wake time value before the call to vTaskDelayUntil() | |
| as this is not really a periodic task. */ | |
| xNextWakeTime = xTaskGetTickCount(); | |
| /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow | |
| all the auto reload timers to expire at least once. */ | |
| vTaskDelayUntil( &xNextWakeTime, ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); | |
| /* Check that all the auto reload timers have called their callback | |
| function the expected number of times. */ | |
| for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ ) | |
| { | |
| /* The timer in array position 0 should elapse every xBasePeriod ticks, | |
| the timer in array position 1 should elapse every ( 2 * xBasePeriod ) | |
| ticks, etc. This task blocked for configTIMER_QUEUE_LENGTH * xBasePeriod, | |
| so the timer in array position 0 should have elapsed | |
| configTIMER_QUEUE_LENGTH times, the timer in array possition 1 should | |
| have elapsed ( configTIMER_QUEUE_LENGTH - 1 ) times, etc. */ | |
| ucMaxAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer ); | |
| ucMinAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer ) - 1; | |
| if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) || | |
| ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue ) | |
| ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so the | |
| check task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ) | |
| { | |
| unsigned char ucTimer; | |
| /* Check the auto reload timers can be stopped correctly, and correctly | |
| report their state. */ | |
| /* Stop all the active timers. */ | |
| for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ ) | |
| { | |
| /* The timer has not been stopped yet! */ | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Now stop the timer. This will appear to happen immediately to | |
| this task because this task is running at a priority below the | |
| timer service task. */ | |
| xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); | |
| /* The timer should now be inactive. */ | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| taskENTER_CRITICAL(); | |
| { | |
| /* The timer in array position configTIMER_QUEUE_LENGTH should not | |
| be active. The critical section is used to ensure the timer does | |
| not call its callback between the next line running and the array | |
| being cleared back to zero, as that would mask an error condition. */ | |
| if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( unsigned char ) 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Clear the timer callback count. */ | |
| memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) ); | |
| } | |
| taskEXIT_CRITICAL(); | |
| /* The timers are now all inactive, so this time, after delaying, none | |
| of the callback counters should have incremented. */ | |
| vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); | |
| for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ ) | |
| { | |
| if( ucAutoReloadTimerCounters[ ucTimer ] != ( unsigned char ) 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so | |
| the check task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest5_CheckBasicOneShotTimerBehaviour( void ) | |
| { | |
| /* Check the one shot timer only calls its callback once after it has been | |
| started, and that it reports its state correctly. */ | |
| /* The one shot timer should not be active yet. */ | |
| if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( ucOneShotTimerCounter != ( unsigned char ) 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Start the one shot timer and check that it reports its state correctly. */ | |
| xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); | |
| if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Delay for three times as long as the one shot timer period, then check | |
| to ensure it has only called its callback once, and is now not in the | |
| active state. */ | |
| vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( portTickType ) 3 ); | |
| if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( ucOneShotTimerCounter != ( unsigned char ) 1 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| else | |
| { | |
| /* Reset the one shot timer callback count. */ | |
| ucOneShotTimerCounter = ( unsigned char ) 0; | |
| } | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so the | |
| check task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvTest6_CheckAutoReloadResetBehaviour( void ) | |
| { | |
| unsigned char ucTimer; | |
| /* Check timer reset behaviour. */ | |
| /* Restart the one shot timer and check it reports its status correctly. */ | |
| xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); | |
| if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Restart one of the auto reload timers and check that it reports its | |
| status correctly. */ | |
| xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ ) | |
| { | |
| /* Delay for half as long as the one shot timer period, then reset it. | |
| It should never expire while this is done, so its callback count should | |
| never increment. */ | |
| vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 ); | |
| /* Check both running timers are still active, but have not called their | |
| callback functions. */ | |
| if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( ucOneShotTimerCounter != ( unsigned char ) 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( unsigned char ) 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Reset both running timers. */ | |
| xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); | |
| xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so | |
| the check task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /* Finally delay long enough for both running timers to expire. */ | |
| vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); | |
| /* The timers were not reset during the above delay period so should now | |
| both have called their callback functions. */ | |
| if( ucOneShotTimerCounter != ( unsigned char ) 1 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* The one shot timer should no longer be active, while the auto reload | |
| timer should still be active. */ | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Stop the auto reload timer again. */ | |
| xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Clear the timer callback counts, ready for another iteration of these | |
| tests. */ | |
| ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( unsigned char ) 0; | |
| ucOneShotTimerCounter = ( unsigned char ) 0; | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so the check | |
| task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |
| static void prvResetStartConditionsForNextIteration( void ) | |
| { | |
| unsigned char ucTimer; | |
| /* Start the timers again to start all the tests over again. */ | |
| /* Start the timers again. */ | |
| for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ ) | |
| { | |
| /* The timer has not been started yet! */ | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| /* Now start the timer. This will appear to happen immediately to | |
| this task because this task is running at a priority below the timer | |
| service task. */ | |
| xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); | |
| /* The timer should now be active. */ | |
| if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) | |
| { | |
| xTestStatus = pdFAIL; | |
| } | |
| } | |
| if( xTestStatus == pdPASS ) | |
| { | |
| /* No errors have been reported so increment the loop counter so the | |
| check task knows this task is still running. */ | |
| ulLoopCounter++; | |
| } | |
| } | |
| /*-----------------------------------------------------------*/ | |