--- /dev/null
+/* Need a method of switching to an overflow list. _RB_*/\r
+\r
+/*\r
+ FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS books - available as PDF or paperback *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\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
+ ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
+ more details. You should have received a copy of the GNU General Public\r
+ License and the FreeRTOS license exception along with FreeRTOS; if not it\r
+ can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
+ by writing to Richard Barry, contact details for whom are available on the\r
+ FreeRTOS WEB site.\r
+\r
+ 1 tab == 4 spaces!\r
+\r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers. That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "timers.h"\r
+\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
+/* IDs for commands that can be sent/received on the timer queue. */\r
+#define tmrSTART 0\r
+\r
+/* Misc definitions. */\r
+#define timerNO_DELAY ( portTickType ) 0U\r
+\r
+/* The definition of the timers themselves. */\r
+typedef struct tmrTimerControl\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
+ 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
+} xTIMER;\r
+\r
+/* The definition of messages that can be sent and received on the timer \r
+queue. */\r
+typedef struct tmrTimerQueueMessage\r
+{\r
+ portBASE_TYPE xMessageID;\r
+ portTickType xMessageValue;\r
+ xTIMER * pxTimer;\r
+} xTIMER_MESSAGE;\r
+\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 xActiveTimerList. */\r
+PRIVILEGED_DATA static xList xActiveTimerList;\r
+\r
+/* A queue that is used to send commands to the timer service task. */\r
+PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Called when a timer is about to be modified. If the timer is already in the\r
+ * list of active timers then it is removed prior to the modification.\r
+ */\r
+static void prvRemoveTimerFromActiveList( xTIMER *pxTimer ) PRIVILEGED_FUNCTION;\r
+\r
+static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;\r
+\r
+/*\r
+ * The timer service task (daemon).\r
+ */\r
+static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;\r
+\r
+\r
+/* Handlers for commands received on the timer queue. */\r
+static void prvTimerStart( xTIMER *pxTimer );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTimerCreateTimerTask( void )\r
+{\r
+portBASE_TYPE xReturn = pdFAIL;\r
+\r
+ /* This function is called when the scheduler is started if \r
+ configUSE_TIMERS is set to 1. */\r
+ prvCheckForValidListAndQueue();\r
+\r
+ if( xTimerQueue != NULL )\r
+ {\r
+ xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Timers", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY, NULL );\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )\r
+{\r
+xTIMER *pxNewTimer;\r
+\r
+ /* Allocate the timer structure. */\r
+ pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );\r
+ if( pxNewTimer != NULL )\r
+ {\r
+ prvCheckForValidListAndQueue();\r
+\r
+ /* Initialise the timer structure members. */\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
+\r
+ return ( xTimerHandle ) pxNewTimer;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime )\r
+{\r
+portBASE_TYPE xReturn = pdFAIL;\r
+xTIMER_MESSAGE xMessage;\r
+\r
+ if( xTimerQueue != NULL )\r
+ {\r
+ xMessage.xMessageID = tmrSTART;\r
+ xMessage.pxTimer = ( xTIMER * ) xTimer;\r
+\r
+ xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void *pvTimerGetTimerID( xTimerHandle xTimer )\r
+{\r
+xTIMER *pxTimer = ( xTIMER * ) xTimer;\r
+\r
+ return pxTimer->pvTimerID;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRemoveTimerFromActiveList( xTIMER *pxTimer )\r
+{\r
+ /* Is the timer already in the list of active timers? */\r
+ if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )\r
+ {\r
+ /* The timer is in the list, remove it. */\r
+ vListRemove( &( pxTimer->xTimerListItem ) );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTimerTask( void *pvParameters )\r
+{\r
+portTickType xNextWakeTime, xTimeNow;\r
+xTIMER *pxTimer;\r
+xTIMER_MESSAGE xMessage;\r
+\r
+ /* Just to avoid compiler warnings. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ if( listLIST_IS_EMPTY( &xActiveTimerList ) == pdFALSE )\r
+ {\r
+ xNextWakeTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( &xActiveTimerList );\r
+ }\r
+ else\r
+ {\r
+ xNextWakeTime = portMAX_DELAY;\r
+ }\r
+\r
+ if( xNextWakeTime <= xTaskGetTickCount() )\r
+ {\r
+ /* Remove the timer from the list. This functionality relies on\r
+ the list of active timers not being accessed from outside of this\r
+ task. */\r
+ pxTimer = listGET_OWNER_OF_HEAD_ENTRY( &xActiveTimerList );\r
+ vListRemove( &( pxTimer->xTimerListItem ) );\r
+\r
+ if( pxTimer->uxAutoReload == pdTRUE )\r
+ {\r
+ listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), ( xNextWakeTime + pxTimer->xTimerPeriodInTicks ) );\r
+ vListInsert( &xActiveTimerList, &( pxTimer->xTimerListItem ) );\r
+ }\r
+\r
+ /* Call the timer callback. */\r
+ pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );\r
+ }\r
+ else\r
+ {\r
+ /* Calculate the block time. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ xTimeNow = xTaskGetTickCount();\r
+ if( xTimeNow < xNextWakeTime )\r
+ {\r
+ vQueueWaitForMessageRestricted( xTimerQueue, ( xNextWakeTime - xTimeNow ) );\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+ portYIELD_WITHIN_API();\r
+\r
+ while( xQueueReceive( xTimerQueue, &xMessage, timerNO_DELAY ) != pdFAIL )\r
+ {\r
+ switch( xMessage.xMessageID )\r
+ {\r
+ case tmrSTART : prvTimerStart( xMessage.pxTimer );\r
+ break;\r
+ default : /* Don't expect to get here. */\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckForValidListAndQueue( void )\r
+{\r
+ /* Check that the list from which active timers are referenced, and the\r
+ queue used to communicate with the timer service, have been \r
+ initialised. */\r
+ taskENTER_CRITICAL();\r
+ {\r
+ if( xTimerQueue == NULL )\r
+ {\r
+ vListInitialise( &xActiveTimerList );\r
+ xTimerQueue = xQueueCreate( configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );\r
+ }\r
+ }\r
+ taskEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTimerStart( xTIMER *pxTimer )\r
+{\r
+portTickType xTimeToWake;\r
+\r
+ if( pxTimer != NULL )\r
+ {\r
+ /* Is the timer already in the list of active timers? */\r
+ prvRemoveTimerFromActiveList( pxTimer );\r
+\r
+ xTimeToWake = xTaskGetTickCount() + pxTimer->xTimerPeriodInTicks;\r
+ listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xTimeToWake );\r
+ listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
+ vListInsert( &xActiveTimerList, &( pxTimer->xTimerListItem ) );\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )\r
+{\r
+ return pdFALSE;\r
+}\r
+\r
+void vTimerStop( xTimerHandle xTimer )\r
+{\r
+}\r
+\r
+\r
+void vTimerChangePeriod( xTimerHandle xTimer )\r
+{\r
+}\r
+\r
+void vTimerDelete( xTimerHandle xTimer )\r
+{\r
+}\r
+/*-----------------------------------------------------------*/\r