/*\r
- FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+ FreeRTOS V9.0.0rc2 - Copyright (C) 2016 Real Time Engineers Ltd.\r
All rights reserved\r
\r
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */\r
#endif\r
\r
- #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
- uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created from a StaticTimer_t structure, and pdFALSE if the timer structure was allocated dynamically. */\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
} xTIMER;\r
\r
\r
/* A queue that is used to send commands to the timer service task. */\r
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;\r
-\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
-\r
- PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;\r
-\r
-#endif\r
+PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;\r
\r
/*lint +e956 */\r
\r
*/\r
static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION;\r
\r
+/*\r
+ * Called after a Timer_t structure has been allocated either statically or\r
+ * dynamically to fill in the structure's members.\r
+ */\r
+static void prvInitialiseNewTimer( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
/*-----------------------------------------------------------*/\r
\r
BaseType_t xTimerCreateTimerTask( void )\r
{\r
BaseType_t xReturn = pdFAIL;\r
-StaticTask_t *pxTimerTaskTCBBuffer = NULL;\r
-StackType_t *pxTimerTaskStackBuffer = NULL;\r
uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;\r
\r
\r
\r
#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
{\r
- vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &usTimerTaskStackSize );\r
- }\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+ StaticTask_t *pxTimerTaskTCBBuffer = NULL;\r
+ StackType_t *pxTimerTaskStackBuffer = NULL;\r
\r
- #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
- {\r
- /* Create the timer task, storing its handle in xTimerTaskHandle so\r
- it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */\r
- xReturn = xTaskGenericCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer, NULL );\r
+ vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &usTimerTaskStackSize );\r
+ xReturn = xTaskCreateStatic( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer );\r
}\r
#else\r
{\r
- /* Create the timer task without storing its handle. */\r
- xReturn = xTaskGenericCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer, NULL );\r
+ xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );\r
}\r
- #endif\r
+ #endif /* configSUPPORT_STATIC_ALLOCATION */\r
}\r
else\r
{\r
}\r
/*-----------------------------------------------------------*/\r
\r
-TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
-{\r
-Timer_t *pxNewTimer;\r
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
\r
- #if( ( configASSERT_DEFINED == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )\r
+ TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
{\r
- /* Sanity check that the size of the structure used to declare a\r
- variable of type StaticTimer_t equals the size of the real timer\r
- structures. */\r
- volatile size_t xSize = sizeof( StaticTimer_t );\r
- configASSERT( xSize == sizeof( Timer_t ) );\r
- }\r
- #endif /* configASSERT_DEFINED */\r
+ Timer_t *pxNewTimer;\r
\r
- /* Allocate the timer structure. */\r
- if( xTimerPeriodInTicks == ( TickType_t ) 0U )\r
- {\r
- pxNewTimer = NULL;\r
- }\r
- else\r
- {\r
- /* If the user passed in a statically allocated timer structure then use\r
- it, otherwise allocate the structure dynamically. */\r
- if( pxTimerBuffer == NULL )\r
- {\r
- pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );\r
- }\r
- else\r
- {\r
- pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */\r
- }\r
+ pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );\r
\r
if( pxNewTimer != NULL )\r
{\r
- /* Ensure the infrastructure used by the timer service task has been\r
- created/initialised. */\r
- prvCheckForValidListAndQueue();\r
-\r
- /* Initialise the timer structure members using the function\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
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
\r
#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
{\r
- if( pxTimerBuffer == NULL )\r
- {\r
- pxNewTimer->ucStaticallyAllocated = pdFALSE;\r
- }\r
- else\r
- {\r
- pxNewTimer->ucStaticallyAllocated = pdTRUE;\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
- traceTIMER_CREATE( pxNewTimer );\r
+#endif /* configSUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+\r
+ TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ {\r
+ Timer_t *pxNewTimer;\r
+\r
+ #if( configASSERT_DEFINED == 1 )\r
+ {\r
+ /* Sanity check that the size of the structure used to declare a\r
+ variable of type StaticTimer_t equals the size of the real timer\r
+ structures. */\r
+ volatile size_t xSize = sizeof( StaticTimer_t );\r
+ configASSERT( xSize == sizeof( Timer_t ) );\r
}\r
- else\r
+ #endif /* configASSERT_DEFINED */\r
+\r
+ /* A pointer to a StaticTimer_t structure MUST be provided, use it. */\r
+ configASSERT( pxTimerBuffer );\r
+ pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */\r
+\r
+ if( pxNewTimer != NULL )\r
{\r
- traceTIMER_CREATE_FAILED();\r
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\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
}\r
+\r
+ return pxNewTimer;\r
}\r
\r
+#endif /* configSUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitialiseNewTimer( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+{\r
/* 0 is not a valid value for xTimerPeriodInTicks. */\r
configASSERT( ( xTimerPeriodInTicks > 0 ) );\r
\r
- return ( TimerHandle_t ) pxNewTimer;\r
+ if( pxNewTimer != NULL )\r
+ {\r
+ /* Ensure the infrastructure used by the timer service task has been\r
+ created/initialised. */\r
+ prvCheckForValidListAndQueue();\r
+\r
+ /* Initialise the timer structure members using the function\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
+ traceTIMER_CREATE( pxNewTimer );\r
+ }\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )\r
+{\r
+ /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been\r
+ started, then xTimerTaskHandle will be NULL. */\r
+ configASSERT( ( xTimerTaskHandle != NULL ) );\r
+ return xTimerTaskHandle;\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )\r
- {\r
- /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been\r
- started, then xTimerTaskHandle will be NULL. */\r
- configASSERT( ( xTimerTaskHandle != NULL ) );\r
- return xTimerTaskHandle;\r
- }\r
+TickType_t xTimerGetPeriod( TimerHandle_t xTimer )\r
+{\r
+Timer_t *pxTimer = ( Timer_t * ) xTimer;\r
\r
-#endif\r
+ configASSERT( xTimer );\r
+ return pxTimer->xTimerPeriodInTicks;\r
+}\r
/*-----------------------------------------------------------*/\r
\r
-const char * pcTimerGetTimerName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )\r
+{\r
+Timer_t * pxTimer = ( Timer_t * ) xTimer;\r
+TickType_t xReturn;\r
+\r
+ configASSERT( xTimer );\r
+ xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
{\r
Timer_t *pxTimer = ( Timer_t * ) xTimer;\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
correct list relative to the time this task thinks it is now. */\r
- if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )\r
+ if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE )\r
{\r
/* The timer expired before it was added to the active timer\r
list. Reload it now. */\r
{\r
/* Has the expiry time elapsed between the command to start/reset a\r
timer was issued, and the time the command was processed? */\r
- if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )\r
+ if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */\r
{\r
/* The time between a command being issued and the command being\r
processed actually exceeds the timers period. */\r
case tmrCOMMAND_RESET_FROM_ISR :\r
case tmrCOMMAND_START_DONT_TRACE :\r
/* Start or restart a timer. */\r
- if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE )\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
timer list. Process it now. */\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_STATIC_ALLOCATION == 1 )\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
{\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
{\r
vPortFree( pxTimer );\r
mtCOVERAGE_TEST_MARKER();\r
}\r
}\r
- #else\r
- {\r
- vPortFree( pxTimer );\r
- }\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
break;\r
\r
default :\r
vListInitialise( &xActiveTimerList2 );\r
pxCurrentTimerList = &xActiveTimerList1;\r
pxOverflowTimerList = &xActiveTimerList2;\r
- xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );\r
- configASSERT( xTimerQueue );\r
+\r
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+ {\r
+ /* The timer queue is allocated statically in case\r
+ configSUPPORT_DYNAMIC_ALLOCATION is 0. */\r
+ static StaticQueue_t xStaticTimerQueue;\r
+ static uint8_t ucStaticTimerQueueStorage[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ];\r
+\r
+ xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue );\r
+ }\r
+ #else\r
+ {\r
+ xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) );\r
+ }\r
+ #endif\r
\r
#if ( configQUEUE_REGISTRY_SIZE > 0 )\r
{\r