#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
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
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
}\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
}\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
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
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