]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/timers.c
Provide the ability to create event groups and software timers using pre statically...
[freertos] / FreeRTOS / Source / timers.c
index 11681723df47b73ad448fdbbfd419ece155f792e..904189dc2316934cf8b1501800538fbf73c407c2 100644 (file)
@@ -112,6 +112,10 @@ typedef struct tmrTimerControl
        #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 )\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
+       #endif\r
 } xTIMER;\r
 \r
 /* The old xTIMER name is maintained above then typedefed to the new Timer_t\r
@@ -184,7 +188,7 @@ PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;
        following callback function - which enables the application to optionally\r
        provide the memory that will be used by the timer task as the task's stack\r
        and TCB. */\r
-       extern void vApplicationGetTimerTaskMemory( StaticTCB_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );\r
+       extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize );\r
 \r
 #endif\r
 \r
@@ -250,7 +254,7 @@ static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseTy
 BaseType_t xTimerCreateTimerTask( void )\r
 {\r
 BaseType_t xReturn = pdFAIL;\r
-StaticTCB_t *pxTimerTaskTCBBuffer = NULL;\r
+StaticTask_t *pxTimerTaskTCBBuffer = NULL;\r
 StackType_t *pxTimerTaskStackBuffer = NULL;\r
 uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;\r
 \r
@@ -294,10 +298,20 @@ uint16_t usTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
 }\r
 /*-----------------------------------------------------------*/\r
 \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
+TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxStaticTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
 {\r
 Timer_t *pxNewTimer;\r
 \r
+       #if( ( configASSERT_DEFINED == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 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
+       #endif /* configASSERT_DEFINED */\r
+\r
        /* Allocate the timer structure. */\r
        if( xTimerPeriodInTicks == ( TickType_t ) 0U )\r
        {\r
@@ -305,14 +319,25 @@ Timer_t *pxNewTimer;
        }\r
        else\r
        {\r
-               pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );\r
+               /* If the user passed in a statically allocated timer structure then use\r
+               it, otherwise allocate the structure dynamically. */\r
+               if( pxStaticTimer == NULL )\r
+               {\r
+                       pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );\r
+               }\r
+               else\r
+               {\r
+                       pxNewTimer = ( Timer_t * ) pxStaticTimer;\r
+               }\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 parameters. */\r
+                       /* Initialise the timer structure members using the function\r
+                       parameters. */\r
                        pxNewTimer->pcTimerName = pcTimerName;\r
                        pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
                        pxNewTimer->uxAutoReload = uxAutoReload;\r
@@ -320,6 +345,15 @@ Timer_t *pxNewTimer;
                        pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
                        vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
 \r
+                       if( pxStaticTimer == NULL )\r
+                       {\r
+                               pxNewTimer->ucStaticallyAllocated = pdFALSE;\r
+                       }\r
+                       else\r
+                       {\r
+                               pxNewTimer->ucStaticallyAllocated = pdTRUE;\r
+                       }\r
+\r
                        traceTIMER_CREATE( pxNewTimer );\r
                }\r
                else\r
@@ -716,19 +750,27 @@ TickType_t xTimeNow;
                                        pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue;\r
                                        configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
 \r
-                                       /* The new period does not really have a reference, and can be\r
-                                       longer or shorter than the old one.  The command time is\r
-                                       therefore set to the current time, and as the period cannot be\r
-                                       zero the next expiry time can only be in the future, meaning\r
-                                       (unlike for the xTimerStart() case above) there is no fail case\r
-                                       that needs to be handled here. */\r
+                                       /* The new period does not really have a reference, and can\r
+                                       be longer or shorter than the old one.  The command time is\r
+                                       therefore set to the current time, and as the period cannot\r
+                                       be zero the next expiry time can only be in the future,\r
+                                       meaning (unlike for the xTimerStart() case above) there is\r
+                                       no fail case that needs to be handled here. */\r
                                        ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );\r
                                        break;\r
 \r
                                case tmrCOMMAND_DELETE :\r
                                        /* The timer has already been removed from the active list,\r
-                                       just free up the memory. */\r
-                                       vPortFree( pxTimer );\r
+                                       just free up the memory if the memory was dynamically\r
+                                       allocated. */\r
+                                       if( pxTimer->ucStaticallyAllocated == pdFALSE )\r
+                                       {\r
+                                               vPortFree( pxTimer );\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               mtCOVERAGE_TEST_MARKER();\r
+                                       }\r
                                        break;\r
 \r
                                default :\r