]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/timers.c
Update version number to 9.0.0rc2.
[freertos] / FreeRTOS / Source / timers.c
index 25d8167156a6a3e1652f1a6be3508181a21ee303..907ac6696694610c6981139f390c000b569be5ad 100644 (file)
@@ -1,5 +1,5 @@
 /*\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
@@ -113,8 +113,8 @@ typedef struct tmrTimerControl
                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
@@ -171,12 +171,7 @@ PRIVILEGED_DATA static List_t *pxOverflowTimerList;
 \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
@@ -249,13 +244,16 @@ static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIV
  */\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
@@ -270,22 +268,17 @@ uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
 \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
@@ -297,78 +290,94 @@ uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
 }\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
@@ -415,20 +424,36 @@ DaemonTaskMessage_t xMessage;
 }\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
@@ -454,7 +479,7 @@ Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTi
                /* 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
@@ -633,7 +658,7 @@ BaseType_t xProcessTimerNow = pdFALSE;
        {\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
@@ -730,7 +755,7 @@ TickType_t xTimeNow;
                            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
@@ -778,8 +803,17 @@ TickType_t xTimeNow;
                                        /* 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
@@ -789,11 +823,7 @@ TickType_t xTimeNow;
                                                        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
@@ -877,8 +907,21 @@ static void prvCheckForValidListAndQueue( void )
                        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