/*\r
-    FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+    FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
 \r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\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
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that has become a de facto standard.             *\r
      *                                                                       *\r
-     *    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
+     *    Help yourself get started quickly and support the FreeRTOS         *\r
+     *    project by purchasing a FreeRTOS tutorial book, reference          *\r
+     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
      *                                                                       *\r
-     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
-     *                                                                       *\r
-     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *    Thank you!                                                         *\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
+    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+    >>! NOTE: The modification to the GPL is included to allow you to distribute\r
+    >>! a combined work that includes FreeRTOS without being obliged to provide\r
+    >>! the source code for proprietary components outside of the FreeRTOS\r
+    >>! kernel.\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
+    link: http://www.freertos.org/a00114.html\r
 \r
     1 tab == 4 spaces!\r
 \r
-    http://www.FreeRTOS.org - Documentation, latest information, license and\r
-    contact details.\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    Having a problem?  Start by reading the FAQ "My application does   *\r
+     *    not run, what could be wrong?"                                     *\r
+     *                                                                       *\r
+     *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+    license and Real Time Engineers Ltd. contact details.\r
 \r
-    http://www.SafeRTOS.com - A version that is certified for use in safety\r
-    critical systems.\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
 \r
-    http://www.OpenRTOS.com - Commercial support, development, porting,\r
-    licensing and training services.\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
 */\r
 \r
 /* Standard includes. */\r
 
  *\r
  */\r
 \r
-/*\r
-\r
-Changes from V4.1.1\r
-\r
-       + The second set of tasks were created the wrong way around.  This has been\r
-         corrected.\r
-*/\r
-\r
-\r
 #include <stdlib.h>\r
 \r
 /* Scheduler include files. */\r
 
 unsigned long ulReceived;\r
 xQueueHandle xActivatedQueue;\r
 \r
+       /* Remove compiler warnings. */\r
+       ( void ) pvParameters;\r
+\r
        /* Create the queues and add them to the queue set before resuming the Tx\r
        task. */\r
        prvSetupTest();\r
 
  */\r
 static void prvDemonstrateTaskStateAndHandleGetFunctions( void );\r
 \r
+/*\r
+ * A task to demonstrate the use of the xQueueSpacesAvailable() function.\r
+ */\r
+static void prvDemoQueueSpaceFunctions( void *pvParameters );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* The variable into which error messages are latched. */\r
        vStartCountingSemaphoreTasks();\r
        vStartDynamicPriorityTasks();\r
        vStartQueueSetTasks();\r
-       vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );\r
+       vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );       \r
+       xTaskCreate( prvDemoQueueSpaceFunctions, ( signed char * ) "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
 \r
        /* The suicide tasks must be created last as they need to know how many\r
        tasks were running prior to their creation.  This then allows them to \r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvDemoQueueSpaceFunctions( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = NULL;\r
+const unsigned portBASE_TYPE uxQueueLength = 10;\r
+unsigned portBASE_TYPE uxReturn, x;\r
+\r
+       /* Remove compiler warnings. */\r
+       ( void ) pvParameters;\r
+\r
+       /* Create the queue that will be used.  Nothing is actually going to be\r
+       sent or received so the queue item size is set to 0. */\r
+       xQueue = xQueueCreate( uxQueueLength, 0 );\r
+       configASSERT( xQueue );\r
+\r
+       for( ;; )\r
+       {\r
+               for( x = 0; x < uxQueueLength; x++ )\r
+               {\r
+                       /* Ask how many messages are available... */\r
+                       uxReturn = uxQueueMessagesWaiting( xQueue );\r
+                       \r
+                       /* Check the number of messages being reported as being available\r
+                       is as expected, and force an assert if not. */\r
+                       if( uxReturn != x )\r
+                       {\r
+                               /* xQueue cannot be NULL so this is deliberately causing an\r
+                               assert to be triggered as there is an error. */\r
+                               configASSERT( xQueue == NULL );\r
+                       }\r
+\r
+                       /* Ask how many spaces remain in the queue... */\r
+                       uxReturn = uxQueueSpacesAvailable( xQueue );\r
+                       \r
+                       /* Check the number of spaces being reported as being available\r
+                       is as expected, and force an assert if not. */\r
+                       if( uxReturn != ( uxQueueLength - x ) )\r
+                       {\r
+                               /* xQueue cannot be NULL so this is deliberately causing an\r
+                               assert to be triggered as there is an error. */\r
+                               configASSERT( xQueue == NULL );\r
+                       }\r
+\r
+                       /* Fill one more space in the queue. */\r
+                       xQueueSendToBack( xQueue, NULL, 0 );\r
+               }\r
+\r
+               /* Perform the same check while the queue is full. */\r
+               uxReturn = uxQueueMessagesWaiting( xQueue );\r
+               if( uxReturn != uxQueueLength )\r
+               {\r
+                       configASSERT( xQueue == NULL );\r
+               }\r
+\r
+               uxReturn = uxQueueSpacesAvailable( xQueue );\r
+                       \r
+               if( uxReturn != 0 )\r
+               {\r
+                       configASSERT( xQueue == NULL );\r
+               }\r
+\r
+               /* The queue is full, start again. */\r
+               xQueueReset( xQueue );\r
+       }\r
+}\r
+\r
 \r
 
        #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )\r
 #endif\r
 \r
