/*\r
- * FreeRTOS Kernel V10.1.0\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
*\r
* Permission is hereby granted, free of charge, to any person obtaining a copy of\r
* this software and associated documentation files (the "Software"), to deal in\r
#define configTIMER_SERVICE_TASK_NAME "Tmr Svc"\r
#endif\r
\r
+/* Bit definitions used in the ucStatus member of a timer structure. */\r
+#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 )\r
+#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 )\r
+#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 )\r
+\r
/* The definition of the timers themselves. */\r
-typedef struct TimerDef_t\r
+typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */\r
{\r
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. */\r
ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */\r
TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */\r
- 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. */\r
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */\r
TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */\r
#if( configUSE_TRACE_FACILITY == 1 )\r
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */\r
#endif\r
-\r
- #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )\r
- 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. */\r
- #endif\r
+ uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */\r
} xTIMER;\r
\r
/* The old xTIMER name is maintained above then typedefed to the new Timer_t\r
\r
/* The list in which active timers are stored. Timers are referenced in expire\r
time order, with the nearest expiry time at the front of the list. Only the\r
-timer service task is allowed to access these lists. */\r
+timer service task is allowed to access these lists.\r
+xActiveTimerList1 and xActiveTimerList2 could be at function scope but that\r
+breaks some kernel aware debuggers, and debuggers that reply on removing the\r
+static qualifier. */\r
+PRIVILEGED_DATA static List_t xActiveTimerList1;\r
+PRIVILEGED_DATA static List_t xActiveTimerList2;\r
PRIVILEGED_DATA static List_t *pxCurrentTimerList;\r
PRIVILEGED_DATA static List_t *pxOverflowTimerList;\r
\r
* task. Other tasks communicate with the timer service task using the\r
* xTimerQueue queue.\r
*/\r
-static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;\r
+static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Called by the timer service task to interpret and process a command it\r
\r
/*\r
* An active timer has reached its expire time. Reload the timer if it is an\r
- * auto reload timer, then call its callback.\r
+ * auto-reload timer, then call its callback.\r
*/\r
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;\r
\r
\r
if( pxNewTimer != NULL )\r
{\r
+ /* Status is thus far zero as the timer is not created statically\r
+ and has not been started. The auto-reload bit may get set in\r
+ prvInitialiseNewTimer. */\r
+ pxNewTimer->ucStatus = 0x00;\r
prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
-\r
- #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
- {\r
- /* Timers can be created statically or dynamically, so note this\r
- timer was created dynamically in case the timer is later\r
- deleted. */\r
- pxNewTimer->ucStaticallyAllocated = pdFALSE;\r
- }\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\r
}\r
\r
return pxNewTimer;\r
}\r
\r
-#endif /* configSUPPORT_STATIC_ALLOCATION */\r
+#endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
/*-----------------------------------------------------------*/\r
\r
#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
\r
if( pxNewTimer != NULL )\r
{\r
- prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
+ /* Timers can be created statically or dynamically so note this\r
+ timer was created statically in case it is later deleted. The\r
+ auto-reload bit may get set in prvInitialiseNewTimer(). */\r
+ pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;\r
\r
- #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
- {\r
- /* Timers can be created statically or dynamically so note this\r
- timer was created statically in case it is later deleted. */\r
- pxNewTimer->ucStaticallyAllocated = pdTRUE;\r
- }\r
- #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
}\r
\r
return pxNewTimer;\r
parameters. */\r
pxNewTimer->pcTimerName = pcTimerName;\r
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
- pxNewTimer->uxAutoReload = uxAutoReload;\r
pxNewTimer->pvTimerID = pvTimerID;\r
pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
+ if( uxAutoReload != pdFALSE )\r
+ {\r
+ pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;\r
+ }\r
traceTIMER_CREATE( pxNewTimer );\r
}\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload )\r
+{\r
+Timer_t * pxTimer = xTimer;\r
+\r
+ configASSERT( xTimer );\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( uxAutoReload != pdFALSE )\r
+ {\r
+ pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;\r
+ }\r
+ else\r
+ {\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer )\r
+{\r
+Timer_t * pxTimer = xTimer;\r
+UBaseType_t uxReturn;\r
+\r
+ configASSERT( xTimer );\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 )\r
+ {\r
+ /* Not an auto-reload timer. */\r
+ uxReturn = ( UBaseType_t ) pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ /* Is an auto-reload timer. */\r
+ uxReturn = ( UBaseType_t ) pdTRUE;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return uxReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )\r
{\r
Timer_t * pxTimer = xTimer;\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
- /* If the timer is an auto reload timer then calculate the next\r
+ /* If the timer is an auto-reload timer then calculate the next\r
expiry time and re-insert the timer in the list of active timers. */\r
- if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
/* The timer is inserted into a list using a time relative to anything\r
other than the current time. It will therefore be inserted into the\r
}\r
else\r
{\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
mtCOVERAGE_TEST_MARKER();\r
}\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvTimerTask( void *pvParameters )\r
+static portTASK_FUNCTION( prvTimerTask, pvParameters )\r
{\r
TickType_t xNextExpireTime;\r
BaseType_t xListWasEmpty;\r
switch( xMessage.xMessageID )\r
{\r
case tmrCOMMAND_START :\r
- case tmrCOMMAND_START_FROM_ISR :\r
- case tmrCOMMAND_RESET :\r
- case tmrCOMMAND_RESET_FROM_ISR :\r
+ case tmrCOMMAND_START_FROM_ISR :\r
+ case tmrCOMMAND_RESET :\r
+ case tmrCOMMAND_RESET_FROM_ISR :\r
case tmrCOMMAND_START_DONT_TRACE :\r
/* Start or restart a timer. */\r
+ pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;\r
if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE )\r
{\r
/* The timer expired before it was added to the active\r
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
configASSERT( xResult );\r
\r
case tmrCOMMAND_STOP :\r
case tmrCOMMAND_STOP_FROM_ISR :\r
- /* The timer has already been removed from the active list.\r
- There is nothing to do here. */\r
+ /* The timer has already been removed from the active list. */\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
break;\r
\r
case tmrCOMMAND_CHANGE_PERIOD :\r
case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR :\r
+ pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE;\r
pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;\r
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
\r
break;\r
\r
case tmrCOMMAND_DELETE :\r
- /* The timer has already been removed from the active list,\r
- just free up the memory if the memory was dynamically\r
- allocated. */\r
- #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )\r
- {\r
- /* The timer can only have been allocated dynamically -\r
- free it again. */\r
- vPortFree( pxTimer );\r
- }\r
- #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )\r
+ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
{\r
- /* The timer could have been allocated statically or\r
- dynamically, so check before attempting to free the\r
- memory. */\r
- if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )\r
+ /* The timer has already been removed from the active list,\r
+ just free up the memory if the memory was dynamically\r
+ allocated. */\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )\r
{\r
vPortFree( pxTimer );\r
}\r
else\r
{\r
- mtCOVERAGE_TEST_MARKER();\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
}\r
}\r
+ #else\r
+ {\r
+ /* If dynamic allocation is not enabled, the memory\r
+ could not have been dynamically allocated. So there is\r
+ no need to free the memory - just mark the timer as\r
+ "not active". */\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
+ }\r
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
break;\r
\r
have not yet been switched. */\r
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
/* Calculate the reload value, and if the reload value results in\r
the timer going into the same timer list then it has already expired\r
\r
static void prvCheckForValidListAndQueue( void )\r
{\r
-PRIVILEGED_DATA static List_t xActiveTimerList1;\r
-PRIVILEGED_DATA static List_t xActiveTimerList2;\r
-\r
/* Check that the list from which active timers are referenced, and the\r
queue used to communicate with the timer service, have been\r
initialised. */\r
\r
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )\r
{\r
-BaseType_t xTimerIsInActiveList;\r
+BaseType_t xReturn;\r
Timer_t *pxTimer = xTimer;\r
\r
configASSERT( xTimer );\r
/* Is the timer in the list of active timers? */\r
taskENTER_CRITICAL();\r
{\r
- /* Checking to see if it is in the NULL list in effect checks to see if\r
- it is referenced from either the current or the overflow timer lists in\r
- one go, but the logic has to be reversed, hence the '!'. */\r
- if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )\r
{\r
- xTimerIsInActiveList = pdFALSE;\r
+ xReturn = pdFALSE;\r
}\r
else\r
{\r
- xTimerIsInActiveList = pdTRUE;\r
+ xReturn = pdTRUE;\r
}\r
}\r
taskEXIT_CRITICAL();\r
\r
- return xTimerIsInActiveList;\r
+ return xReturn;\r
} /*lint !e818 Can't be pointer to const due to the typedef. */\r
/*-----------------------------------------------------------*/\r
\r