<listOptionValue builtIn="false" value="225"/>\r
</option>\r
<option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER.1187428873" name="Emit diagnostic identifier numbers (--display_error_number, -pden)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>\r
+ <option id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_FOR_SPEED.2099723751" name="Optimize for speed (--opt_for_speed, -mf)" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_FOR_SPEED" value="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compilerID.OPT_FOR_SPEED._none" valueType="enumerated"/>\r
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS.2129245761" name="C Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__C_SRCS"/>\r
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS.1546995708" name="C++ Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__CPP_SRCS"/>\r
<inputType id="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS.935376908" name="Assembly Sources" superClass="com.ti.ccstudio.buildDefinitions.TMS470_4.9.compiler.inputType__ASM_SRCS"/>\r
--- /dev/null
+REM This file should be executed from the command line prior to the first\r
+REM build. It will be necessary to refresh the Eclipse project once the\r
+REM .bat file has been executed (normally just press F5 to refresh).\r
+\r
+REM Copies all the required files from their location within the standard\r
+REM FreeRTOS directory structure to under the Eclipse project directory.\r
+REM This permits the Eclipse project to be used in 'managed' mode and without\r
+REM having to setup any linked resources.\r
+\r
+REM Standard paths\r
+SET FREERTOS_SOURCE=..\..\Source\r
+SET COMMON_SOURCE=..\Common\minimal\r
+SET COMMON_INCLUDE=..\Common\include\r
+\r
+REM Have the files already been copied?\r
+IF EXIST .\FreeRTOS_Source Goto END\r
+\r
+ REM Create the required directory structure.\r
+ MD FreeRTOS\r
+ MD FreeRTOS\include\r
+ MD FreeRTOS\portable\r
+ MD FreeRTOS\portable\CCS\r
+ MD FreeRTOS\portable\CCS\ARM_Cortex-R4_RM48_TMS570\r
+ MD FreeRTOS\portable\MemMang \r
+ MD Common-Demo-Source\r
+ MD Common-Demo-Source\include\r
+ \r
+ REM Copy the core kernel files into the project directory\r
+ copy %FREERTOS_SOURCE%\tasks.c FreeRTOS\r
+ copy %FREERTOS_SOURCE%\queue.c FreeRTOS\r
+ copy %FREERTOS_SOURCE%\list.c FreeRTOS\r
+ copy %FREERTOS_SOURCE%\timers.c FreeRTOS\r
+\r
+ REM Copy the common header files into the project directory\r
+ copy %FREERTOS_SOURCE%\include\*.* FreeRTOS\include\r
+ \r
+ REM Copy the portable layer files into the project directory\r
+ copy %FREERTOS_SOURCE%\portable\CCS\ARM_Cortex-R4_RM48_TMS570\*.* FreeRTOS\portable\CCS\ARM_Cortex-R4_RM48_TMS570\r
+ \r
+ REM Copy the memory allocation files into the project directory\r
+ copy %FREERTOS_SOURCE%\portable\MemMang\heap_4.c FreeRTOS\portable\MemMang\r
+\r
+ REM Copy the files that define the common demo tasks.\r
+ copy %COMMON_SOURCE%\dynamic.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\BlockQ.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\death.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\blocktim.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\semtest.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\PollQ.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\GenQTest.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\recmutex.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\countsem.c Common-Demo-Source\r
+ copy %COMMON_SOURCE%\integer.c Common-Demo-Source\r
+ \r
+ REM Copy the common demo file headers.\r
+ copy %COMMON_INCLUDE%\*.h Common-Demo-Source\include\r
+ \r
+: END\r
* See http://www.freertos.org/a00110.html.\r
*----------------------------------------------------------*/\r
\r
-#define configUSE_PREEMPTION 1\r
-#define configUSE_FPU 1\r
-#define configUSE_IDLE_HOOK 1\r
-#define configUSE_TICK_HOOK 1\r
-#define configUSE_TRACE_FACILITY 0\r
-#define configUSE_16_BIT_TICKS 0\r
-#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 90000000 ) /* Timer clock. */\r
-#define configTICK_RATE_HZ ( ( portTickType ) 1000 )\r
-#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 )\r
-#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )\r
-#define configTOTAL_HEAP_SIZE ( ( size_t ) 32768 )\r
-#define configMAX_TASK_NAME_LEN ( 16 )\r
-#define configIDLE_SHOULD_YIELD 1\r
-#define configGENERATE_RUN_TIME_STATS 0\r
-#define configUSE_MALLOC_FAILED_HOOK 1\r
-\r
-#define configCHECK_FOR_STACK_OVERFLOW 2\r
+#define configUSE_PREEMPTION 1\r
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1\r
+#define configUSE_FPU 1\r
+#define configUSE_IDLE_HOOK 1\r
+#define configUSE_TICK_HOOK 1\r
+#define configUSE_TRACE_FACILITY 0\r
+#define configUSE_16_BIT_TICKS 0\r
+#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 80000000 ) /* Timer clock. */\r
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )\r
+#define configMAX_PRIORITIES ( 8 )\r
+#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) 32768 )\r
+#define configMAX_TASK_NAME_LEN ( 16 )\r
+#define configIDLE_SHOULD_YIELD 1\r
+#define configGENERATE_RUN_TIME_STATS 0\r
+#define configUSE_MALLOC_FAILED_HOOK 1\r
+\r
+#define configCHECK_FOR_STACK_OVERFLOW 2\r
\r
/* Co-routine definitions. */\r
-#define configUSE_CO_ROUTINES 0\r
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+#define configUSE_CO_ROUTINES 0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
\r
/* Mutexes */\r
-#define configUSE_MUTEXES 1\r
-#define configUSE_RECURSIVE_MUTEXES 1\r
+#define configUSE_MUTEXES 1\r
+#define configUSE_RECURSIVE_MUTEXES 1\r
\r
/* Semaphores */\r
-#define configUSE_COUNTING_SEMAPHORES 1\r
+#define configUSE_COUNTING_SEMAPHORES 1\r
\r
/* Timers */\r
-#define configUSE_TIMERS 1\r
-#define configTIMER_TASK_PRIORITY ( 2 )\r
-#define configTIMER_QUEUE_LENGTH 10\r
-#define configTIMER_TASK_STACK_DEPTH ( 128 )\r
+#define configUSE_TIMERS 1\r
+#define configTIMER_TASK_PRIORITY ( 2 )\r
+#define configTIMER_QUEUE_LENGTH 10\r
+#define configTIMER_TASK_STACK_DEPTH ( 128 )\r
\r
/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */\r
-#define INCLUDE_vTaskPrioritySet 1\r
-#define INCLUDE_uxTaskPriorityGet 1\r
-#define INCLUDE_vTaskDelete 1\r
-#define INCLUDE_vTaskCleanUpResources 0\r
-#define INCLUDE_vTaskSuspend 1\r
-#define INCLUDE_xTaskResumeFromISR 0\r
-#define INCLUDE_vTaskDelayUntil 1\r
-#define INCLUDE_vTaskDelay 1\r
-#define INCLUDE_xTaskGetSchedulerState 1\r
-#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
+#define INCLUDE_vTaskPrioritySet 1\r
+#define INCLUDE_uxTaskPriorityGet 1\r
+#define INCLUDE_vTaskDelete 1\r
+#define INCLUDE_vTaskCleanUpResources 0\r
+#define INCLUDE_vTaskSuspend 1\r
+#define INCLUDE_xTaskResumeFromISR 0\r
+#define INCLUDE_vTaskDelayUntil 1\r
+#define INCLUDE_vTaskDelay 1\r
+#define INCLUDE_xTaskGetSchedulerState 1\r
+#define INCLUDE_uxTaskGetStackHighWaterMark 1\r
\r
#define configASSERT( x ) if( ( x ) == pdFALSE ) { taskDISABLE_INTERRUPTS(); for( ;; ); }\r
\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\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 modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or 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
+ ***************************************************************************\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
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+/*\r
+ * Creates eight tasks, each of which loops continuously performing an (emulated) \r
+ * floating point calculation.\r
+ *\r
+ * All the tasks run at the idle priority and never block or yield. This causes \r
+ * all eight tasks to time slice with the idle task. Running at the idle priority \r
+ * means that these tasks will get pre-empted any time another task is ready to run\r
+ * or a time slice occurs. More often than not the pre-emption will occur mid \r
+ * calculation, creating a good test of the schedulers context switch mechanism - a \r
+ * calculation producing an unexpected result could be a symptom of a corruption in \r
+ * the context of a task.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <math.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo program include files. */\r
+#include "flop.h"\r
+\r
+#define mathSTACK_SIZE configMINIMAL_STACK_SIZE\r
+#define mathNUMBER_OF_TASKS ( 8 )\r
+\r
+/* Four tasks, each of which performs a different floating point calculation. \r
+Each of the four is created twice. */\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );\r
+\r
+/* These variables are used to check that all the tasks are still running. If a \r
+task gets a calculation wrong it will\r
+stop incrementing its check variable. */\r
+static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
+\r
+/* Must be called by tasks that need to maintain a floating point context. */\r
+void vPortTaskUsesFPU( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartMathTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+ xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );\r
+ xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )\r
+{\r
+volatile portDOUBLE d1, d2, d3, d4;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+volatile portDOUBLE dAnswer;\r
+short sError = pdFALSE;\r
+\r
+ /* Must be called before any floating point operations are performed to let\r
+ the RTOS portable layer know that this task requires a floating point \r
+ context. */\r
+ vPortTaskUsesFPU();\r
+\r
+ d1 = 123.4567;\r
+ d2 = 2345.6789;\r
+ d3 = -918.222;\r
+\r
+ dAnswer = ( d1 + d2 ) * d3;\r
+\r
+ /* The variable this task increments to show it is still running is passed in \r
+ as the parameter. */\r
+ pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+ /* Keep performing a calculation and checking the result against a constant. */\r
+ for(;;)\r
+ {\r
+ d1 = 123.4567;\r
+ d2 = 2345.6789;\r
+ d3 = -918.222;\r
+\r
+ d4 = ( d1 + d2 ) * d3;\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ /* If the calculation does not match the expected constant, stop the \r
+ increment of the check variable. */\r
+ if( fabs( d4 - dAnswer ) > 0.001 )\r
+ {\r
+ sError = pdTRUE;\r
+ }\r
+\r
+ if( sError == pdFALSE )\r
+ {\r
+ /* If the calculation has always been correct, increment the check \r
+ variable so we know this task is still running okay. */\r
+ ( *pusTaskCheckVariable )++;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )\r
+{\r
+volatile portDOUBLE d1, d2, d3, d4;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+volatile portDOUBLE dAnswer;\r
+short sError = pdFALSE;\r
+\r
+ /* Must be called before any floating point operations are performed to let\r
+ the RTOS portable layer know that this task requires a floating point \r
+ context. */\r
+ vPortTaskUsesFPU();\r
+\r
+ d1 = -389.38;\r
+ d2 = 32498.2;\r
+ d3 = -2.0001;\r
+\r
+ dAnswer = ( d1 / d2 ) * d3;\r
+\r
+\r
+ /* The variable this task increments to show it is still running is passed in \r
+ as the parameter. */\r
+ pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+ /* Keep performing a calculation and checking the result against a constant. */\r
+ for( ;; )\r
+ {\r
+ d1 = -389.38;\r
+ d2 = 32498.2;\r
+ d3 = -2.0001;\r
+\r
+ d4 = ( d1 / d2 ) * d3;\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+ \r
+ /* If the calculation does not match the expected constant, stop the \r
+ increment of the check variable. */\r
+ if( fabs( d4 - dAnswer ) > 0.001 )\r
+ {\r
+ sError = pdTRUE;\r
+ }\r
+\r
+ if( sError == pdFALSE )\r
+ {\r
+ /* If the calculation has always been correct, increment the check \r
+ variable so we know\r
+ this task is still running okay. */\r
+ ( *pusTaskCheckVariable )++;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )\r
+{\r
+volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+const size_t xArraySize = 10;\r
+size_t xPosition;\r
+short sError = pdFALSE;\r
+\r
+ /* Must be called before any floating point operations are performed to let\r
+ the RTOS portable layer know that this task requires a floating point \r
+ context. */\r
+ vPortTaskUsesFPU();\r
+\r
+ /* The variable this task increments to show it is still running is passed in \r
+ as the parameter. */\r
+ pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+ pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
+\r
+ /* Keep filling an array, keeping a running total of the values placed in the \r
+ array. Then run through the array adding up all the values. If the two totals \r
+ do not match, stop the check variable from incrementing. */\r
+ for( ;; )\r
+ {\r
+ dTotal1 = 0.0;\r
+ dTotal2 = 0.0;\r
+\r
+ for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+ {\r
+ pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5;\r
+ dTotal1 += ( portDOUBLE ) xPosition + 5.5; \r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+ {\r
+ dTotal2 += pdArray[ xPosition ];\r
+ }\r
+\r
+ dDifference = dTotal1 - dTotal2;\r
+ if( fabs( dDifference ) > 0.001 )\r
+ {\r
+ sError = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ if( sError == pdFALSE )\r
+ {\r
+ /* If the calculation has always been correct, increment the check \r
+ variable so we know this task is still running okay. */\r
+ ( *pusTaskCheckVariable )++;\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )\r
+{\r
+volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+const size_t xArraySize = 10;\r
+size_t xPosition;\r
+short sError = pdFALSE;\r
+\r
+ /* Must be called before any floating point operations are performed to let\r
+ the RTOS portable layer know that this task requires a floating point \r
+ context. */\r
+ vPortTaskUsesFPU();\r
+\r
+ /* The variable this task increments to show it is still running is passed in \r
+ as the parameter. */\r
+ pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+ pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) );\r
+\r
+ /* Keep filling an array, keeping a running total of the values placed in the \r
+ array. Then run through the array adding up all the values. If the two totals \r
+ do not match, stop the check variable from incrementing. */\r
+ for( ;; )\r
+ {\r
+ dTotal1 = 0.0;\r
+ dTotal2 = 0.0;\r
+\r
+ for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+ {\r
+ pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123;\r
+ dTotal1 += ( portDOUBLE ) xPosition * 12.123; \r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+ {\r
+ dTotal2 += pdArray[ xPosition ];\r
+ }\r
+\r
+ dDifference = dTotal1 - dTotal2;\r
+ if( fabs( dDifference ) > 0.001 )\r
+ {\r
+ sError = pdTRUE;\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ taskYIELD();\r
+ #endif\r
+\r
+ if( sError == pdFALSE )\r
+ {\r
+ /* If the calculation has always been correct, increment the check \r
+ variable so we know this task is still running okay. */\r
+ ( *pusTaskCheckVariable )++;\r
+ }\r
+ }\r
+} \r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreMathsTaskStillRunning( void )\r
+{\r
+/* Keep a history of the check variables so we know if they have been incremented \r
+since the last call. */\r
+static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
+portBASE_TYPE xReturn = pdTRUE, xTask;\r
+\r
+ /* Check the maths tasks are still running by ensuring their check variables \r
+ are still incrementing. */\r
+ for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )\r
+ {\r
+ if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )\r
+ {\r
+ /* The check has not incremented so an error exists. */\r
+ xReturn = pdFALSE;\r
+ }\r
+\r
+ usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
+ \r
+\r
+ ***************************************************************************\r
+ * *\r
+ * FreeRTOS tutorial books are available in pdf and paperback. *\r
+ * Complete, revised, and edited pdf reference manuals are also *\r
+ * available. *\r
+ * *\r
+ * Purchasing FreeRTOS documentation will not only help you, by *\r
+ * ensuring you get running as quickly as possible and with an *\r
+ * in-depth knowledge of how to use FreeRTOS, it will also help *\r
+ * the FreeRTOS project to continue with its mission of providing *\r
+ * professional grade, cross platform, de facto standard solutions *\r
+ * for microcontrollers - completely free of charge! *\r
+ * *\r
+ * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
+ * *\r
+ * Thank you for using FreeRTOS, and thank you for your support! *\r
+ * *\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 modification to the GPL is included to allow you to\r
+ distribute a combined work that includes FreeRTOS without being obliged to\r
+ provide the source code for proprietary components outside of the FreeRTOS\r
+ kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
+ or 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
+ ***************************************************************************\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
+ \r
+ http://www.FreeRTOS.org - Documentation, training, latest information, \r
+ license and contact details.\r
+ \r
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+ including FreeRTOS+Trace - an indispensable productivity tool.\r
+\r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
+ the code with commercial support, indemnification, and middleware, under \r
+ the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
+ provide a safety engineered and independently SIL3 certified version under \r
+ the SafeRTOS brand: http://www.SafeRTOS.com.\r
+*/\r
+\r
+#ifndef FLOP_TASKS_H\r
+#define FLOP_TASKS_H\r
+\r
+void vStartMathTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreMathsTaskStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
* required to configure the hardware, are defined in main.c.\r
******************************************************************************\r
*\r
- * main_full() creates all the demo application tasks and a software timer, then\r
- * starts the scheduler. The web documentation provides more details of the \r
- * standard demo application tasks, which provide no particular functionality, \r
- * but do provide a good example of how to use the FreeRTOS API.\r
+ * main_full() creates all the demo application tasks and two software timers,\r
+ * then starts the scheduler. The web documentation provides more details of\r
+ * the standard demo application tasks, which provide no particular\r
+ * functionality, but do provide a good example of how to use the FreeRTOS API.\r
*\r
* In addition to the standard demo tasks, the following tasks and tests are\r
* defined and/or created within this file:\r
*\r
- * "Check" timer - The check software timer period is initially set to three\r
- * seconds. The callback function associated with the check software timer\r
- * checks that all the standard demo tasks are not only still executing, but \r
- * are executing without reporting any errors. If the check software timer \r
- * discovers that a task has either stalled, or reported an error, then it \r
- * changes its own execution period from the initial three seconds, to just \r
- * 200ms. The check software timer callback function also toggles the green \r
- * LED each time it is called. This provides a visual indication of the system \r
- * status: If the green LED toggles every three seconds, then no issues have \r
- * been discovered. If the green LED toggles every 200ms, then an issue has \r
- * been discovered with at least one task.\r
+ * "Check" timer - The check software timer period is set to three seconds.\r
+ * The callback function associated with the check software timer checks that\r
+ * all the standard demo tasks are not only still executing, but are executing\r
+ * without reporting any errors. If the check software timer discovers that a\r
+ * task has either stalled, or reported an error, then the error is logged and\r
+ * the check software timer toggles the red LEDs. If an error has never been\r
+ * latched, the check software timer toggles the green LEDs. Therefore, if the\r
+ * system is executing correctly, the green LEDs will toggle every three\r
+ * seconds, and if an error has ever been detected, the red LEDs will toggle\r
+ * every three seconds.\r
+ *\r
+ * "Reg test" tasks - These fill both the core and floating point registers\r
+ * with known values, then check that each register maintains its expected\r
+ * value for the lifetime of the tasks. Each task uses a different set of\r
+ * values. The reg test tasks execute with a very low priority, so get\r
+ * preempted very frequently. A register containing an unexpected value is\r
+ * indicative of an error in the context switching mechanism.\r
+ *\r
+ * "LED" software timer - The callback function associated with the LED\r
+ * software time maintains a pattern of spinning white LEDs.\r
*\r
* See the documentation page for this demo on the FreeRTOS.org web site for\r
* full information, including hardware setup requirements. \r
#include "recmutex.h"\r
#include "death.h"\r
#include "partest.h"\r
+#include "flop.h"\r
\r
/* Priorities for the demo application tasks. */\r
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )\r
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )\r
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
\r
/* A block time of zero simply means "don't block". */\r
#define mainDONT_BLOCK ( 0UL )\r
vStartRecursiveMutexTasks();\r
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+ vStartMathTasks( mainFLOP_TASK_PRIORITY );\r
\r
/* Create the register test tasks, as described at the top of this file. */\r
xTaskCreate( vRegTestTask1, ( const signed char * ) "Reg1...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
xTaskCreate( vRegTestTask2, ( const signed char * ) "Reg2...", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
\r
+\r
/* Create the software timer that performs the 'check' functionality,\r
as described at the top of this file. */\r
xTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */\r
xTimerStart( xTimer, mainDONT_BLOCK );\r
}\r
\r
- /* Create the software timer that performs the 'LED toggle' functionality,\r
+ /* Create the software timer that performs the 'LED spin' functionality,\r
as described at the top of this file. */\r
xTimer = xTimerCreate( ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */\r
( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 75ms. */\r
{\r
ulErrorFound = pdTRUE;\r
}\r
- \r
+\r
+ if( xAreMathsTaskStillRunning() != pdTRUE )\r
+ {\r
+ ulErrorFound = pdTRUE;\r
+ }\r
+\r
/* Check the reg test tasks are still cycling. They will stop\r
incrementing their loop counters if they encounter an error. */\r
if( ulRegTest1Counter == ulLastRegTest1Counter )\r
/* Application specific configuration options. */\r
#include "FreeRTOSConfig.h"\r
\r
+/* configUSE_PORT_OPTIMISED_TASK_SELECTION must be defined before portable.h\r
+is included as it is used by the port layer. */\r
+#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION\r
+ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0\r
+#endif\r
+\r
/* Definitions specific to the port being used. */\r
#include "portable.h"\r
\r
#define INCLUDE_uxTaskGetStackHighWaterMark 0\r
#endif\r
\r
+#ifndef INCLUDE_eTaskStateGet\r
+ #define INCLUDE_eTaskStateGet 0\r
+#endif\r
+\r
#ifndef configUSE_RECURSIVE_MUTEXES\r
#define configUSE_RECURSIVE_MUTEXES 0\r
#endif\r
#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )\r
#endif\r
\r
+#ifndef portSUPPRESS_TICKS_AND_SLEEP\r
+ #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )\r
+#endif\r
+\r
+#ifndef portPRE_SLEEP_PROCESSING\r
+ #define portPRE_SLEEP_PROCESSING()\r
+#endif\r
+\r
+#ifndef portPOST_SLEEP_PROCESSING\r
+ #define portPOST_SLEEP_PROCESSING()\r
+#endif\r
+\r
#endif /* INC_FREERTOS_H */\r
\r
+++ /dev/null
-/*\r
- FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\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 modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or 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
- ***************************************************************************\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
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
- license and contact details.\r
- \r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool.\r
-\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
- the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
- the SafeRTOS brand: http://www.SafeRTOS.com.\r
-*/\r
-\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "croutine.h"\r
-\r
-/*\r
- * Some kernel aware debuggers require data to be viewed to be global, rather\r
- * than file scope.\r
- */\r
-#ifdef portREMOVE_STATIC_QUALIFIER\r
- #define static\r
-#endif\r
-\r
-\r
-/* Lists for ready and blocked co-routines. --------------------*/\r
-static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */\r
-static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */\r
-static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */\r
-static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */\r
-static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */\r
-static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */\r
-\r
-/* Other file private variables. --------------------------------*/\r
-corCRCB * pxCurrentCoRoutine = NULL;\r
-static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;\r
-static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;\r
-\r
-/* The initial state of the co-routine when it is created. */\r
-#define corINITIAL_STATE ( 0 )\r
-\r
-/*\r
- * Place the co-routine represented by pxCRCB into the appropriate ready queue\r
- * for the priority. It is inserted at the end of the list.\r
- *\r
- * This macro accesses the co-routine ready lists and therefore must not be\r
- * used from within an ISR.\r
- */\r
-#define prvAddCoRoutineToReadyQueue( pxCRCB ) \\r
-{ \\r
- if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \\r
- { \\r
- uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \\r
- } \\r
- vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \\r
-} \r
-\r
-/*\r
- * Utility to ready all the lists used by the scheduler. This is called\r
- * automatically upon the creation of the first co-routine.\r
- */\r
-static void prvInitialiseCoRoutineLists( void );\r
-\r
-/*\r
- * Co-routines that are readied by an interrupt cannot be placed directly into\r
- * the ready lists (there is no mutual exclusion). Instead they are placed in\r
- * in the pending ready list in order that they can later be moved to the ready\r
- * list by the co-routine scheduler.\r
- */\r
-static void prvCheckPendingReadyList( void );\r
-\r
-/*\r
- * Macro that looks at the list of co-routines that are currently delayed to\r
- * see if any require waking.\r
- *\r
- * Co-routines are stored in the queue in the order of their wake time -\r
- * meaning once one co-routine has been found whose timer has not expired\r
- * we need not look any further down the list.\r
- */\r
-static void prvCheckDelayedList( void );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )\r
-{\r
-signed portBASE_TYPE xReturn;\r
-corCRCB *pxCoRoutine;\r
-\r
- /* Allocate the memory that will store the co-routine control block. */\r
- pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );\r
- if( pxCoRoutine )\r
- {\r
- /* If pxCurrentCoRoutine is NULL then this is the first co-routine to\r
- be created and the co-routine data structures need initialising. */\r
- if( pxCurrentCoRoutine == NULL )\r
- {\r
- pxCurrentCoRoutine = pxCoRoutine;\r
- prvInitialiseCoRoutineLists();\r
- }\r
-\r
- /* Check the priority is within limits. */\r
- if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )\r
- {\r
- uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;\r
- }\r
-\r
- /* Fill out the co-routine control block from the function parameters. */\r
- pxCoRoutine->uxState = corINITIAL_STATE;\r
- pxCoRoutine->uxPriority = uxPriority;\r
- pxCoRoutine->uxIndex = uxIndex;\r
- pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;\r
-\r
- /* Initialise all the other co-routine control block parameters. */\r
- vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );\r
- vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );\r
-\r
- /* Set the co-routine control block as a link back from the xListItem.\r
- This is so we can get back to the containing CRCB from a generic item\r
- in a list. */\r
- listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );\r
- listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );\r
- \r
- /* Event lists are always in priority order. */\r
- listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );\r
- \r
- /* Now the co-routine has been initialised it can be added to the ready\r
- list at the correct priority. */\r
- prvAddCoRoutineToReadyQueue( pxCoRoutine );\r
-\r
- xReturn = pdPASS;\r
- }\r
- else\r
- { \r
- xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;\r
- }\r
- \r
- return xReturn; \r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )\r
-{\r
-portTickType xTimeToWake;\r
-\r
- /* Calculate the time to wake - this may overflow but this is\r
- not a problem. */\r
- xTimeToWake = xCoRoutineTickCount + xTicksToDelay;\r
-\r
- /* We must remove ourselves from the ready list before adding\r
- ourselves to the blocked list as the same list item is used for\r
- both lists. */\r
- vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
-\r
- /* The list item will be inserted in wake time order. */\r
- listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );\r
-\r
- if( xTimeToWake < xCoRoutineTickCount )\r
- {\r
- /* Wake time has overflowed. Place this item in the\r
- overflow list. */\r
- vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
- }\r
- else\r
- {\r
- /* The wake time has not overflowed, so we can use the\r
- current block list. */\r
- vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );\r
- }\r
-\r
- if( pxEventList )\r
- {\r
- /* Also add the co-routine to an event list. If this is done then the\r
- function must be called with interrupts disabled. */\r
- vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );\r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckPendingReadyList( void )\r
-{\r
- /* Are there any co-routines waiting to get moved to the ready list? These\r
- are co-routines that have been readied by an ISR. The ISR cannot access\r
- the ready lists itself. */\r
- while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )\r
- {\r
- corCRCB *pxUnblockedCRCB;\r
-\r
- /* The pending ready list can be accessed by an ISR. */\r
- portDISABLE_INTERRUPTS();\r
- { \r
- pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); \r
- vListRemove( &( pxUnblockedCRCB->xEventListItem ) );\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- vListRemove( &( pxUnblockedCRCB->xGenericListItem ) );\r
- prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); \r
- }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckDelayedList( void )\r
-{\r
-corCRCB *pxCRCB;\r
-\r
- xPassedTicks = xTaskGetTickCount() - xLastTickCount;\r
- while( xPassedTicks )\r
- {\r
- xCoRoutineTickCount++;\r
- xPassedTicks--;\r
-\r
- /* If the tick count has overflowed we need to swap the ready lists. */\r
- if( xCoRoutineTickCount == 0 )\r
- {\r
- xList * pxTemp;\r
-\r
- /* Tick count has overflowed so we need to swap the delay lists. If there are\r
- any items in pxDelayedCoRoutineList here then there is an error! */\r
- pxTemp = pxDelayedCoRoutineList;\r
- pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;\r
- pxOverflowDelayedCoRoutineList = pxTemp;\r
- }\r
-\r
- /* See if this tick has made a timeout expire. */\r
- while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )\r
- {\r
- pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );\r
-\r
- if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) \r
- { \r
- /* Timeout not yet expired. */ \r
- break; \r
- } \r
-\r
- portDISABLE_INTERRUPTS();\r
- {\r
- /* The event could have occurred just before this critical\r
- section. If this is the case then the generic list item will\r
- have been moved to the pending ready list and the following\r
- line is still valid. Also the pvContainer parameter will have\r
- been set to NULL so the following lines are also valid. */\r
- vListRemove( &( pxCRCB->xGenericListItem ) ); \r
-\r
- /* Is the co-routine waiting on an event also? */ \r
- if( pxCRCB->xEventListItem.pvContainer ) \r
- { \r
- vListRemove( &( pxCRCB->xEventListItem ) ); \r
- }\r
- }\r
- portENABLE_INTERRUPTS();\r
-\r
- prvAddCoRoutineToReadyQueue( pxCRCB ); \r
- } \r
- }\r
-\r
- xLastTickCount = xCoRoutineTickCount;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vCoRoutineSchedule( void )\r
-{\r
- /* See if any co-routines readied by events need moving to the ready lists. */\r
- prvCheckPendingReadyList();\r
-\r
- /* See if any delayed co-routines have timed out. */\r
- prvCheckDelayedList();\r
-\r
- /* Find the highest priority queue that contains ready co-routines. */\r
- while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )\r
- {\r
- if( uxTopCoRoutineReadyPriority == 0 )\r
- {\r
- /* No more co-routines to check. */\r
- return;\r
- }\r
- --uxTopCoRoutineReadyPriority;\r
- }\r
-\r
- /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines\r
- of the same priority get an equal share of the processor time. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );\r
-\r
- /* Call the co-routine. */\r
- ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );\r
-\r
- return;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvInitialiseCoRoutineLists( void )\r
-{\r
-unsigned portBASE_TYPE uxPriority;\r
-\r
- for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )\r
- {\r
- vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );\r
- }\r
-\r
- vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );\r
- vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );\r
- vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );\r
-\r
- /* Start with pxDelayedCoRoutineList using list1 and the\r
- pxOverflowDelayedCoRoutineList using list2. */\r
- pxDelayedCoRoutineList = &xDelayedCoRoutineList1;\r
- pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )\r
-{\r
-corCRCB *pxUnblockedCRCB;\r
-signed portBASE_TYPE xReturn;\r
-\r
- /* This function is called from within an interrupt. It can only access\r
- event lists and the pending ready list. This function assumes that a\r
- check has already been made to ensure pxEventList is not empty. */\r
- pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
- vListRemove( &( pxUnblockedCRCB->xEventListItem ) );\r
- vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );\r
-\r
- if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )\r
- {\r
- xReturn = pdTRUE;\r
- }\r
- else\r
- {\r
- xReturn = pdFALSE;\r
- }\r
-\r
- return xReturn;\r
-}\r
-\r
+++ /dev/null
-/*\r
- FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
-\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS tutorial books are available in pdf and paperback. *\r
- * Complete, revised, and edited pdf reference manuals are also *\r
- * available. *\r
- * *\r
- * Purchasing FreeRTOS documentation will not only help you, by *\r
- * ensuring you get running as quickly as possible and with an *\r
- * in-depth knowledge of how to use FreeRTOS, it will also help *\r
- * the FreeRTOS project to continue with its mission of providing *\r
- * professional grade, cross platform, de facto standard solutions *\r
- * for microcontrollers - completely free of charge! *\r
- * *\r
- * >>> See http://www.FreeRTOS.org/Documentation for details. <<< *\r
- * *\r
- * Thank you for using FreeRTOS, and thank you for your support! *\r
- * *\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 modification to the GPL is included to allow you to\r
- distribute a combined work that includes FreeRTOS without being obliged to\r
- provide the source code for proprietary components outside of the FreeRTOS\r
- kernel. FreeRTOS is distributed in the hope that it will be useful, but\r
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
- or 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
- ***************************************************************************\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
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
- license and contact details.\r
- \r
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
- including FreeRTOS+Trace - an indispensable productivity tool.\r
-\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
- the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
- the SafeRTOS brand: http://www.SafeRTOS.com.\r
-*/\r
-\r
-#ifndef CO_ROUTINE_H\r
-#define CO_ROUTINE_H\r
-\r
-#ifndef INC_FREERTOS_H\r
- #error "include FreeRTOS.h must appear in source files before include croutine.h"\r
-#endif\r
-\r
-#include "list.h"\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-/* Used to hide the implementation of the co-routine control block. The\r
-control block structure however has to be included in the header due to\r
-the macro implementation of the co-routine functionality. */\r
-typedef void * xCoRoutineHandle;\r
-\r
-/* Defines the prototype to which co-routine functions must conform. */\r
-typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );\r
-\r
-typedef struct corCoRoutineControlBlock\r
-{\r
- crCOROUTINE_CODE pxCoRoutineFunction;\r
- xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */\r
- unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */\r
- unsigned short uxState; /*< Used internally by the co-routine implementation. */\r
-} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- portBASE_TYPE xCoRoutineCreate(\r
- crCOROUTINE_CODE pxCoRoutineCode,\r
- unsigned portBASE_TYPE uxPriority,\r
- unsigned portBASE_TYPE uxIndex\r
- );</pre>\r
- *\r
- * Create a new co-routine and add it to the list of co-routines that are\r
- * ready to run.\r
- *\r
- * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine\r
- * functions require special syntax - see the co-routine section of the WEB\r
- * documentation for more information.\r
- *\r
- * @param uxPriority The priority with respect to other co-routines at which\r
- * the co-routine will run.\r
- *\r
- * @param uxIndex Used to distinguish between different co-routines that\r
- * execute the same function. See the example below and the co-routine section\r
- * of the WEB documentation for further information.\r
- *\r
- * @return pdPASS if the co-routine was successfully created and added to a ready\r
- * list, otherwise an error code defined with ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- static const char cLedToFlash[ 2 ] = { 5, 6 };\r
- static const portTickType uxFlashRates[ 2 ] = { 200, 400 };\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This co-routine just delays for a fixed period, then toggles\r
- // an LED. Two co-routines are created using this function, so\r
- // the uxIndex parameter is used to tell the co-routine which\r
- // LED to flash and how long to delay. This assumes xQueue has\r
- // already been created.\r
- vParTestToggleLED( cLedToFlash[ uxIndex ] );\r
- crDELAY( xHandle, uxFlashRates[ uxIndex ] );\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }\r
-\r
- // Function that creates two co-routines.\r
- void vOtherFunction( void )\r
- {\r
- unsigned char ucParameterToPass;\r
- xTaskHandle xHandle;\r
- \r
- // Create two co-routines at priority 0. The first is given index 0\r
- // so (from the code above) toggles LED 5 every 200 ticks. The second\r
- // is given index 1 so toggles LED 6 every 400 ticks.\r
- for( uxIndex = 0; uxIndex < 2; uxIndex++ )\r
- {\r
- xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );\r
- }\r
- }\r
- </pre>\r
- * \defgroup xCoRoutineCreate xCoRoutineCreate\r
- * \ingroup Tasks\r
- */\r
-signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );\r
-\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- void vCoRoutineSchedule( void );</pre>\r
- *\r
- * Run a co-routine.\r
- *\r
- * vCoRoutineSchedule() executes the highest priority co-routine that is able\r
- * to run. The co-routine will execute until it either blocks, yields or is\r
- * preempted by a task. Co-routines execute cooperatively so one\r
- * co-routine cannot be preempted by another, but can be preempted by a task.\r
- *\r
- * If an application comprises of both tasks and co-routines then\r
- * vCoRoutineSchedule should be called from the idle task (in an idle task\r
- * hook).\r
- *\r
- * Example usage:\r
- <pre>\r
- // This idle task hook will schedule a co-routine each time it is called.\r
- // The rest of the idle task will execute between co-routine calls.\r
- void vApplicationIdleHook( void )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
-\r
- // Alternatively, if you do not require any other part of the idle task to\r
- // execute, the idle task hook can call vCoRoutineScheduler() within an\r
- // infinite loop.\r
- void vApplicationIdleHook( void )\r
- {\r
- for( ;; )\r
- {\r
- vCoRoutineSchedule();\r
- }\r
- }\r
- </pre>\r
- * \defgroup vCoRoutineSchedule vCoRoutineSchedule\r
- * \ingroup Tasks\r
- */\r
-void vCoRoutineSchedule( void );\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crSTART( xCoRoutineHandle xHandle );</pre>\r
- *\r
- * This macro MUST always be called at the start of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static long ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crEND();</pre>\r
- *\r
- * This macro MUST always be called at the end of a co-routine function.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static long ulAVariable;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Co-routine functionality goes here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crSTART crSTART\r
- * \ingroup Tasks\r
- */\r
-#define crEND() }\r
-\r
-/*\r
- * These macros are intended for internal use by the co-routine implementation\r
- * only. The macros should not be used directly by application writers.\r
- */\r
-#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):\r
-#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):\r
-\r
-/**\r
- * croutine. h\r
- *<pre>\r
- crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>\r
- *\r
- * Delay a co-routine for a fixed period of time.\r
- *\r
- * crDELAY can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * @param xHandle The handle of the co-routine to delay. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should delay\r
- * for. The actual amount of time this equates to is defined by\r
- * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS\r
- * can be used to convert ticks to milliseconds.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine to be created.\r
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- // This may not be necessary for const variables.\r
- // We are to delay for 200ms.\r
- static const xTickType xDelayTime = 200 / portTICK_RATE_MS;\r
-\r
- // Must start every co-routine with a call to crSTART();\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Delay for 200ms.\r
- crDELAY( xHandle, xDelayTime );\r
-\r
- // Do something here.\r
- }\r
-\r
- // Must end every co-routine with a call to crEND();\r
- crEND();\r
- }</pre>\r
- * \defgroup crDELAY crDELAY\r
- * \ingroup Tasks\r
- */\r
-#define crDELAY( xHandle, xTicksToDelay ) \\r
- if( ( xTicksToDelay ) > 0 ) \\r
- { \\r
- vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \\r
- } \\r
- crSET_STATE0( ( xHandle ) );\r
-\r
-/**\r
- * <pre>\r
- crQUEUE_SEND(\r
- xCoRoutineHandle xHandle,\r
- xQueueHandle pxQueue,\r
- void *pvItemToQueue,\r
- portTickType xTicksToWait,\r
- portBASE_TYPE *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_SEND can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue on which the data will be posted.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvItemToQueue A pointer to the data being posted onto the queue.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied from pvItemToQueue into the queue\r
- * itself.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for space to become available on the queue, should space not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example\r
- * below).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully posted onto the queue, otherwise it will be set to an\r
- * error defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // Co-routine function that blocks for a fixed period then posts a number onto\r
- // a queue.\r
- static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static portBASE_TYPE xNumberToPost = 0;\r
- static portBASE_TYPE xResult;\r
-\r
- // Co-routines must begin with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // This assumes the queue has already been created.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );\r
-\r
- if( xResult != pdPASS )\r
- {\r
- // The message was not posted!\r
- }\r
-\r
- // Increment the number to be posted onto the queue.\r
- xNumberToPost++;\r
-\r
- // Delay for 100 ticks.\r
- crDELAY( xHandle, 100 );\r
- }\r
-\r
- // Co-routines must end with a call to crEND().\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_SEND crQUEUE_SEND\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \\r
- } \\r
- if( *pxResult == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *pxResult = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_RECEIVE(\r
- xCoRoutineHandle xHandle,\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portTickType xTicksToWait,\r
- portBASE_TYPE *pxResult\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine\r
- * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.\r
- *\r
- * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas\r
- * xQueueSend() and xQueueReceive() can only be used from tasks.\r
- *\r
- * crQUEUE_RECEIVE can only be called from the co-routine function itself - not\r
- * from within a function called by the co-routine function. This is because\r
- * co-routines do not maintain their own stack.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xHandle The handle of the calling co-routine. This is the xHandle\r
- * parameter of the co-routine function.\r
- *\r
- * @param pxQueue The handle of the queue from which the data will be received.\r
- * The handle is obtained as the return value when the queue is created using\r
- * the xQueueCreate() API function.\r
- *\r
- * @param pvBuffer The buffer into which the received item is to be copied.\r
- * The number of bytes of each queued item is specified when the queue is\r
- * created. This number of bytes is copied into pvBuffer.\r
- *\r
- * @param xTickToDelay The number of ticks that the co-routine should block\r
- * to wait for data to become available from the queue, should data not be\r
- * available immediately. The actual amount of time this equates to is defined\r
- * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant\r
- * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the\r
- * crQUEUE_SEND example).\r
- *\r
- * @param pxResult The variable pointed to by pxResult will be set to pdPASS if\r
- * data was successfully retrieved from the queue, otherwise it will be set to\r
- * an error code as defined within ProjDefs.h.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine receives the number of an LED to flash from a queue. It\r
- // blocks on the queue until the number is received.\r
- static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.\r
- static portBASE_TYPE xResult;\r
- static unsigned portBASE_TYPE uxLEDToFlash;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue.\r
- crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // We received the LED to flash - flash it!\r
- vParTestToggleLED( uxLEDToFlash );\r
- }\r
- }\r
-\r
- crEND();\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \\r
-{ \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \\r
- if( *( pxResult ) == errQUEUE_BLOCKED ) \\r
- { \\r
- crSET_STATE0( ( xHandle ) ); \\r
- *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \\r
- } \\r
- if( *( pxResult ) == errQUEUE_YIELD ) \\r
- { \\r
- crSET_STATE1( ( xHandle ) ); \\r
- *( pxResult ) = pdPASS; \\r
- } \\r
-}\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- xQueueHandle pxQueue,\r
- void *pvItemToQueue,\r
- portBASE_TYPE xCoRoutinePreviouslyWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue\r
- * that is being used from within a co-routine.\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvItemToQueue A pointer to the item that is to be placed on the\r
- * queue. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from pvItemToQueue\r
- * into the queue storage area.\r
- *\r
- * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto\r
- * the same queue multiple times from a single interrupt. The first call\r
- * should always pass in pdFALSE. Subsequent calls should pass in\r
- * the value returned from the previous call.\r
- *\r
- * @return pdTRUE if a co-routine was woken by posting onto the queue. This is\r
- * used by the ISR to determine if a context switch may be required following\r
- * the ISR.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that blocks on a queue waiting for characters to be received.\r
- static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- char cRxedChar;\r
- portBASE_TYPE xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Wait for data to become available on the queue. This assumes the\r
- // queue xCommsRxQueue has already been created!\r
- crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );\r
-\r
- // Was a character received?\r
- if( xResult == pdPASS )\r
- {\r
- // Process the character here.\r
- }\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to send characters received on a serial port to\r
- // a co-routine.\r
- void vUART_ISR( void )\r
- {\r
- char cRxedChar;\r
- portBASE_TYPE xCRWokenByPost = pdFALSE;\r
-\r
- // We loop around reading characters until there are none left in the UART.\r
- while( UART_RX_REG_NOT_EMPTY() )\r
- {\r
- // Obtain the character from the UART.\r
- cRxedChar = UART_RX_REG;\r
-\r
- // Post the character onto a queue. xCRWokenByPost will be pdFALSE\r
- // the first time around the loop. If the post causes a co-routine\r
- // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.\r
- // In this manner we can ensure that if more than one co-routine is\r
- // blocked on the queue only one is woken by this ISR no matter how\r
- // many characters are posted to the queue.\r
- xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )\r
-\r
-\r
-/**\r
- * croutine. h\r
- * <pre>\r
- crQUEUE_SEND_FROM_ISR(\r
- xQueueHandle pxQueue,\r
- void *pvBuffer,\r
- portBASE_TYPE * pxCoRoutineWoken\r
- )</pre>\r
- *\r
- * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the\r
- * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()\r
- * functions used by tasks.\r
- *\r
- * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to\r
- * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and\r
- * xQueueReceiveFromISR() can only be used to pass data between a task and and\r
- * ISR.\r
- *\r
- * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data\r
- * from a queue that is being used from within a co-routine (a co-routine\r
- * posted to the queue).\r
- *\r
- * See the co-routine section of the WEB documentation for information on\r
- * passing data between tasks and co-routines and between ISR's and\r
- * co-routines.\r
- *\r
- * @param xQueue The handle to the queue on which the item is to be posted.\r
- *\r
- * @param pvBuffer A pointer to a buffer into which the received item will be\r
- * placed. The size of the items the queue will hold was defined when the\r
- * queue was created, so this many bytes will be copied from the queue into\r
- * pvBuffer.\r
- *\r
- * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become\r
- * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a\r
- * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise\r
- * *pxCoRoutineWoken will remain unchanged.\r
- *\r
- * @return pdTRUE an item was successfully received from the queue, otherwise\r
- * pdFALSE.\r
- *\r
- * Example usage:\r
- <pre>\r
- // A co-routine that posts a character to a queue then blocks for a fixed\r
- // period. The character is incremented each time.\r
- static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )\r
- {\r
- // cChar holds its value while this co-routine is blocked and must therefore\r
- // be declared static.\r
- static char cCharToTx = 'a';\r
- portBASE_TYPE xResult;\r
-\r
- // All co-routines must start with a call to crSTART().\r
- crSTART( xHandle );\r
-\r
- for( ;; )\r
- {\r
- // Send the next character to the queue.\r
- crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );\r
-\r
- if( xResult == pdPASS )\r
- {\r
- // The character was successfully posted to the queue.\r
- }\r
- else\r
- {\r
- // Could not post the character to the queue.\r
- }\r
-\r
- // Enable the UART Tx interrupt to cause an interrupt in this\r
- // hypothetical UART. The interrupt will obtain the character\r
- // from the queue and send it.\r
- ENABLE_RX_INTERRUPT();\r
-\r
- // Increment to the next character then block for a fixed period.\r
- // cCharToTx will maintain its value across the delay as it is\r
- // declared static.\r
- cCharToTx++;\r
- if( cCharToTx > 'x' )\r
- {\r
- cCharToTx = 'a';\r
- }\r
- crDELAY( 100 );\r
- }\r
-\r
- // All co-routines must end with a call to crEND().\r
- crEND();\r
- }\r
-\r
- // An ISR that uses a queue to receive characters to send on a UART.\r
- void vUART_ISR( void )\r
- {\r
- char cCharToTx;\r
- portBASE_TYPE xCRWokenByPost = pdFALSE;\r
-\r
- while( UART_TX_REG_EMPTY() )\r
- {\r
- // Are there any characters in the queue waiting to be sent?\r
- // xCRWokenByPost will automatically be set to pdTRUE if a co-routine\r
- // is woken by the post - ensuring that only a single co-routine is\r
- // woken no matter how many times we go around this loop.\r
- if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )\r
- {\r
- SEND_CHARACTER( cCharToTx );\r
- }\r
- }\r
- }</pre>\r
- * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR\r
- * \ingroup Tasks\r
- */\r
-#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )\r
-\r
-/*\r
- * This function is intended for internal use by the co-routine macros only.\r
- * The macro nature of the co-routine implementation requires that the\r
- * prototype appears here. The function should not be used by application\r
- * writers.\r
- *\r
- * Removes the current co-routine from its ready list and places it in the\r
- * appropriate delayed list.\r
- */\r
-void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );\r
-\r
-/*\r
- * This function is intended for internal use by the queue implementation only.\r
- * The function should not be used by application writers.\r
- *\r
- * Removes the highest priority co-routine from the event list and places it in\r
- * the pending ready list.\r
- */\r
-signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif /* CO_ROUTINE_H */\r
FreeRTOS WEB site.\r
\r
1 tab == 4 spaces!\r
- \r
+\r
***************************************************************************\r
* *\r
* Having a problem? Start by reading the FAQ "My application does *\r
* *\r
***************************************************************************\r
\r
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
license and contact details.\r
- \r
+\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool.\r
\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
+ provide a safety engineered and independently SIL3 certified version under\r
the SafeRTOS brand: http://www.SafeRTOS.com.\r
*/\r
\r
before vTaskStartScheduler() has been called?).\r
See http://www.freertos.org/FAQHelp.html for more tips.\r
**********************************************************************/\r
- \r
+\r
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )\r
{\r
/* There is nothing to do here, we are just iterating to the\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vListRemove( xListItem *pxItemToRemove )\r
+unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove )\r
{\r
xList * pxList;\r
\r
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;\r
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;\r
- \r
+\r
/* The list item knows which list it is in. Obtain the list from the list\r
item. */\r
pxList = ( xList * ) pxItemToRemove->pvContainer;\r
\r
pxItemToRemove->pvContainer = NULL;\r
( pxList->uxNumberOfItems )--;\r
+\r
+ return pxList->uxNumberOfItems;\r
}\r
/*-----------------------------------------------------------*/\r
\r
*/\r
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )\r
\r
+/*\r
+ * Return the list a list item is contained within (referenced from).\r
+ *\r
+ * @param pxListItem The list item being queried.\r
+ * @return A pointer to the xList object that references the pxListItem\r
+ */\r
+#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )\r
+\r
/*\r
* This provides a crude means of knowing if a list has been initialised, as\r
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()\r
* Remove an item from a list. The list item has a pointer to the list that\r
* it is in, so only the list item need be passed into the function.\r
*\r
- * @param vListRemove The item to be removed. The item will remove itself from\r
+ * @param uxListRemove The item to be removed. The item will remove itself from\r
* the list pointed to by it's pxContainer parameter.\r
+ * \r
+ * @return The number of items that remain in the list after the list item has\r
+ * been removed.\r
*\r
- * \page vListRemove vListRemove\r
+ * \page uxListRemove uxListRemove\r
* \ingroup LinkedList\r
*/\r
-void vListRemove( xListItem *pxItemToRemove );\r
+unsigned portBASE_TYPE uxListRemove( xListItem *pxItemToRemove );\r
\r
#ifdef __cplusplus\r
}\r
#define vTaskDelay MPU_vTaskDelay\r
#define uxTaskPriorityGet MPU_uxTaskPriorityGet\r
#define vTaskPrioritySet MPU_vTaskPrioritySet\r
+ #define eTaskStateGet MPU_eTaskStateGet\r
#define vTaskSuspend MPU_vTaskSuspend\r
#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended\r
#define vTaskResume MPU_vTaskResume\r
; Restore the context of the task selected to execute.\r
portRESTORE_CONTEXT\r
\r
+;-------------------------------------------------------------------------------\r
+\r
+ .def ulPortCountLeadingZeros\r
+\r
+ulPortCountLeadingZeros:\r
+\r
+ CLZ R0, R0\r
+ BX LR\r
+\r
;-------------------------------------------------------------------------------\r
\r
.if (__TI_VFP_SUPPORT__)\r
\r
.endif ;__TI_VFP_SUPPORT__\r
\r
+\r
pxCurrentTCBConst .word pxCurrentTCB\r
ulFPUContextConst .word ulTaskHasFPUContext\r
;-------------------------------------------------------------------------------\r
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }\r
#define portYIELD_FROM_ISR() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; ( void ) portSYS_SSIR1_REG; }\r
\r
+/* Architecture specific optimisations. */\r
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1\r
+\r
+ /* Generic helper function. */\r
+ unsigned long ulPortCountLeadingZeros( unsigned long ulBitmap );\r
+\r
+ /* Check the configuration. */\r
+ #if( configMAX_PRIORITIES > 32 )\r
+ #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.\r
+ #endif\r
+\r
+ /* Store/clear the ready priorities in a bit map. */\r
+ #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )\r
+ #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )\r
+\r
+ /*-----------------------------------------------------------*/\r
+\r
+ #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )\r
+\r
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */\r
+\r
+\r
/* Task function macros as described on the FreeRTOS.org WEB site. */\r
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)\r
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)\r
FreeRTOS WEB site.\r
\r
1 tab == 4 spaces!\r
- \r
+\r
***************************************************************************\r
* *\r
* Having a problem? Start by reading the FAQ "My application does *\r
* *\r
***************************************************************************\r
\r
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
license and contact details.\r
- \r
+\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool.\r
\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
+ provide a safety engineered and independently SIL3 certified version under\r
the SafeRTOS brand: http://www.SafeRTOS.com.\r
*/\r
\r
\r
volatile signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
volatile signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */\r
- \r
+\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
unsigned char ucQueueNumber;\r
unsigned char ucQueueType;\r
\r
if( xNewQueue == pdFALSE )\r
{\r
- /* If there are tasks blocked waiting to read from the queue, then \r
- the tasks will remain blocked as after this function exits the queue \r
- will still be empty. If there are tasks blocked waiting to write to \r
- the queue, then one should be unblocked as after this function exits \r
+ /* If there are tasks blocked waiting to read from the queue, then\r
+ the tasks will remain blocked as after this function exits the queue\r
+ will still be empty. If there are tasks blocked waiting to write to\r
+ the queue, then one should be unblocked as after this function exits\r
it will be possible to write to it. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
{\r
/* Ensure the event queues start in the correct state. */\r
vListInitialise( &( pxQueue->xTasksWaitingToSend ) );\r
- vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); \r
+ vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );\r
}\r
}\r
taskEXIT_CRITICAL();\r
/* This function is called by xSemaphoreGetMutexHolder(), and should not\r
be called directly. Note: This is is a good way of determining if the\r
calling task is the mutex holder, but not a good way of determining the\r
- identity of the mutex holder, as the holder may change between the \r
+ identity of the mutex holder, as the holder may change between the\r
following critical section exiting and the function returning. */\r
taskENTER_CRITICAL();\r
{\r
}\r
}\r
taskEXIT_CRITICAL();\r
- \r
+\r
return pxReturn;\r
}\r
\r
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
{\r
portENTER_CRITICAL();\r
+ {\r
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+ }\r
portEXIT_CRITICAL();\r
}\r
}\r
xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ];\r
} xTaskParameters;\r
\r
+/* Task states returned by eTaskStateGet. */\r
+typedef enum\r
+{\r
+ eRunning = 0, /* A task is querying the state of itself, so must be running. */\r
+ eReady, /* The task being queried is in a read or pending ready list. */\r
+ eBlocked, /* The task being queried is in the Blocked state. */\r
+ eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */\r
+ eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */\r
+} eTaskState;\r
+\r
/*\r
* Defines the priority used by the idle task. This must not be modified.\r
*\r
*/\r
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
\r
+/**\r
+ * task. h\r
+ * <pre>eTaskState eTaskStateGet( xTaskHandle pxTask );</pre>\r
+ *\r
+ * INCLUDE_eTaskStateGet must be defined as 1 for this function to be available.\r
+ * See the configuration section for more information.\r
+ *\r
+ * Obtain the state of any task. States are encoded by the eTaskState \r
+ * enumerated type.\r
+ *\r
+ * @param pxTask Handle of the task to be queried.\r
+ *\r
+ * @return The state of pxTask at the time the function was called. Note the\r
+ * state of the task might change between the function being called, and the\r
+ * functions return value being tested by the calling task.\r
+ */\r
+eTaskState eTaskStateGet( xTaskHandle pxTask ) PRIVILEGED_FUNCTION;\r
+\r
/**\r
* task. h\r
* <pre>void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );</pre>\r
*/\r
void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle );\r
\r
+/*\r
+ * Return the amount of time, in ticks, that will pass before the kernel will\r
+ * next move a task from the Blocked state to the Running state.\r
+ */\r
+portTickType xTaskGetExpectedIdleTime( void );\r
+\r
+/*\r
+ * If tickless mode is being used, or a low power mode is implemented, then\r
+ * the tick interrupt will not execute during idle periods. When this is the\r
+ * case, the tick count value maintained by the scheduler needs to be kept up\r
+ * to date with the actual execution time by being skipped forward by the by\r
+ * a time equal to the idle period.\r
+ */\r
+void vTaskStepTick( portTickType xTicksToJump );\r
+\r
+/*\r
+ * Returns the number of tick interrupts that have occurred while the scheduler \r
+ * has been suspended. The count pending ticks is reset if xResetOnExit is set\r
+ * to pdTRUE.\r
+ */\r
+unsigned portBASE_TYPE uxTaskPendingTicksGet( portBASE_TYPE xResetOnExit );\r
\r
#ifdef __cplusplus\r
}\r
/*\r
FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
- \r
+\r
\r
***************************************************************************\r
* *\r
FreeRTOS WEB site.\r
\r
1 tab == 4 spaces!\r
- \r
+\r
***************************************************************************\r
* *\r
* Having a problem? Start by reading the FAQ "My application does *\r
* *\r
***************************************************************************\r
\r
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
license and contact details.\r
- \r
+\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool.\r
\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
+ provide a safety engineered and independently SIL3 certified version under\r
the SafeRTOS brand: http://www.SafeRTOS.com.\r
*/\r
\r
-\r
+/* Standard includes. */\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include <string.h>\r
task.h is included from an application file. */\r
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
\r
+/* FreeRTOS includes. */\r
#include "FreeRTOS.h"\r
#include "task.h"\r
#include "timers.h"\r
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
\r
/*\r
- * Macro to define the amount of stack available to the idle task.\r
+ * Defines the size, in words, of the stack allocated to the idle task.\r
*/\r
#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE\r
\r
/*\r
- * Task control block. A task control block (TCB) is allocated to each task,\r
- * and stores the context of the task.\r
+ * Task control block. A task control block (TCB) is allocated for each task,\r
+ * and stores task state information, including a pointer to the task's context\r
+ * (the task's run time environment, including register values)\r
*/\r
typedef struct tskTaskControlBlock\r
{\r
- volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE STRUCT. */\r
+ volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */\r
\r
#if ( portUSING_MPU_WRAPPERS == 1 )\r
- xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE STRUCT. */\r
- #endif \r
- \r
- xListItem xGenericListItem; /*< List item used to place the TCB in ready and blocked queues. */\r
- xListItem xEventListItem; /*< List item used to place the TCB in event lists. */\r
- unsigned portBASE_TYPE uxPriority; /*< The priority of the task where 0 is the lowest priority. */\r
+ xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */\r
+ #endif\r
+\r
+ xListItem xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */\r
+ xListItem xEventListItem; /*< Used to reference a task from an event list. */\r
+ unsigned portBASE_TYPE uxPriority; /*< The priority of the task. 0 is the lowest priority. */\r
portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */\r
signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */\r
\r
#if ( portSTACK_GROWTH > 0 )\r
- portSTACK_TYPE *pxEndOfStack; /*< Used for stack overflow checking on architectures where the stack grows up from low memory. */\r
+ portSTACK_TYPE *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */\r
#endif\r
\r
#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
- unsigned portBASE_TYPE uxCriticalNesting;\r
+ unsigned portBASE_TYPE uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */\r
#endif\r
\r
#if ( configUSE_TRACE_FACILITY == 1 )\r
- unsigned portBASE_TYPE uxTCBNumber; /*< This stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */\r
- unsigned portBASE_TYPE uxTaskNumber; /*< This stores a number specifically for use by third party trace code. */\r
+ unsigned portBASE_TYPE uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */\r
+ unsigned portBASE_TYPE uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */\r
#endif\r
\r
#if ( configUSE_MUTEXES == 1 )\r
#endif\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
- unsigned long ulRunTimeCounter; /*< Used for calculating how much CPU time each task is utilising. */\r
+ unsigned long ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */\r
#endif\r
\r
} tskTCB;\r
\r
\r
/*\r
- * Some kernel aware debuggers require data to be viewed to be global, rather\r
- * than file scope.\r
+ * Some kernel aware debuggers require the data the debugger needs access to to\r
+ * be global, rather than file scope.\r
*/\r
#ifdef portREMOVE_STATIC_QUALIFIER\r
#define static\r
PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;\r
\r
/* Lists for ready and blocked tasks. --------------------*/\r
-\r
PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */\r
PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */\r
PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */\r
#endif\r
\r
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
- \r
- PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL;\r
- \r
+\r
+ PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */\r
+\r
#endif\r
\r
/* File private variables. --------------------------------*/\r
PRIVILEGED_DATA static volatile portBASE_TYPE xMissedYield = ( portBASE_TYPE ) pdFALSE;\r
PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0;\r
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U;\r
-PRIVILEGED_DATA static portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;\r
+PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = ( portTickType ) portMAX_DELAY;\r
\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
\r
\r
/*-----------------------------------------------------------*/\r
\r
+#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 0\r
+\r
+ /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is\r
+ performed in a generic way that is not optimised to any particular\r
+ microcontroller architecture. */\r
+\r
+ /* uxTopReadyPriority holds the priority of the highest priority ready\r
+ state task. */\r
+ #define taskRECORD_READY_PRIORITY( uxPriority ) \\r
+ { \\r
+ if( ( uxPriority ) > uxTopReadyPriority ) \\r
+ { \\r
+ uxTopReadyPriority = ( uxPriority ); \\r
+ } \\r
+ } /* taskRECORD_READY_PRIORITY */\r
+\r
+ /*-----------------------------------------------------------*/\r
+\r
+ #define taskSELECT_HIGHEST_PRIORITY_TASK() \\r
+ { \\r
+ /* Find the highest priority queue that contains ready tasks. */ \\r
+ while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \\r
+ { \\r
+ configASSERT( uxTopReadyPriority ); \\r
+ --uxTopReadyPriority; \\r
+ } \\r
+ \\r
+ /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \\r
+ the same priority get an equal share of the processor time. */ \\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \\r
+ } /* taskSELECT_HIGHEST_PRIORITY_TASK */\r
+\r
+ /*-----------------------------------------------------------*/\r
+\r
+ /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as\r
+ they are only required when a port optimised method of task selection is\r
+ being used. */\r
+ #define taskRESET_READY_PRIORITY( uxPriority )\r
+ #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )\r
+\r
+#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */\r
+\r
+ /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is\r
+ performed in a way that is tailored to the particular microcontroller\r
+ architecture being used. */\r
+\r
+ /* A port optimised version is provided. Call the port defined macros. */\r
+ #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )\r
+\r
+ /*-----------------------------------------------------------*/\r
+\r
+ #define taskSELECT_HIGHEST_PRIORITY_TASK() \\r
+ { \\r
+ unsigned portBASE_TYPE uxTopPriority; \\r
+ \\r
+ /* Find the highest priority queue that contains ready tasks. */ \\r
+ portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \\r
+ configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \\r
+ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \\r
+ } /* taskSELECT_HIGHEST_PRIORITY_TASK() */\r
+\r
+ /*-----------------------------------------------------------*/\r
+\r
+ /* A port optimised version is provided, call it only if the TCB being reset\r
+ is being referenced from a ready list. If it is referenced from a delayed\r
+ or suspended list then it won't be in a ready list. */\r
+ #define taskRESET_READY_PRIORITY( uxPriority ) \\r
+ { \\r
+ if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 ) \\r
+ { \\r
+ portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \\r
+ } \\r
+ }\r
+\r
+#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */\r
+\r
/*\r
* Place the task represented by pxTCB into the appropriate ready queue for\r
* the task. It is inserted at the end of the list. One quirk of this is\r
* executing task, then it will only be rescheduled after the currently\r
* executing task has been rescheduled.\r
*/\r
-#define prvAddTaskToReadyQueue( pxTCB ) \\r
- traceMOVED_TASK_TO_READY_STATE( pxTCB ) \\r
- if( ( pxTCB )->uxPriority > uxTopReadyPriority ) \\r
- { \\r
- uxTopReadyPriority = ( pxTCB )->uxPriority; \\r
- } \\r
+#define prvAddTaskToReadyQueue( pxTCB ) \\r
+ traceMOVED_TASK_TO_READY_STATE( pxTCB ) \\r
+ taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \\r
vListInsertEnd( ( xList * ) &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
/*-----------------------------------------------------------*/\r
\r
} \\r
\\r
/* It is time to remove the item from the Blocked state. */ \\r
- vListRemove( &( pxTCB->xGenericListItem ) ); \\r
+ uxListRemove( &( pxTCB->xGenericListItem ) ); \\r
\\r
/* Is the task waiting on an event also? */ \\r
if( pxTCB->xEventListItem.pvContainer != NULL ) \\r
{ \\r
- vListRemove( &( pxTCB->xEventListItem ) ); \\r
+ uxListRemove( &( pxTCB->xEventListItem ) ); \\r
} \\r
prvAddTaskToReadyQueue( pxTCB ); \\r
} \\r
/* Callback function prototypes. --------------------------*/\r
extern void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );\r
extern void vApplicationTickHook( void );\r
- \r
+\r
/* File private functions. --------------------------------*/\r
\r
/*\r
#else\r
{\r
pxTopOfStack = pxNewTCB->pxStack;\r
- \r
+\r
/* Check the alignment of the stack buffer is correct. */\r
configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
\r
required.*/\r
*pxCreatedTask = ( xTaskHandle ) pxNewTCB;\r
}\r
- \r
+\r
/* We are going to manipulate the task queues to add this task to a\r
ready list, so must make sure no interrupts occur. */\r
taskENTER_CRITICAL();\r
This will stop the task from be scheduled. The idle task will check\r
the termination list and free up any memory allocated by the\r
scheduler for the TCB and stack. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
+ }\r
\r
/* Is the task waiting on an event also? */\r
if( pxTCB->xEventListItem.pvContainer != NULL )\r
{\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
+ uxListRemove( &( pxTCB->xEventListItem ) );\r
}\r
\r
vListInsertEnd( ( xList * ) &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) );\r
/* We must remove ourselves from the ready list before adding\r
ourselves to the blocked list as the same list item is used for\r
both lists. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is\r
+ no need to check, and the port reset macro can be called\r
+ directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
+\r
prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
}\r
/* We must remove ourselves from the ready list before adding\r
ourselves to the blocked list as the same list item is used for\r
both lists. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is\r
+ no need to check, and the port reset macro can be called\r
+ directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
xAlreadyYielded = xTaskResumeAll();\r
#endif\r
/*-----------------------------------------------------------*/\r
\r
+#if ( INCLUDE_eTaskStateGet == 1 )\r
+\r
+ eTaskState eTaskStateGet( xTaskHandle pxTask )\r
+ {\r
+ eTaskState eReturn;\r
+ xList *pxStateList;\r
+ tskTCB *pxTCB;\r
+\r
+ pxTCB = ( tskTCB * ) pxTask;\r
+\r
+ if( pxTCB == pxCurrentTCB )\r
+ {\r
+ /* The task calling this function is querying its own state. */\r
+ eReturn = eRunning;\r
+ }\r
+ else\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pxStateList = ( xList * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) );\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) )\r
+ {\r
+ /* The task being queried is referenced from one of the Blocked\r
+ lists. */\r
+ eReturn = eBlocked;\r
+ }\r
+\r
+ #if ( INCLUDE_vTaskSuspend == 1 )\r
+ else if( pxStateList == &xSuspendedTaskList )\r
+ {\r
+ /* The task being queried is referenced from the suspended\r
+ list. */\r
+ eReturn = eSuspended;\r
+ }\r
+ #endif\r
+\r
+ #if ( INCLUDE_vTaskDelete == 1 )\r
+ else if( pxStateList == &xTasksWaitingTermination )\r
+ {\r
+ /* The task being queried is referenced from the deleted\r
+ tasks list. */\r
+ eReturn = eDeleted;\r
+ }\r
+ #endif\r
+\r
+ else\r
+ {\r
+ /* If the task is not in any other state, it must be in the\r
+ Ready (including pending ready) state. */\r
+ eReturn = eReady;\r
+ }\r
+ }\r
+\r
+ return eReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
#if ( INCLUDE_uxTaskPriorityGet == 1 )\r
\r
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )\r
void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )\r
{\r
tskTCB *pxTCB;\r
- unsigned portBASE_TYPE uxCurrentPriority;\r
+ unsigned portBASE_TYPE uxCurrentPriority, uxPriorityUsedOnEntry;\r
portBASE_TYPE xYieldRequired = pdFALSE;\r
\r
configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );\r
xYieldRequired = pdTRUE;\r
}\r
\r
-\r
+ #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1\r
+ {\r
+ /* Remember the ready list the task might be referenced from\r
+ before its uxPriority member is changed so the\r
+ taskRESET_READY_PRIORITY() macro can function correctly. */\r
+ uxPriorityUsedOnEntry = pxTCB->uxPriority;\r
+ }\r
+ #endif\r
\r
#if ( configUSE_MUTEXES == 1 )\r
{\r
/* The task is currently in its ready list - remove before adding\r
it to it's new ready list. As we are in a critical section we\r
can do this even if the scheduler is suspended. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( uxPriorityUsedOnEntry );\r
+ }\r
prvAddTaskToReadyQueue( pxTCB );\r
}\r
\r
}\r
}\r
taskEXIT_CRITICAL();\r
+\r
+ /* Remove compiler warning about unused parameter when the port\r
+ optimised task selection is not being used. */\r
+ ( void ) uxPriorityUsedOnEntry;\r
}\r
\r
#endif\r
traceTASK_SUSPEND( pxTCB );\r
\r
/* Remove task from the ready/delayed list and place in the suspended list. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
+ }\r
\r
/* Is the task waiting on an event also? */\r
if( pxTCB->xEventListItem.pvContainer != NULL )\r
{\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
+ uxListRemove( &( pxTCB->xEventListItem ) );\r
}\r
\r
vListInsertEnd( ( xList * ) &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );\r
\r
/* As we are in a critical section we can access the ready\r
lists even if the scheduler is suspended. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ uxListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
\r
/* We may have just resumed a higher priority task. */\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ uxListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
}\r
else\r
macro must be defined to configure the timer/counter used to generate\r
the run time counter time base. */\r
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();\r
- \r
+\r
/* Setting up the timer tick is hardware specific and thus in the\r
portable interface. */\r
if( xPortStartScheduler() != pdFALSE )\r
}\r
/*----------------------------------------------------------*/\r
\r
+portTickType xTaskGetExpectedIdleTime( void )\r
+{\r
+portTickType xReturn;\r
+\r
+ if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY )\r
+ {\r
+ xReturn = 0;\r
+ }\r
+ else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 )\r
+ {\r
+ /* There are other idle priority tasks in the ready state. If\r
+ time slicing is used then the very next tick interrupt must be\r
+ processed. */\r
+ xReturn = 0;\r
+ }\r
+ else\r
+ {\r
+ xReturn = xNextTaskUnblockTime - xTickCount;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*----------------------------------------------------------*/\r
+\r
signed portBASE_TYPE xTaskResumeAll( void )\r
{\r
register tskTCB *pxTCB;\r
while( listLIST_IS_EMPTY( ( xList * ) &xPendingReadyList ) == pdFALSE )\r
{\r
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xPendingReadyList ) );\r
- vListRemove( &( pxTCB->xEventListItem ) );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ uxListRemove( &( pxTCB->xEventListItem ) );\r
+ uxListRemove( &( pxTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxTCB );\r
\r
/* If we have moved a task that has a priority higher than\r
/* Divide ulTotalRunTime by 100 to make the percentage caluclations\r
simpler in the prvGenerateRunTimeStatsForTasksInList() function. */\r
ulTotalRunTime /= 100UL;\r
- \r
+\r
/* Run through all the lists that could potentially contain a TCB,\r
generating a table of run timer percentages in the provided\r
buffer. */\r
configASSERT( ( xIdleTaskHandle != NULL ) );\r
return xIdleTaskHandle;\r
}\r
- \r
+\r
#endif\r
+/*----------------------------------------------------------*/\r
+\r
+void vTaskStepTick( portTickType xTicksToJump )\r
+{\r
+ configASSERT( xTicksToJump <= xNextTaskUnblockTime );\r
+ xTickCount += xTicksToJump;\r
+}\r
\r
/*-----------------------------------------------------------\r
* SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES\r
/* Called by the portable layer each time a tick interrupt occurs.\r
Increments the tick then checks to see if the new tick value will cause any\r
tasks to be unblocked. */\r
+ traceTASK_INCREMENT_TICK( xTickCount );\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
++xTickCount;\r
If there are any items in pxDelayedTaskList here then there is\r
an error! */\r
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );\r
- \r
+\r
pxTemp = pxDelayedTaskList;\r
pxDelayedTaskList = pxOverflowDelayedTaskList;\r
pxOverflowDelayedTaskList = pxTemp;\r
xNumOfOverflows++;\r
- \r
+\r
if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )\r
{\r
/* The new current delayed list is empty. Set\r
xNextTaskUnblockTime to the maximum possible value so it is\r
- extremely unlikely that the \r
+ extremely unlikely that the\r
if( xTickCount >= xNextTaskUnblockTime ) test will pass until\r
there is an item in the delayed list. */\r
xNextTaskUnblockTime = portMAX_DELAY;\r
}\r
}\r
#endif\r
-\r
- traceTASK_INCREMENT_TICK( xTickCount );\r
}\r
/*-----------------------------------------------------------*/\r
\r
else\r
{\r
traceTASK_SWITCHED_OUT();\r
- \r
+\r
#if ( configGENERATE_RUN_TIME_STATS == 1 )\r
{\r
unsigned long ulTempCounter;\r
- \r
+\r
#ifdef portALT_GET_RUN_TIME_COUNTER_VALUE\r
portALT_GET_RUN_TIME_COUNTER_VALUE( ulTempCounter );\r
#else\r
ulTempCounter = portGET_RUN_TIME_COUNTER_VALUE();\r
#endif\r
- \r
+\r
/* Add the amount of time the task has been running to the accumulated\r
time so far. The time the task started running was stored in\r
ulTaskSwitchedInTime. Note that there is no overflow protection here\r
ulTaskSwitchedInTime = ulTempCounter;\r
}\r
#endif\r
- \r
+\r
taskFIRST_CHECK_FOR_STACK_OVERFLOW();\r
taskSECOND_CHECK_FOR_STACK_OVERFLOW();\r
- \r
- /* Find the highest priority queue that contains ready tasks. */\r
- while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) )\r
- {\r
- configASSERT( uxTopReadyPriority );\r
- --uxTopReadyPriority;\r
- }\r
- \r
- /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the\r
- same priority get an equal share of the processor time. */\r
- listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\r
- \r
+\r
+ taskSELECT_HIGHEST_PRIORITY_TASK();\r
+\r
traceTASK_SWITCHED_IN();\r
}\r
}\r
/* We must remove ourselves from the ready list before adding ourselves\r
to the blocked list as the same list item is used for both lists. We have\r
exclusive access to the ready lists as the scheduler is locked. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
-\r
+ if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is no need to\r
+ check, and the port reset macro can be called directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
\r
#if ( INCLUDE_vTaskSuspend == 1 )\r
{\r
designed for use by kernel code, and has special calling requirements -\r
it should be called from a critical section. */\r
\r
- \r
+\r
/* Place the event list item of the TCB in the appropriate event list.\r
In this case it is assume that this is the only task that is going to\r
be waiting on this event list, so the faster vListInsertEnd() function\r
/* We must remove this task from the ready list before adding it to the\r
blocked list as the same list item is used for both lists. This\r
function is called form a critical section. */\r
- vListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxCurrentTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ /* The current task must be in a ready list, so there is no need to\r
+ check, and the port reset macro can be called directly. */\r
+ portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority );\r
+ }\r
\r
/* Calculate the time at which the task should be woken if the event does\r
not occur. This may overflow but this doesn't matter. */\r
xTimeToWake = xTickCount + xTicksToWait;\r
prvAddCurrentTaskToDelayedList( xTimeToWake );\r
}\r
- \r
+\r
#endif /* configUSE_TIMERS */\r
/*-----------------------------------------------------------*/\r
\r
If an event is for a queue that is locked then this function will never\r
get called - the lock count on the queue will get modified instead. This\r
means we can always expect exclusive access to the event list here.\r
- \r
+\r
This function assumes that a check has already been made to ensure that\r
pxEventList is not empty. */\r
pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );\r
configASSERT( pxUnblockedTCB );\r
- vListRemove( &( pxUnblockedTCB->xEventListItem ) );\r
+ uxListRemove( &( pxUnblockedTCB->xEventListItem ) );\r
\r
if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
{\r
- vListRemove( &( pxUnblockedTCB->xGenericListItem ) );\r
+ uxListRemove( &( pxUnblockedTCB->xGenericListItem ) );\r
prvAddTaskToReadyQueue( pxUnblockedTCB );\r
}\r
else\r
{\r
unsigned portBASE_TYPE uxReturn;\r
tskTCB *pxTCB;\r
- \r
+\r
if( xTask != NULL )\r
{\r
pxTCB = ( tskTCB * ) xTask;\r
{\r
uxReturn = 0U;\r
}\r
- \r
+\r
return uxReturn;\r
}\r
#endif\r
void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle )\r
{\r
tskTCB *pxTCB;\r
- \r
+\r
if( xTask != NULL )\r
{\r
pxTCB = ( tskTCB * ) xTask;\r
vApplicationIdleHook();\r
}\r
#endif\r
+\r
+ #if ( configUSE_TICKLESS_IDLE == 1 )\r
+ {\r
+ portTickType xExpectedIdleTime;\r
+ /* If the expected idle time is 1 then the idle time would end at\r
+ the end of the current time slice. The idle time must be at least\r
+ 2 to ensure any pended ticks between this point and the tick being\r
+ stopped can be legitimately stepped over when the tick suppression\r
+ routines returns. */\r
+ const portTickType xMinimumExpectedIdleTime = ( portTickType ) 2;\r
+\r
+ /* Don't enter low power if there are still tasks waiting\r
+ deletion. */\r
+ if( uxTasksDeleted == 0 )\r
+ {\r
+ /* It is not desirable to suspend then resume the scheduler on\r
+ each iteration of the idle task. Therefore, a preliminary\r
+ test of the expected idle time is performed without the\r
+ scheduler suspended. The result here is not necessarily\r
+ valid. */\r
+ xExpectedIdleTime = xTaskGetExpectedIdleTime();\r
+\r
+ if( xExpectedIdleTime >= xMinimumExpectedIdleTime )\r
+ {\r
+ vTaskSuspendAll();\r
+ {\r
+ /* Now the scheduler is suspended, the expected idle\r
+ time can be sampled again, and this time its value can\r
+ be used. */\r
+ configASSERT( xNextTaskUnblockTime >= xTickCount );\r
+ xExpectedIdleTime = xTaskGetExpectedIdleTime();\r
+\r
+ if( xExpectedIdleTime >= xMinimumExpectedIdleTime )\r
+ {\r
+ portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );\r
+ }\r
+ }\r
+ xTaskResumeAll();\r
+ }\r
+ }\r
+ }\r
+ #endif\r
}\r
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */\r
\r
void vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions )\r
{\r
tskTCB *pxTCB;\r
- \r
+\r
if( xTaskToModify == pxCurrentTCB )\r
{\r
xTaskToModify = NULL;\r
taskENTER_CRITICAL();\r
{\r
pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( ( xList * ) &xTasksWaitingTermination ) );\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ uxListRemove( &( pxTCB->xGenericListItem ) );\r
--uxCurrentNumberOfTasks;\r
--uxTasksDeleted;\r
}\r
{\r
usStackRemaining = usTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack );\r
}\r
- #endif \r
- \r
+ #endif\r
+\r
sprintf( pcStatusString, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxNextTCB->pcTaskName, cStatus, ( unsigned int ) pxNextTCB->uxPriority, usStackRemaining, ( unsigned int ) pxNextTCB->uxTCBNumber );\r
strcat( ( char * ) pcWriteBuffer, ( char * ) pcStatusString );\r
\r
{\r
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
{\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage ); \r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter, ulStatsAsPercentage );\r
}\r
#else\r
{\r
consumed less than 1% of the total run time. */\r
#ifdef portLU_PRINTF_SPECIFIER_REQUIRED\r
{\r
- sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter ); \r
+ sprintf( pcStatsString, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxNextTCB->pcTaskName, pxNextTCB->ulRunTimeCounter );\r
}\r
#else\r
{\r
{\r
tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
\r
- configASSERT( pxMutexHolder );\r
-\r
- if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
+ /* If the mutex was given back by an interrupt while the queue was\r
+ locked then the mutex holder might now be NULL. */\r
+ if( pxMutexHolder != NULL )\r
{\r
- /* Adjust the mutex holder state to account for its new priority. */\r
- listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
-\r
- /* If the task being modified is in the ready state it will need to\r
- be moved in to a new list. */\r
- if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
{\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ /* Adjust the mutex holder state to account for its new priority. */\r
+ listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
\r
- /* Inherit the priority before being moved into the new list. */\r
- pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
- prvAddTaskToReadyQueue( pxTCB );\r
- }\r
- else\r
- {\r
- /* Just inherit the priority. */\r
- pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
- }\r
+ /* If the task being modified is in the ready state it will need to\r
+ be moved into a new list. */\r
+ if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
+ {\r
+ if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
+ }\r
+\r
+ /* Inherit the priority before being moved into the new list. */\r
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+ prvAddTaskToReadyQueue( pxTCB );\r
+ }\r
+ else\r
+ {\r
+ /* Just inherit the priority. */\r
+ pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+ }\r
\r
- traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );\r
+ traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );\r
+ }\r
}\r
}\r
\r
{\r
/* We must be the running task to be able to give the mutex back.\r
Remove ourselves from the ready list we currently appear in. */\r
- vListRemove( &( pxTCB->xGenericListItem ) );\r
+ if( uxListRemove( ( xListItem * ) &( pxTCB->xGenericListItem ) ) == 0 )\r
+ {\r
+ taskRESET_READY_PRIORITY( pxTCB->uxPriority );\r
+ }\r
\r
/* Disinherit the priority before adding the task into the new\r
ready list. */\r
\r
#if ( portCRITICAL_NESTING_IN_TCB == 1 )\r
\r
-void vTaskExitCritical( void )\r
-{\r
- if( xSchedulerRunning != pdFALSE )\r
+ void vTaskExitCritical( void )\r
{\r
- if( pxCurrentTCB->uxCriticalNesting > 0U )\r
+ if( xSchedulerRunning != pdFALSE )\r
{\r
- ( pxCurrentTCB->uxCriticalNesting )--;\r
-\r
- if( pxCurrentTCB->uxCriticalNesting == 0U )\r
+ if( pxCurrentTCB->uxCriticalNesting > 0U )\r
{\r
- portENABLE_INTERRUPTS();\r
+ ( pxCurrentTCB->uxCriticalNesting )--;\r
+\r
+ if( pxCurrentTCB->uxCriticalNesting == 0U )\r
+ {\r
+ portENABLE_INTERRUPTS();\r
+ }\r
}\r
}\r
}\r
-}\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TICKLESS_IDLE == 1 )\r
+\r
+ unsigned portBASE_TYPE uxTaskPendingTicksGet( portBASE_TYPE xResetOnExit )\r
+ {\r
+ unsigned portBASE_TYPE uxReturn;\r
+\r
+ uxReturn = uxMissedTicks;\r
+\r
+ if( xResetOnExit == pdTRUE )\r
+ {\r
+ uxMissedTicks = 0;\r
+ }\r
+\r
+ return uxReturn;\r
+ }\r
\r
#endif\r
/*-----------------------------------------------------------*/\r
FreeRTOS WEB site.\r
\r
1 tab == 4 spaces!\r
- \r
+\r
***************************************************************************\r
* *\r
* Having a problem? Start by reading the FAQ "My application does *\r
* *\r
***************************************************************************\r
\r
- \r
- http://www.FreeRTOS.org - Documentation, training, latest information, \r
+\r
+ http://www.FreeRTOS.org - Documentation, training, latest information,\r
license and contact details.\r
- \r
+\r
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
including FreeRTOS+Trace - an indispensable productivity tool.\r
\r
- Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell \r
- the code with commercial support, indemnification, and middleware, under \r
+ Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
+ the code with commercial support, indemnification, and middleware, under\r
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also\r
- provide a safety engineered and independently SIL3 certified version under \r
+ provide a safety engineered and independently SIL3 certified version under\r
the SafeRTOS brand: http://www.SafeRTOS.com.\r
*/\r
\r
PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;\r
\r
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )\r
- \r
+\r
PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;\r
- \r
+\r
#endif\r
\r
/*-----------------------------------------------------------*/\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, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle ); \r
+ xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );\r
}\r
#else\r
{\r
/* Ensure the infrastructure used by the timer service task has been\r
created/initialised. */\r
prvCheckForValidListAndQueue();\r
- \r
+\r
/* Initialise the timer structure members using the function parameters. */\r
pxNewTimer->pcTimerName = pcTimerName;\r
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;\r
pxNewTimer->pvTimerID = pvTimerID;\r
pxNewTimer->pxCallbackFunction = pxCallbackFunction;\r
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );\r
- \r
+\r
traceTIMER_CREATE( pxNewTimer );\r
}\r
else\r
traceTIMER_CREATE_FAILED();\r
}\r
}\r
- \r
+\r
return ( xTimerHandle ) pxNewTimer;\r
}\r
/*-----------------------------------------------------------*/\r
{\r
xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );\r
}\r
- \r
+\r
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );\r
}\r
- \r
+\r
return xReturn;\r
}\r
/*-----------------------------------------------------------*/\r
configASSERT( ( xTimerTaskHandle != NULL ) );\r
return xTimerTaskHandle;\r
}\r
- \r
+\r
#endif\r
/*-----------------------------------------------------------*/\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
- vListRemove( &( pxTimer->xTimerListItem ) );\r
+ uxListRemove( &( pxTimer->xTimerListItem ) );\r
traceTIMER_EXPIRED( pxTimer );\r
\r
/* If the timer is an auto reload timer then calculate the next\r
/* If a timer has expired, process it. Otherwise, block this task\r
until either a timer does expire, or a command is received. */\r
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );\r
- \r
+\r
/* Empty the command queue. */\r
- prvProcessReceivedCommands(); \r
+ prvProcessReceivedCommands();\r
}\r
}\r
/*-----------------------------------------------------------*/\r
PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U;\r
\r
xTimeNow = xTaskGetTickCount();\r
- \r
+\r
if( xTimeNow < xLastTime )\r
{\r
prvSwitchTimerLists( xLastTime );\r
{\r
*pxTimerListsWereSwitched = pdFALSE;\r
}\r
- \r
+\r
xLastTime = xTimeNow;\r
- \r
+\r
return xTimeNow;\r
}\r
/*-----------------------------------------------------------*/\r
\r
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );\r
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );\r
- \r
+\r
if( xNextExpiryTime <= xTimeNow )\r
{\r
/* Has the expiry time elapsed between the command to start/reset a\r
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )\r
{\r
/* The timer is in a list, remove it. */\r
- vListRemove( &( pxTimer->xTimerListItem ) );\r
+ uxListRemove( &( pxTimer->xTimerListItem ) );\r
}\r
}\r
\r
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );\r
- \r
+\r
switch( xMessage.xMessageID )\r
{\r
- case tmrCOMMAND_START : \r
+ case tmrCOMMAND_START :\r
/* Start or restart a timer. */\r
if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )\r
{\r
}\r
break;\r
\r
- case tmrCOMMAND_STOP : \r
+ case tmrCOMMAND_STOP :\r
/* The timer has already been removed from the active list.\r
There is nothing to do here. */\r
break;\r
vPortFree( pxTimer );\r
break;\r
\r
- default : \r
+ default :\r
/* Don't expect to get here. */\r
break;\r
}\r
\r
/* Remove compiler warnings if configASSERT() is not defined. */\r
( void ) xLastTime;\r
- \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
then they must have expired and should be processed before the lists\r
\r
/* Remove the timer from the list. */\r
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );\r
- vListRemove( &( pxTimer->xTimerListItem ) );\r
+ uxListRemove( &( pxTimer->xTimerListItem ) );\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