+#ifndef traceMALLOC\r
+    #define traceMALLOC( pvAddress, uiSize )\r
+#endif\r
+\r
+#ifndef traceFREE\r
+    #define traceFREE( pvAddress, uiSize )\r
+#endif\r
+\r
 #ifndef configGENERATE_RUN_TIME_STATS\r
        #define configGENERATE_RUN_TIME_STATS 0\r
 #endif\r
 
  */\r
 static void vPortStartFirstTask( void ) __attribute__ (( naked ));\r
 \r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
        *pxTopOfStack = portINITIAL_XPSR;       /* xPSR */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
-       pxTopOfStack -= 6;      /* LR, R12, R3..R1 */\r
+       pxTopOfStack--;\r
+       *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError;    /* LR */\r
+       pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
        pxTopOfStack -= 8; /* R11..R4. */\r
 \r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvTaskExitError( void )\r
+{\r
+       /* A function that implements a task must not exit or attempt to return to\r
+       its caller as there is nothing to return to.  If a task wants to exit it \r
+       should instead call vTaskDelete( NULL ).\r
+       \r
+       Artificially force an assert() to be triggered if configASSERT() is \r
+       defined, then stop here so application writers can catch the error. */\r
+       configASSERT( uxCriticalNesting == ~0UL );\r
+       portDISABLE_INTERRUPTS();       \r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 void vPortSVCHandler( void )\r
 {\r
        __asm volatile (\r
                                        " msr PRIMASK, r0       \n"\r
                                        " bx lr                           "\r
                                  );\r
+                                 \r
+       /* Just to avoid compiler warning. */\r
+       ( void ) ulMask;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 
  */\r
 extern void vPortStartFirstTask( void );\r
 \r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
        *pxTopOfStack = portINITIAL_XPSR;       /* xPSR */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
-       pxTopOfStack -= 6;      /* LR, R12, R3..R1 */\r
+       pxTopOfStack--;\r
+       *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError;    /* LR */\r
+       pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
        pxTopOfStack -= 8; /* R11..R4. */\r
 \r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvTaskExitError( void )\r
+{\r
+       /* A function that implements a task must not exit or attempt to return to\r
+       its caller as there is nothing to return to.  If a task wants to exit it \r
+       should instead call vTaskDelete( NULL ).\r
+       \r
+       Artificially force an assert() to be triggered if configASSERT() is \r
+       defined, then stop here so application writers can catch the error. */\r
+       configASSERT( uxCriticalNesting == ~0UL );\r
+       portDISABLE_INTERRUPTS();       \r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 /*\r
  * See header file for description.\r
  */\r
 
  */\r
 static void prvPortStartFirstTask( void );\r
 \r
+/*\r
+ * Used to catch tasks that attempt to return from their implementing function.\r
+ */\r
+static void prvTaskExitError( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
        *pxTopOfStack = portINITIAL_XPSR;       /* xPSR */\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
-       pxTopOfStack -= 6;      /* LR, R12, R3..R1 */\r
+       pxTopOfStack--;\r
+       *pxTopOfStack = ( portSTACK_TYPE ) prvTaskExitError;    /* LR */\r
+       pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
        pxTopOfStack -= 8; /* R11..R4. */\r
 \r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvTaskExitError( void )\r
+{\r
+       /* A function that implements a task must not exit or attempt to return to\r
+       its caller as there is nothing to return to.  If a task wants to exit it \r
+       should instead call vTaskDelete( NULL ).\r
+       \r
+       Artificially force an assert() to be triggered if configASSERT() is \r
+       defined, then stop here so application writers can catch the error. */\r
+       configASSERT( uxCriticalNesting == ~0UL );\r
+       portDISABLE_INTERRUPTS();       \r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 __asm void vPortSVCHandler( void )\r
 {\r
        extern pxCurrentTCB;\r
 
        uxTaskGetSystemState() function.  Note the formatting functions are provided\r
        for convenience only, and are NOT considered part of the kernel. */\r
        #include <stdio.h>\r
-#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */\r
+#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */\r
 \r
 /* Sanity check the configuration. */\r
 #if configUSE_TICKLESS_IDLE != 0\r
 \r
                                if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE )\r
                                {\r
-                                       xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority );\r
+                                       if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
+                                       {\r
+                                               xYieldRequired = pdTRUE;\r
+                                       }\r
+\r
                                        ( void ) uxListRemove(  &( pxTCB->xGenericListItem ) );\r
                                        prvAddTaskToReadyList( pxTCB );\r
                                }\r
                before or during the call to xPortStartScheduler().  The stacks of\r
                the created tasks contain a status word with interrupts switched on\r
                so interrupts will automatically get re-enabled when the first task\r
-               starts to run.\r
-\r
-               STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE\r
-               DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */\r
+               starts to run. */\r
                portDISABLE_INTERRUPTS();\r
 \r
+               #if ( configUSE_NEWLIB_REENTRANT == 1 )\r
+               {\r
+                       /* Switch Newlib's _impure_ptr variable to point to the _reent\r
+                       structure specific to the task that will run first. */\r
+                       _impure_ptr = &( pxCurrentTCB->xNewLib_reent );\r
+               }\r
+               #endif /* configUSE_NEWLIB_REENTRANT */\r
+\r
                xSchedulerRunning = pdTRUE;\r
                xTickCount = ( portTickType ) 0U;\r
 \r
 {\r
 tskTCB *pxTCB;\r
 portBASE_TYPE xAlreadyYielded = pdFALSE;\r
-portBASE_TYPE xYieldRequired = pdFALSE;\r
 \r
        /* If uxSchedulerSuspended is zero then this function does not match a\r
        previous call to vTaskSuspendAll(). */\r
                                        the current task then we should yield. */\r
                                        if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )\r
                                        {\r
-                                               xYieldRequired = pdTRUE;\r
+                                               xYieldPending = pdTRUE;\r
                                        }\r
                                }\r
 \r
                                        {\r
                                                if( xTaskIncrementTick() != pdFALSE )\r
                                                {\r
-                                                       xYieldRequired = pdTRUE;\r
+                                                       xYieldPending = pdTRUE;\r
                                                }\r
                                                --uxPendedTicks;\r
                                        }\r
                                }\r
 \r
-                               if( ( xYieldRequired == pdTRUE ) || ( xYieldPending == pdTRUE ) )\r
+                               if( xYieldPending == pdTRUE )\r
                                {\r
                                        xAlreadyYielded = pdTRUE;\r
-                                       xYieldPending = pdFALSE;\r
                                        portYIELD_WITHIN_API();\r
                                }\r
                        }\r
                                                        portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) );\r
                                                #else\r
                                                        *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE();\r
