diff --git a/FreeRTOS/Demo/Common/Minimal/TimerDemo.c b/FreeRTOS/Demo/Common/Minimal/TimerDemo.c index 70a1eec307..aaf8147636 100644 --- a/FreeRTOS/Demo/Common/Minimal/TimerDemo.c +++ b/FreeRTOS/Demo/Common/Minimal/TimerDemo.c @@ -686,6 +686,8 @@ uint8_t ucTimer; static void prvTest7_CheckBacklogBehaviour( void ) { +UBaseType_t uxOriginalPriority; + /* Use the first auto-reload timer to test stopping a timer from a backlogged callback. */ @@ -734,6 +736,55 @@ static void prvTest7_CheckBacklogBehaviour( void ) /* Clear the reload count for the timer used in this test. */ ucAutoReloadTimerCounters[ 0 ] = ( uint8_t ) 0; + + /* Verify a one-shot timer is marked as inactive if the timer task processes + the start or reset request after the expiration time has passed. */ + + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Use the timer period specific to backlogged timers because it reduces + the impact on other tests that might be running when xTaskCatchUpTicks() + creates the backlog, below. */ + xTimerChangePeriod( xOneShotTimer, tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK ); + + /* Temporarily give this task maximum priority so it can cause the timer + task to delay its processing of the reset request below. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); + + /* Reset the timer. The timer service won't process this request right + away as noted above. */ + xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); + + /* Cause the timer period to elapse without giving an opportunity for the + timer service task to process the reset request. */ + xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD ); + + /* Return this task to its original priority. The timer service task will + process the reset request immediately. The timer task must handle the reset + request as if it were processed at the time of the request even though in + this test the processing occurs after the intended expiration time. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restore the standard timer period, and leave the timer inactive. */ + xTimerChangePeriod( xOneShotTimer, tmrdemoONE_SHOT_TIMER_PERIOD, tmrdemoDONT_BLOCK ); + xTimerStop( xOneShotTimer, tmrdemoDONT_BLOCK ); + + /* Clear the counter for the timer used in this test. */ + ucOneShotTimerCounter = ( uint8_t ) 0; + if( xTestStatus == pdPASS ) { /* No errors have been reported so increment the loop counter so the check