From 477bd40c1a1bc93b344686101c350f22ff30eea9 Mon Sep 17 00:00:00 2001 From: rtel Date: Wed, 24 Oct 2018 21:37:59 +0000 Subject: [PATCH] Update the method used to detect if a timer is active. Previously the timer was deemed to be inactive if it was not referenced from a list. However, when a timer is updated it is temporarily removed from, then re-added to a list, so now the timer's active status is stored separately. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2589 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Source/include/FreeRTOS.h | 6 +- FreeRTOS/Source/timers.c | 89 ++++++++++++------------------ 2 files changed, 37 insertions(+), 58 deletions(-) diff --git a/FreeRTOS/Source/include/FreeRTOS.h b/FreeRTOS/Source/include/FreeRTOS.h index 9329e0cff..e599b013b 100644 --- a/FreeRTOS/Source/include/FreeRTOS.h +++ b/FreeRTOS/Source/include/FreeRTOS.h @@ -1142,16 +1142,12 @@ typedef struct xSTATIC_TIMER void *pvDummy1; StaticListItem_t xDummy2; TickType_t xDummy3; - UBaseType_t uxDummy4; void *pvDummy5; TaskFunction_t pvDummy6; #if( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxDummy7; #endif - - #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucDummy8; - #endif + uint8_t ucDummy8; } StaticTimer_t; diff --git a/FreeRTOS/Source/timers.c b/FreeRTOS/Source/timers.c index 4e24a297a..a64565b41 100644 --- a/FreeRTOS/Source/timers.c +++ b/FreeRTOS/Source/timers.c @@ -64,22 +64,23 @@ defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" #endif +/* Bit definitions used in the ucStatus member of a timer structure. */ +#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) +#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) +#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + /* The definition of the timers themselves. */ typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ { const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ - UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ #if( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ #endif - - #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */ - #endif + uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ } xTIMER; /* The old xTIMER name is maintained above then typedefed to the new Timer_t @@ -127,7 +128,7 @@ which static variables must be declared volatile. */ /* The list in which active timers are stored. Timers are referenced in expire time order, with the nearest expiry time at the front of the list. Only the -timer service task is allowed to access these lists. +timer service task is allowed to access these lists. xActiveTimerList1 and xActiveTimerList2 could be at function scope but that breaks some kernel aware debuggers, and debuggers that reply on removing the static qualifier. */ @@ -290,16 +291,11 @@ BaseType_t xReturn = pdFAIL; if( pxNewTimer != NULL ) { + /* Status is thus far zero as the timer is not created statically + and has not been started. The autoreload bit may get set in + prvInitialiseNewTimer. */ + pxNewTimer->ucStatus = 0x00; prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); - - #if( configSUPPORT_STATIC_ALLOCATION == 1 ) - { - /* Timers can be created statically or dynamically, so note this - timer was created dynamically in case the timer is later - deleted. */ - pxNewTimer->ucStaticallyAllocated = pdFALSE; - } - #endif /* configSUPPORT_STATIC_ALLOCATION */ } return pxNewTimer; @@ -336,15 +332,12 @@ BaseType_t xReturn = pdFAIL; if( pxNewTimer != NULL ) { - prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + /* Timers can be created statically or dynamically so note this + timer was created statically in case it is later deleted. The + autoreload bit may get set in prvInitialiseNewTimer(). */ + pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; - #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) - { - /* Timers can be created statically or dynamically so note this - timer was created statically in case it is later deleted. */ - pxNewTimer->ucStaticallyAllocated = pdTRUE; - } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); } return pxNewTimer; @@ -373,10 +366,13 @@ static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e97 parameters. */ pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; - pxNewTimer->uxAutoReload = uxAutoReload; pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pxCallbackFunction = pxCallbackFunction; vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + if( uxAutoReload != pdFALSE ) + { + pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } traceTIMER_CREATE( pxNewTimer ); } } @@ -475,7 +471,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi /* If the timer is an auto reload timer then calculate the next expiry time and re-insert the timer in the list of active timers. */ - if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) { /* The timer is inserted into a list using a time relative to anything other than the current time. It will therefore be inserted into the @@ -495,6 +491,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi } else { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; mtCOVERAGE_TEST_MARKER(); } @@ -756,6 +753,7 @@ TickType_t xTimeNow; case tmrCOMMAND_RESET_FROM_ISR : case tmrCOMMAND_START_DONT_TRACE : /* Start or restart a timer. */ + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) { /* The timer expired before it was added to the active @@ -763,7 +761,7 @@ TickType_t xTimeNow; pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); traceTIMER_EXPIRED( pxTimer ); - if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) { xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); configASSERT( xResult ); @@ -782,12 +780,13 @@ TickType_t xTimeNow; case tmrCOMMAND_STOP : case tmrCOMMAND_STOP_FROM_ISR : - /* The timer has already been removed from the active list. - There is nothing to do here. */ + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; break; case tmrCOMMAND_CHANGE_PERIOD : case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); @@ -804,27 +803,14 @@ TickType_t xTimeNow; /* The timer has already been removed from the active list, just free up the memory if the memory was dynamically allocated. */ - #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) { - /* The timer can only have been allocated dynamically - - free it again. */ vPortFree( pxTimer ); } - #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + else { - /* The timer could have been allocated statically or - dynamically, so check before attempting to free the - memory. */ - if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) - { - vPortFree( pxTimer ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; } - #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ break; default : @@ -861,7 +847,7 @@ BaseType_t xResult; have not yet been switched. */ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); - if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) { /* Calculate the reload value, and if the reload value results in the timer going into the same timer list then it has already expired @@ -948,7 +934,7 @@ static void prvCheckForValidListAndQueue( void ) BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) { -BaseType_t xTimerIsInActiveList; +BaseType_t xReturn; Timer_t *pxTimer = xTimer; configASSERT( xTimer ); @@ -956,21 +942,18 @@ Timer_t *pxTimer = xTimer; /* Is the timer in the list of active timers? */ taskENTER_CRITICAL(); { - /* Checking to see if it is in the NULL list in effect checks to see if - it is referenced from either the current or the overflow timer lists in - one go, but the logic has to be reversed, hence the '!'. */ - if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdTRUE ) + if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) { - xTimerIsInActiveList = pdFALSE; + xReturn = pdFALSE; } else { - xTimerIsInActiveList = pdTRUE; + xReturn = pdTRUE; } } taskEXIT_CRITICAL(); - return xTimerIsInActiveList; + return xReturn; } /*lint !e818 Can't be pointer to const due to the typedef. */ /*-----------------------------------------------------------*/ -- 2.39.5