Skip to content

Commit 2e77211

Browse files
authored
Add test late timer start (retry FreeRTOS#557) (FreeRTOS#591)
* Add test for timer start delayed past expiration This reverts commit 53af0ec, which itself reverted 9c91199. * Add warning about vTimerDemoIncludeBacklogTests() * uncrustify for CI check * Remove unintentional changes to spacing in comments
1 parent 3693b3e commit 2e77211

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

FreeRTOS/Demo/Common/Minimal/TimerDemo.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ static void prvTest2_CheckTaskAndTimersInitialState( void )
364364
{
365365
uint8_t ucTimer;
366366

367-
/* Ensure all the timers are in their expected initial state. This depends
367+
/* Ensure all the timers are in their expected initial state. This depends
368368
* on the timer service task having a higher priority than this task.
369369
*
370370
* auto-reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active,
@@ -691,6 +691,8 @@ static void prvTest6_CheckAutoReloadResetBehaviour( void )
691691

692692
static void prvTest7_CheckBacklogBehaviour( void )
693693
{
694+
UBaseType_t uxOriginalPriority;
695+
694696
/* Use the first auto-reload timer to test stopping a timer from a
695697
* backlogged callback. */
696698

@@ -739,6 +741,55 @@ static void prvTest7_CheckBacklogBehaviour( void )
739741
/* Clear the reload count for the timer used in this test. */
740742
ucAutoReloadTimerCounters[ 0 ] = ( uint8_t ) 0;
741743

744+
745+
/* Verify a one-shot timer is marked as inactive if the timer task processes
746+
* the start or reset request after the expiration time has passed. */
747+
748+
/* The timer has not been started yet! */
749+
if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )
750+
{
751+
xTestStatus = pdFAIL;
752+
configASSERT( xTestStatus );
753+
}
754+
755+
/* Use the timer period specific to backlogged timers because it reduces
756+
* the impact on other tests that might be running when xTaskCatchUpTicks()
757+
* creates the backlog, below. */
758+
xTimerChangePeriod( xOneShotTimer, tmrdemoBACKLOG_TIMER_PERIOD, tmrdemoDONT_BLOCK );
759+
760+
/* Temporarily give this task maximum priority so it can cause the timer
761+
* task to delay its processing of the reset request below. */
762+
uxOriginalPriority = uxTaskPriorityGet( NULL );
763+
vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) );
764+
765+
/* Reset the timer. The timer service won't process this request right
766+
* away as noted above. */
767+
xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );
768+
769+
/* Cause the timer period to elapse without giving an opportunity for the
770+
* timer service task to process the reset request. */
771+
xTaskCatchUpTicks( tmrdemoBACKLOG_TIMER_PERIOD );
772+
773+
/* Return this task to its original priority. The timer service task will
774+
* process the reset request immediately. The timer task must handle the reset
775+
* request as if it were processed at the time of the request even though in
776+
* this test the processing occurs after the intended expiration time. */
777+
vTaskPrioritySet( NULL, uxOriginalPriority );
778+
779+
/* The timer should now be inactive. */
780+
if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )
781+
{
782+
xTestStatus = pdFAIL;
783+
configASSERT( xTestStatus );
784+
}
785+
786+
/* Restore the standard timer period, and leave the timer inactive. */
787+
xTimerChangePeriod( xOneShotTimer, tmrdemoONE_SHOT_TIMER_PERIOD, tmrdemoDONT_BLOCK );
788+
xTimerStop( xOneShotTimer, tmrdemoDONT_BLOCK );
789+
790+
/* Clear the counter for the timer used in this test. */
791+
ucOneShotTimerCounter = ( uint8_t ) 0;
792+
742793
if( xTestStatus == pdPASS )
743794
{
744795
/* No errors have been reported so increment the loop counter so the check
@@ -931,7 +982,7 @@ void vTimerPeriodicISRTests( void )
931982
else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) )
932983
{
933984
/* The auto-reload timer and one-shot timer will be active. At
934-
* this time the auto-reload timer should have expired again, but the one
985+
* this time the auto-reload timer should have expired again, but the one
935986
* shot timer count should not have changed yet. */
936987
if( ucISRAutoReloadTimerCounter != 3 )
937988
{
@@ -1063,8 +1114,8 @@ void vTimerPeriodicISRTests( void )
10631114
else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) )
10641115
{
10651116
/* Only the one-shot timer should have been running and this time it
1066-
* should have expired. Check its callback count has been incremented.
1067-
* The auto-reload timer is still not running so should still have the same
1117+
* should have expired. Check its callback count has been incremented.
1118+
* The auto-reload timer is still not running so should still have the same
10681119
* count value. This time the one-shot timer is not reset so should not
10691120
* restart from its expiry period again. */
10701121
if( ucISRAutoReloadTimerCounter != 3 )

FreeRTOS/Demo/Common/include/TimerDemo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
void vStartTimerDemoTask( TickType_t xBaseFrequencyIn );
3131
BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency );
3232
void vTimerPeriodicISRTests( void );
33+
34+
/*
35+
* Test the behavior of backlogged timers. The backlog tests should not be
36+
* included while other demos are running concurrently with the timer demo. The
37+
* backlog tests utilize xTaskCatchUpTicks(), which is logically equivalent to
38+
* starving all tasks for some number of ticks. Under these conditions, other
39+
* demos may errantly detect test failures.
40+
*/
3341
void vTimerDemoIncludeBacklogTests( BaseType_t includeBacklogTests );
3442

3543
#endif /* TIMER_DEMO_H */

0 commit comments

Comments
 (0)