/*\r
- FreeRTOS V8.2.3 - Copyright (C) 2015 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
- 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
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\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 on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\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.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial 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.2.1\r
+ * Copyright (C) 2019 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
#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
/* Misc definitions. */\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 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
- UBaseType_t 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
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
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
-\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
+ 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
} u;\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
+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
\r
/* A queue that is used to send commands to the timer service task. */\r
PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL;\r
+PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;\r
\r
-#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
-\r
- PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL;\r
-\r
-#endif\r
-\r
-/*lint +e956 */\r
+/*lint -restore */\r
\r
/*-----------------------------------------------------------*/\r
\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, uint16_t *pusTimerTaskStackSize );\r
+ extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );\r
\r
#endif\r
\r
* task. Other tasks communicate with the timer service task using the\r
* xTimerQueue queue.\r
*/\r
-static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;\r
+static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Called by the timer service task to interpret and process a command it\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
+ * auto-reload timer, then call its callback.\r
*/\r
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION;\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, /*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
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
/* 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
-\r
#if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
{\r
- vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &usTimerTaskStackSize );\r
- }\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\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
+ 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 = xTaskGenericCreate( prvTimerTask, "Tmr Svc", usTimerTaskStackSize, NULL, ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL, pxTimerTaskStackBuffer, pxTimerTaskTCBBuffer, 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
}\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, /*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
- /* 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
+ 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
- pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) );\r
+ /* Status is thus far zero as the timer is not created statically\r
+ and has not been started. The auto-reload bit may get set in\r
+ prvInitialiseNewTimer. */\r
+ pxNewTimer->ucStatus = 0x00;\r
+ prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer );\r
}\r
- else\r
+\r
+ return pxNewTimer;\r
+ }\r
+\r
+#endif /* configSUPPORT_DYNAMIC_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
+ Timer_t *pxNewTimer;\r
+\r
+ #if( configASSERT_DEFINED == 1 )\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
+ /* 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
+ #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
- /* 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
-\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
- }\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+ /* Timers can be created statically or dynamically so note this\r
+ timer was created statically in case it is later deleted. The\r
+ auto-reload bit may get set in prvInitialiseNewTimer(). */\r
+ pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED;\r
\r
- traceTIMER_CREATE( pxNewTimer );\r
- }\r
- else\r
- {\r
- traceTIMER_CREATE_FAILED();\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 ( 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->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
/* 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 = ( Timer_t * ) xTimer;\r
+ xMessage.u.xTimerParameters.pxTimer = xTimer;\r
\r
if( xCommandID < tmrFIRST_FROM_ISR_COMMAND )\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
+TickType_t xTimerGetPeriod( TimerHandle_t xTimer )\r
+{\r
+Timer_t *pxTimer = xTimer;\r
\r
- TaskHandle_t xTimerGetTimerDaemonTaskHandle( void )\r
+ configASSERT( xTimer );\r
+ return pxTimer->xTimerPeriodInTicks;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload )\r
+{\r
+Timer_t * pxTimer = xTimer;\r
+\r
+ configASSERT( xTimer );\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( uxAutoReload != pdFALSE )\r
+ {\r
+ pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD;\r
+ }\r
+ else\r
+ {\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD;\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+UBaseType_t uxTimerGetReloadMode( TimerHandle_t xTimer )\r
+{\r
+Timer_t * pxTimer = xTimer;\r
+UBaseType_t uxReturn;\r
+\r
+ configASSERT( xTimer );\r
+ taskENTER_CRITICAL();\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
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) == 0 )\r
+ {\r
+ /* Not an auto-reload timer. */\r
+ uxReturn = ( UBaseType_t ) pdFALSE;\r
+ }\r
+ else\r
+ {\r
+ /* Is an auto-reload timer. */\r
+ uxReturn = ( UBaseType_t ) pdTRUE;\r
+ }\r
}\r
+ taskEXIT_CRITICAL();\r
\r
-#endif\r
+ return uxReturn;\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
-const char * pcTimerGetTimerName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */\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
+Timer_t *pxTimer = xTimer;\r
\r
configASSERT( xTimer );\r
return pxTimer->pcTimerName;\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 );\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
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
- /* If the timer is an auto reload timer then calculate the next\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 == ( UBaseType_t ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\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
else\r
{\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
mtCOVERAGE_TEST_MARKER();\r
}\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvTimerTask( void *pvParameters )\r
+static portTASK_FUNCTION( prvTimerTask, pvParameters )\r
{\r
TickType_t xNextExpireTime;\r
BaseType_t xListWasEmpty;\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
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
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_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\r
timer list. Process it now. */\r
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE )\r
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 )\r
{\r
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );\r
configASSERT( xResult );\r
\r
case tmrCOMMAND_STOP :\r
case tmrCOMMAND_STOP_FROM_ISR :\r
- /* The timer has already been removed from the active list.\r
- There is nothing to do here. */\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
break;\r
\r
case tmrCOMMAND_DELETE :\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 )\r
{\r
- if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE )\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( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 )\r
{\r
vPortFree( pxTimer );\r
}\r
else\r
{\r
- mtCOVERAGE_TEST_MARKER();\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
}\r
}\r
#else\r
{\r
- vPortFree( pxTimer );\r
+ /* If dynamic allocation is not enabled, the memory\r
+ could not have been dynamically allocated. So there is\r
+ no need to free the memory - just mark the timer as\r
+ "not active". */\r
+ pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE;\r
}\r
- #endif /* configSUPPORT_STATIC_ALLOCATION */\r
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
break;\r
\r
default :\r
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );\r
\r
/* Remove the timer from the list. */\r
- pxTimer = ( Timer_t * ) 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
have not yet been switched. */\r
pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer );\r
\r
- if( pxTimer->uxAutoReload == ( UBaseType_t ) 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
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; /*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
\r
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )\r
{\r
-BaseType_t xTimerIsInActiveList;\r
-Timer_t *pxTimer = ( Timer_t * ) 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 = ( BaseType_t ) !( 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 = ( Timer_t * ) xTimer;\r
+Timer_t * const pxTimer = xTimer;\r
void *pvReturn;\r
\r
configASSERT( xTimer );\r
\r
void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID )\r
{\r
-Timer_t * const pxTimer = ( Timer_t * ) xTimer;\r
+Timer_t * const pxTimer = xTimer;\r
\r
configASSERT( xTimer );\r
\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
to include software timer functionality. If you want to include software timer\r
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */\r