From c45881caeaaf50c9052fbfdcfd29f480a4f2815b Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 20 Feb 2011 10:59:58 +0000 Subject: [PATCH] Updates to timers.c related to module testing. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1301 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/timers.c | 102 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/Source/timers.c b/Source/timers.c index c9d592c28..bcdea58a2 100644 --- a/Source/timers.c +++ b/Source/timers.c @@ -123,7 +123,7 @@ static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, * depending on if the expire time causes a timer counter overflow. */ -static void prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION; +static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION; /* * An active timer has reached its expire time. Reload the timer if it is an @@ -183,22 +183,32 @@ xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPe xTIMER *pxNewTimer; /* Allocate the timer structure. */ - pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) ); - if( pxNewTimer != NULL ) + if( xTimerPeriodInTicks == ( portTickType ) 0U ) { - /* Ensure the infrastructure used by the timer service task has been - created/initialised. */ - prvCheckForValidListAndQueue(); - - /* Initialise the timer structure members using the function parameters. */ - pxNewTimer->pcTimerName = pcTimerName; - pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; - pxNewTimer->uxAutoReload = uxAutoReload; - pxNewTimer->pvTimerID = pvTimerID; - pxNewTimer->pxCallbackFunction = pxCallbackFunction; - vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + pxNewTimer = NULL; + configASSERT( ( xTimerPeriodInTicks > 0 ) ); } - + else + { + pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) ); + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + /* Initialise the timer structure members using the function parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->uxAutoReload = uxAutoReload; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + } + } + return ( xTimerHandle ) pxNewTimer; } /*-----------------------------------------------------------*/ @@ -234,6 +244,7 @@ xTIMER_MESSAGE xMessage; } } + configASSERT( xReturn ); return xReturn; } /*-----------------------------------------------------------*/ @@ -311,11 +322,11 @@ portBASE_TYPE xTimerListsWereSwitched; } else { - /* The tick count has not overflowed, and the next expire - time has not been reached yet. This task should therefore - block to wait for the next expire time or a command to be + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be received - whichever comes first. The following line cannot - be reached unless xNextExpireTime > xTimeNow, except in the + be reached unless xNextExpireTime > xTimeNow, except in the case when the current timer list is empty. */ vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); } @@ -341,7 +352,7 @@ portTickType xNextExpireTime; the timer with the nearest expiry time will expire. If there are no active timers then just set the next expire time to 0. That will cause this task to unblock when the tick count overflows, at which point the - timer lists will be switched and the next expiry time can be + timer lists will be switched and the next expiry time can be re-assessed. */ *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); if( *pxListWasEmpty == pdFALSE ) @@ -381,19 +392,44 @@ static portTickType xLastTime = ( portTickType ) 0U; } /*-----------------------------------------------------------*/ -static void prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow ) +static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) { +portBASE_TYPE xProcessTimerNow = pdFALSE; + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); - if( xNextExpiryTime < xTimeNow ) + if( xNextExpiryTime <= xTimeNow ) { - vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks ) + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } } else { - vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } } + + return xProcessTimerNow; } /*-----------------------------------------------------------*/ @@ -428,7 +464,18 @@ portTickType xTimeNow; { case tmrCOMMAND_START : /* Start or restart a timer. */ - prvInsertTimerInActiveList( pxTimer, xTimeNow + pxTimer->xTimerPeriodInTicks, xTimeNow ); + if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Process it now. */ + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + + if( pxTimer->uxAutoReload == pdTRUE ) + { + xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + } + } break; case tmrCOMMAND_STOP : @@ -438,7 +485,8 @@ portTickType xTimeNow; case tmrCOMMAND_CHANGE_PERIOD : pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; - prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow ); + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); break; case tmrCOMMAND_DELETE : @@ -528,5 +576,3 @@ xTIMER *pxTimer = ( xTIMER * ) xTimer; /*-----------------------------------------------------------*/ - - -- 2.39.5