/*\r
- FreeRTOS V7.6.0 - Copyright (C) 2013 Real Time Engineers Ltd.\r
- All rights reserved\r
-\r
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that has become a de facto standard. *\r
- * *\r
- * Help yourself get started quickly and support the FreeRTOS *\r
- * project by purchasing a FreeRTOS tutorial book, reference *\r
- * manual, or both from: http://www.FreeRTOS.org/Documentation *\r
- * *\r
- * Thank you! *\r
- * *\r
- ***************************************************************************\r
-\r
- This file is part of the FreeRTOS distribution.\r
-\r
- FreeRTOS is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License (version 2) as published by the\r
- Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
- >>! NOTE: The modification to the GPL is included to allow you to distribute\r
- >>! a combined work that includes FreeRTOS without being obliged to provide\r
- >>! the source code for proprietary components outside of the FreeRTOS\r
- >>! kernel.\r
-\r
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. Full license text is available from the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- 1 tab == 4 spaces!\r
-\r
- ***************************************************************************\r
- * *\r
- * Having a problem? Start by reading the FAQ "My application does *\r
- * not run, what could be wrong?" *\r
- * *\r
- * http://www.FreeRTOS.org/FAQHelp.html *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
- license and Real Time Engineers Ltd. contact details.\r
-\r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
- compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
- Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and middleware.\r
-\r
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
- engineered and independently SIL3 certified version for use in safety and\r
- mission critical applications that require provable dependability.\r
-\r
- 1 tab == 4 spaces!\r
-*/\r
+ * FreeRTOS Kernel V10.1.1\r
+ * Copyright (C) 2018 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
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ */\r
\r
/* Standard includes. */\r
#include <stdlib.h>\r
#include "queue.h"\r
#include "timers.h"\r
\r
-#if ( INCLUDE_xTimerPendCallbackFromISR == 1 ) && ( configUSE_TIMERS == 0 )\r
- #error configUSE_TIMERS must be set to 1 to make the INCLUDE_xTimerPendCallbackFromISR() function available.\r
+#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 )\r
+ #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available.\r
#endif\r
\r
-/* Lint e961 and e750 are suppressed as a MISRA exception justified because the\r
-MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the\r
-header files above, but not in this file, in order to generate the correct\r
-privileged Vs unprivileged linkage and placement. */\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */\r
+/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified\r
+because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined\r
+for the header files above, but not in this file, in order to generate the\r
+correct privileged Vs unprivileged linkage and placement. */\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */\r
\r
\r
/* This entire source file will be skipped if the application is not configured\r
#if ( configUSE_TIMERS == 1 )\r
\r
/* Misc definitions. */\r
-#define tmrNO_DELAY ( portTickType ) 0U\r
+#define tmrNO_DELAY ( TickType_t ) 0U\r
+\r
+/* The name assigned to the timer service task. This can be overridden by\r
+defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */\r
+#ifndef configTIMER_SERVICE_TASK_NAME\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 tmrTimerControl\r
+typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */\r
{\r
- const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */\r
- xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */\r
- portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */\r
- unsigned portBASE_TYPE 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
+ 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
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
- tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */\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
+ 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
+name below to enable the use of older kernel aware debuggers. */\r
+typedef xTIMER Timer_t;\r
+\r
/* The definition of messages that can be sent and received on the timer queue.\r
Two types of message can be queued - messages that manipulate a software timer,\r
and messages that request the execution of a non-timer related callback. The\r
and xCallbackParametersType respectively. */\r
typedef struct tmrTimerParameters\r
{\r
- portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */\r
- xTIMER * pxTimer; /*<< The timer to which the command will be applied. */\r
-} xTimerParametersType;\r
+ TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */\r
+ Timer_t * pxTimer; /*<< The timer to which the command will be applied. */\r
+} TimerParameter_t;\r
\r
\r
typedef struct tmrCallbackParameters\r
{\r
- pdAPPLICATION_CALLBACK_CODE pxCallbackFunction; /* << The callback function to execute. */\r
- void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */\r
- unsigned long ulParameter2; /* << The value that will be used as the callback functions second parameter. */\r
-} xCallbackParametersType;\r
+ PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */\r
+ void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */\r
+ uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */\r
+} CallbackParameters_t;\r
\r
/* The structure that contains the two message types, along with an identifier\r
that is used to determine which message type is valid. */\r
typedef struct tmrTimerQueueMessage\r
{\r
- portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */\r
+ BaseType_t xMessageID; /*<< The command being sent to the timer service task. */\r
union\r
{\r
- xTimerParametersType xTimerParameters;\r
+ TimerParameter_t xTimerParameters;\r
\r
/* Don't include xCallbackParameters if it is not going to be used as\r
it makes the structure (and therefore the timer queue) larger. */\r
- #if ( INCLUDE_xTimerPendCallbackFromISR == 1 )\r
- xCallbackParametersType xCallbackParameters;\r
- #endif /* INCLUDE_xTimerPendCallbackFromISR */\r
+ #if ( INCLUDE_xTimerPendFunctionCall == 1 )\r
+ CallbackParameters_t xCallbackParameters;\r
+ #endif /* INCLUDE_xTimerPendFunctionCall */\r
} u;\r
-} xDAEMON_TASK_MESSAGE;\r
+} DaemonTaskMessage_t;\r
\r
-/*lint -e956 A manual analysis and inspection has been used to determine which\r
-static variables must be declared volatile. */\r
+/*lint -save -e956 A manual analysis and inspection has been used to determine\r
+which static variables must be declared volatile. */\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
-PRIVILEGED_DATA static xList xActiveTimerList1;\r
-PRIVILEGED_DATA static xList xActiveTimerList2;\r
-PRIVILEGED_DATA static xList *pxCurrentTimerList;\r
-PRIVILEGED_DATA static xList *pxOverflowTimerList;\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
/* A queue that is used to send commands to the timer service task. */\r
-PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;\r
+PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;\r
+PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;\r
\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+/*lint -restore */\r
\r
- PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;\r
+/*-----------------------------------------------------------*/\r
\r
-#endif\r
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
\r
-/*lint +e956 */\r
+ /* If static allocation is supported then the application must provide the\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( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );\r
\r
-/*-----------------------------------------------------------*/\r
+#endif\r
\r
/*\r
* Initialise the infrastructure used by the timer service task if it has not\r
* Called by the timer service task to interpret and process a command it\r
* received on the timer queue.\r
*/\r
-static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;\r
+static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2,\r
* depending on if the expire time causes a timer counter overflow.\r
*/\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;\r
+static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION;\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
*/\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;\r
+static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* The tick count has overflowed. Switch the timer lists after ensuring the\r
* current timer list does not still reference some timers.\r
*/\r
-static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;\r
+static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE\r
* if a tick count overflow occurred since prvSampleTimeNow() was last called.\r
*/\r
-static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;\r
+static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* If the timer list contains any active timers then return the expire time of\r
* timer list does not contain any timers then return 0 and set *pxListWasEmpty\r
* to pdTRUE.\r
*/\r
-static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;\r
+static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* If a timer has expired, process it. Otherwise, block the timer service task\r
* until either a timer does expire or a command is received.\r
*/\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;\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, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const TickType_t xTimerPeriodInTicks,\r
+ const UBaseType_t uxAutoReload,\r
+ void * const pvTimerID,\r
+ TimerCallbackFunction_t pxCallbackFunction,\r
+ Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION;\r
/*-----------------------------------------------------------*/\r
\r
-portBASE_TYPE xTimerCreateTimerTask( void )\r
+BaseType_t xTimerCreateTimerTask( void )\r
{\r
-portBASE_TYPE xReturn = pdFAIL;\r
+BaseType_t xReturn = pdFAIL;\r
\r
/* This function is called when the scheduler is started if\r
configUSE_TIMERS is set to 1. Check that the infrastructure used by the\r
\r
if( xTimerQueue != NULL )\r
{\r
- #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
{\r
- /* Create the timer task, storing its handle in xTimerTaskHandle so\r
- it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */\r
- xReturn = xTaskCreate( prvTimerTask, ( signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );\r
+ StaticTask_t *pxTimerTaskTCBBuffer = NULL;\r
+ StackType_t *pxTimerTaskStackBuffer = NULL;\r
+ uint32_t ulTimerTaskStackSize;\r
+\r
+ vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize );\r
+ xTimerTaskHandle = xTaskCreateStatic( prvTimerTask,\r
+ configTIMER_SERVICE_TASK_NAME,\r
+ ulTimerTaskStackSize,\r
+ NULL,\r
+ ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,\r
+ pxTimerTaskStackBuffer,\r
+ pxTimerTaskTCBBuffer );\r
+\r
+ if( xTimerTaskHandle != NULL )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
}\r
#else\r
{\r
- /* Create the timer task without storing its handle. */\r
- xReturn = xTaskCreate( prvTimerTask, ( signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);\r
+ xReturn = xTaskCreate( prvTimerTask,\r
+ configTIMER_SERVICE_TASK_NAME,\r
+ configTIMER_TASK_STACK_DEPTH,\r
+ NULL,\r
+ ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT,\r
+ &xTimerTaskHandle );\r
}\r
- #endif\r
+ #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
}\r
\r
configASSERT( xReturn );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )\r
-{\r
-xTIMER *pxNewTimer;\r
+#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
\r
- /* Allocate the timer structure. */\r
- if( xTimerPeriodInTicks == ( portTickType ) 0U )\r
+ TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const TickType_t xTimerPeriodInTicks,\r
+ const UBaseType_t uxAutoReload,\r
+ void * const pvTimerID,\r
+ TimerCallbackFunction_t pxCallbackFunction )\r
{\r
- pxNewTimer = NULL;\r
+ Timer_t *pxNewTimer;\r
+\r
+ pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */\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 autoreload bit may get set in\r
+ prvInitialiseNewTimer. */\r
+ pxNewTimer->ucStatus = 0x00;\r
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
+ }\r
+\r
+ return pxNewTimer;\r
}\r
- else\r
+\r
+#endif /* configSUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+\r
+ TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const TickType_t xTimerPeriodInTicks,\r
+ const UBaseType_t uxAutoReload,\r
+ void * const pvTimerID,\r
+ TimerCallbackFunction_t pxCallbackFunction,\r
+ StaticTimer_t *pxTimerBuffer )\r
{\r
- pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );\r
- if( pxNewTimer != NULL )\r
+ Timer_t *pxNewTimer;\r
+\r
+ #if( configASSERT_DEFINED == 1 )\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
- pxNewTimer->pcTimerName = pcTimerName;\r
- pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
- pxNewTimer->uxAutoReload = uxAutoReload;\r
- pxNewTimer->pvTimerID = pvTimerID;\r
- pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
- vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
-\r
- traceTIMER_CREATE( pxNewTimer );\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
+ structure. */\r
+ volatile size_t xSize = sizeof( StaticTimer_t );\r
+ configASSERT( xSize == sizeof( Timer_t ) );\r
+ ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */\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 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */\r
+\r
+ if( pxNewTimer != NULL )\r
{\r
- traceTIMER_CREATE_FAILED();\r
+ /* Timers can be created statically or dynamically so note this\r
+ timer was created statically in case it is later deleted. The\r
+ autoreload bit may get set in prvInitialiseNewTimer(). */\r
+ pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;\r
+\r
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
}\r
+\r
+ return pxNewTimer;\r
}\r
\r
+#endif /* configSUPPORT_STATIC_ALLOCATION */\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
+ const TickType_t xTimerPeriodInTicks,\r
+ const UBaseType_t uxAutoReload,\r
+ void * const pvTimerID,\r
+ TimerCallbackFunction_t pxCallbackFunction,\r
+ Timer_t *pxNewTimer )\r
+{\r
/* 0 is not a valid value for xTimerPeriodInTicks. */\r
configASSERT( ( xTimerPeriodInTicks > 0 ) );\r
\r
- return ( xTimerHandle ) 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->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
-portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )\r
+BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait )\r
{\r
-portBASE_TYPE xReturn = pdFAIL;\r
-xDAEMON_TASK_MESSAGE xMessage;\r
+BaseType_t xReturn = pdFAIL;\r
+DaemonTaskMessage_t xMessage;\r
+\r
+ configASSERT( xTimer );\r
\r
/* Send a message to the timer service task to perform a particular action\r
on a particular timer definition. */\r
/* Send a command to the timer service task to start the xTimer timer. */\r
xMessage.xMessageID = xCommandID;\r
xMessage.u.xTimerParameters.xMessageValue = xOptionalValue;\r
- xMessage.u.xTimerParameters.pxTimer = ( xTIMER * ) xTimer;\r
+ xMessage.u.xTimerParameters.pxTimer = xTimer;\r
\r
- if( pxHigherPriorityTaskWoken == NULL )\r
+ if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )\r
{\r
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )\r
{\r
- xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );\r
}\r
else\r
{\r
\r
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
\r
return xReturn;\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
- xTaskHandle 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 = xTimer;\r
\r
-#endif\r
+ configASSERT( xTimer );\r
+ return pxTimer->xTimerPeriodInTicks;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )\r
+{\r
+Timer_t * pxTimer = xTimer;\r
+TickType_t xReturn;\r
+\r
+ configASSERT( xTimer );\r
+ xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );\r
+ return xReturn;\r
+}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )\r
+const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\r
{\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xResult;\r
+Timer_t *pxTimer = xTimer;\r
+\r
+ configASSERT( xTimer );\r
+ return pxTimer->pcTimerName;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow )\r
+{\r
+BaseType_t xResult;\r
+Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */\r
\r
/* Remove the timer from the list of active timers. A check has already\r
been performed to ensure the list is not empty. */\r
- pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
traceTIMER_EXPIRED( pxTimer );\r
\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 == ( unsigned portBASE_TYPE ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
- /* This is the only time a timer is inserted into a list using\r
- a time relative to anything other than the current time. It\r
- will therefore be inserted into the correct list relative to\r
- the time this task thinks it is now, even if a command to\r
- switch lists due to a tick count overflow is already waiting in\r
- the timer queue. */\r
- if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )\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 ) != pdFALSE )\r
{\r
/* The timer expired before it was added to the active timer\r
list. Reload it now. */\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );\r
configASSERT( xResult );\r
( void ) xResult;\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
+ mtCOVERAGE_TEST_MARKER();\r
}\r
\r
/* Call the timer callback. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
}\r
/*-----------------------------------------------------------*/\r
\r
static void prvTimerTask( void *pvParameters )\r
{\r
-portTickType xNextExpireTime;\r
-portBASE_TYPE xListWasEmpty;\r
+TickType_t xNextExpireTime;\r
+BaseType_t xListWasEmpty;\r
\r
/* Just to avoid compiler warnings. */\r
( void ) pvParameters;\r
\r
+ #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 )\r
+ {\r
+ extern void vApplicationDaemonTaskStartupHook( void );\r
+\r
+ /* Allow the application writer to execute some code in the context of\r
+ this task at the point the task starts executing. This is useful if the\r
+ application includes initialisation code that would benefit from\r
+ executing after the scheduler has been started. */\r
+ vApplicationDaemonTaskStartupHook();\r
+ }\r
+ #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */\r
+\r
for( ;; )\r
{\r
/* Query the timers list to see if it contains any timers, and if so,\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )\r
+static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty )\r
{\r
-portTickType xTimeNow;\r
-portBASE_TYPE xTimerListsWereSwitched;\r
+TickType_t xTimeNow;\r
+BaseType_t xTimerListsWereSwitched;\r
\r
vTaskSuspendAll();\r
{\r
received - whichever comes first. The following line cannot\r
be reached unless xNextExpireTime > xTimeNow, except in the\r
case when the current timer list is empty. */\r
- vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );\r
+ if( xListWasEmpty != pdFALSE )\r
+ {\r
+ /* The current timer list is empty - is the overflow list\r
+ also empty? */\r
+ xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList );\r
+ }\r
+\r
+ vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty );\r
\r
if( xTaskResumeAll() == pdFALSE )\r
{\r
- /* Yield to wait for either a command to arrive, or the block time\r
- to expire. If a command arrived between the critical section being\r
- exited and this yield then the yield will not cause the task\r
- to block. */\r
+ /* Yield to wait for either a command to arrive, or the\r
+ block time to expire. If a command arrived between the\r
+ critical section being exited and this yield then the yield\r
+ will not cause the task to block. */\r
portYIELD_WITHIN_API();\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
}\r
}\r
else\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )\r
+static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty )\r
{\r
-portTickType xNextExpireTime;\r
+TickType_t xNextExpireTime;\r
\r
/* Timers are listed in expiry time order, with the head of the list\r
referencing the task that will expire first. Obtain the time at which\r
else\r
{\r
/* Ensure the task unblocks when the tick count rolls over. */\r
- xNextExpireTime = ( portTickType ) 0U;\r
+ xNextExpireTime = ( TickType_t ) 0U;\r
}\r
\r
return xNextExpireTime;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )\r
+static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched )\r
{\r
-portTickType xTimeNow;\r
-PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; /*lint !e956 Variable is only accessible to one task. */\r
+TickType_t xTimeNow;\r
+PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */\r
\r
xTimeNow = xTaskGetTickCount();\r
\r
if( xTimeNow < xLastTime )\r
{\r
- prvSwitchTimerLists( xLastTime );\r
+ prvSwitchTimerLists();\r
*pxTimerListsWereSwitched = pdTRUE;\r
}\r
else\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )\r
+static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime )\r
{\r
-portBASE_TYPE xProcessTimerNow = pdFALSE;\r
+BaseType_t xProcessTimerNow = pdFALSE;\r
\r
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );\r
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\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
\r
static void prvProcessReceivedCommands( void )\r
{\r
-xDAEMON_TASK_MESSAGE xMessage;\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xTimerListsWereSwitched, xResult;\r
-portTickType xTimeNow;\r
+DaemonTaskMessage_t xMessage;\r
+Timer_t *pxTimer;\r
+BaseType_t xTimerListsWereSwitched, xResult;\r
+TickType_t xTimeNow;\r
\r
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */\r
{\r
- #if ( INCLUDE_xTimerPendCallbackFromISR == 1 )\r
+ #if ( INCLUDE_xTimerPendFunctionCall == 1 )\r
{\r
- if( xMessage.xMessageID == tmrCOMMAND_EXECUTE_CALLBACK )\r
+ /* Negative commands are pended function calls rather than timer\r
+ commands. */\r
+ if( xMessage.xMessageID < ( BaseType_t ) 0 )\r
{\r
- const xCallbackParametersType * const pxCallback = &( xMessage.u.xCallbackParameters );\r
+ const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters );\r
\r
/* The timer uses the xCallbackParameters member to request a\r
callback be executed. Check the callback is not NULL. */\r
/* Call the function. */\r
pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 );\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
}\r
- #endif /* INCLUDE_xTimerPendCallbackFromISR */\r
+ #endif /* INCLUDE_xTimerPendFunctionCall */\r
\r
- if( xMessage.xMessageID != tmrCOMMAND_EXECUTE_CALLBACK )\r
+ /* Commands that are positive are timer commands rather than pended\r
+ function calls. */\r
+ if( xMessage.xMessageID >= ( BaseType_t ) 0 )\r
{\r
/* The messages uses the xTimerParameters member to work on a\r
software timer. */\r
pxTimer = xMessage.u.xTimerParameters.pxTimer;\r
\r
- if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )\r
+ if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */\r
{\r
/* The timer is in a list, remove it. */\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
\r
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue );\r
\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_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
+ 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 timer\r
- list. Process it now. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+ /* The timer expired before it was added to the active\r
+ timer list. Process it now. */\r
+ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
+ traceTIMER_EXPIRED( pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
configASSERT( xResult );\r
( void ) xResult;\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
}\r
break;\r
\r
case tmrCOMMAND_STOP :\r
- /* The timer has already been removed from the active list.\r
- There is nothing to do here. */\r
+ case tmrCOMMAND_STOP_FROM_ISR :\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
- /* 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->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )\r
+ {\r
+ vPortFree( pxTimer );\r
+ }\r
+ else\r
+ {\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
+ }\r
break;\r
\r
default :\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvSwitchTimerLists( portTickType xLastTime )\r
+static void prvSwitchTimerLists( void )\r
{\r
-portTickType xNextExpireTime, xReloadTime;\r
-xList *pxTemp;\r
-xTIMER *pxTimer;\r
-portBASE_TYPE xResult;\r
-\r
- /* Remove compiler warnings if configASSERT() is not defined. */\r
- ( void ) xLastTime;\r
+TickType_t xNextExpireTime, xReloadTime;\r
+List_t *pxTemp;\r
+Timer_t *pxTimer;\r
+BaseType_t xResult;\r
\r
/* The tick count has overflowed. The timer lists must be switched.\r
If there are any timers still referenced from the current timer list\r
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
\r
/* Remove the timer from the list. */\r
- pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
+ pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */\r
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
+ traceTIMER_EXPIRED( pxTimer );\r
\r
/* Execute its callback, then send a command to restart the timer if\r
it is an auto-reload timer. It cannot be restarted here as the lists\r
have not yet been switched. */\r
- pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+ pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) 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
else\r
{\r
- xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );\r
+ xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY );\r
configASSERT( xResult );\r
( void ) xResult;\r
}\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
}\r
\r
pxTemp = pxCurrentTimerList;\r
vListInitialise( &xActiveTimerList2 );\r
pxCurrentTimerList = &xActiveTimerList1;\r
pxOverflowTimerList = &xActiveTimerList2;\r
- xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xDAEMON_TASK_MESSAGE ) );\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; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */\r
+ static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */\r
+\r
+ xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) 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
if( xTimerQueue != NULL )\r
{\r
- vQueueAddToRegistry( xTimerQueue, ( signed char * ) "TmrQ" );\r
+ vQueueAddToRegistry( xTimerQueue, "TmrQ" );\r
+ }\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
}\r
}\r
#endif /* configQUEUE_REGISTRY_SIZE */\r
}\r
+ else\r
+ {\r
+ mtCOVERAGE_TEST_MARKER();\r
+ }\r
}\r
taskEXIT_CRITICAL();\r
}\r
/*-----------------------------------------------------------*/\r
\r
-portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )\r
+BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )\r
{\r
-portBASE_TYPE xTimerIsInActiveList;\r
-xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+BaseType_t xReturn;\r
+Timer_t *pxTimer = xTimer;\r
+\r
+ configASSERT( xTimer );\r
\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
- xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 )\r
+ {\r
+ xReturn = pdFALSE;\r
+ }\r
+ else\r
+ {\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
+void *pvTimerGetTimerID( const TimerHandle_t xTimer )\r
+{\r
+Timer_t * const pxTimer = xTimer;\r
+void *pvReturn;\r
+\r
+ configASSERT( xTimer );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pvReturn = pxTimer->pvTimerID;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return pvReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void *pvTimerGetTimerID( xTimerHandle xTimer )\r
+void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )\r
{\r
-xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+Timer_t * const pxTimer = xTimer;\r
+\r
+ configASSERT( xTimer );\r
\r
- return pxTimer->pvTimerID;\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pxTimer->pvTimerID = pvNewID;\r
+ }\r
+ taskEXIT_CRITICAL();\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#if( INCLUDE_xTimerPendCallbackFromISR == 1 )\r
+#if( INCLUDE_xTimerPendFunctionCall == 1 )\r
\r
- portBASE_TYPE xTimerPendCallbackFromISR( pdAPPLICATION_CALLBACK_CODE pvCallbackFunction, void *pvParameter1, unsigned long ulParameter2, portBASE_TYPE *pxHigherPriorityTaskWoken )\r
+ BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )\r
{\r
- xDAEMON_TASK_MESSAGE xMessage;\r
- portBASE_TYPE xReturn;\r
+ DaemonTaskMessage_t xMessage;\r
+ BaseType_t xReturn;\r
\r
/* Complete the message with the function parameters and post it to the\r
daemon task. */\r
- xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;\r
- xMessage.u.xCallbackParameters.pxCallbackFunction = pvCallbackFunction;\r
+ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;\r
+ xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;\r
xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;\r
xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;\r
\r
xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );\r
\r
+ tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn );\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif /* INCLUDE_xTimerPendFunctionCall */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( INCLUDE_xTimerPendFunctionCall == 1 )\r
+\r
+ BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait )\r
+ {\r
+ DaemonTaskMessage_t xMessage;\r
+ BaseType_t xReturn;\r
+\r
+ /* This function can only be called after a timer has been created or\r
+ after the scheduler has been started because, until then, the timer\r
+ queue does not exist. */\r
+ configASSERT( xTimerQueue );\r
+\r
+ /* Complete the message with the function parameters and post it to the\r
+ daemon task. */\r
+ xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK;\r
+ xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;\r
+ xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;\r
+ xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;\r
+\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait );\r
+\r
+ tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn );\r
+\r
return xReturn;\r
}\r
\r
-#endif /* INCLUDE_xTimerPendCallbackFromISR */\r
+#endif /* INCLUDE_xTimerPendFunctionCall */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer )\r
+ {\r
+ return ( ( Timer_t * ) xTimer )->uxTimerNumber;\r
+ }\r
+\r
+#endif /* configUSE_TRACE_FACILITY */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber )\r
+ {\r
+ ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber;\r
+ }\r
+\r
+#endif /* configUSE_TRACE_FACILITY */\r
/*-----------------------------------------------------------*/\r
\r
/* This entire source file will be skipped if the application is not configured\r