-                                               #endif                                  \r
+                                               #endif\r
                                        }\r
                                }\r
                                #else\r
                        }\r
                }\r
                #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */\r
+               \r
+               #if ( configUSE_TICK_HOOK == 1 )\r
+               {\r
+                       /* Guard against the tick hook being called when the pended tick\r
+                       count is being unwound (when the scheduler is being unlocked). */\r
+                       if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U )\r
+                       {\r
+                               vApplicationTickHook();\r
+                       }\r
+               }\r
+               #endif /* configUSE_TICK_HOOK */                \r
        }\r
        else\r
        {\r
                #endif\r
        }\r
 \r
-       #if ( configUSE_TICK_HOOK == 1 )\r
+       #if ( configUSE_PREEMPTION == 1 )\r
        {\r
-               /* Guard against the tick hook being called when the missed tick\r
-               count is being unwound (when the scheduler is being unlocked). */\r
-               if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U )\r
+               if( xYieldPending != pdFALSE )\r
                {\r
-                       vApplicationTickHook();\r
+                       xSwitchRequired = pdTRUE;\r
                }\r
        }\r
-       #endif /* configUSE_TICK_HOOK */\r
+       #endif /* configUSE_PREEMPTION */\r
 \r
        return xSwitchRequired;\r
 }\r
        }\r
        else\r
        {\r
+               xYieldPending = pdFALSE;\r
                traceTASK_SWITCHED_OUT();\r
 \r
                #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
                the calling task to know if it should force a context\r
                switch now. */\r
                xReturn = pdTRUE;\r
+\r
+               /* Mark that a yield is pending in case the user is not using the\r
+               "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */\r
+               xYieldPending = pdTRUE;\r
        }\r
        else\r
        {\r
 
                        case tmrCOMMAND_CHANGE_PERIOD :\r
                                pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;\r
                                configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );\r
+\r
+                               /* The new period does not really have a reference, and can be\r
+                               longer or shorter than the old one.  The command time is \r
+                               therefore set to the current time, and as the period cannot be\r
+                               zero the next expiry time can only be in the future, meaning\r
+                               (unlike for the xTimerStart() case above) there is no fail case\r
+                               that needs to be handled here. */\r
                                ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );\r
                                break;\r
 \r