]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/WIN32-MSVC/main.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / WIN32-MSVC / main.c
index 73222836eb84f4657dce8c443ffcbc923d3e3301..b90548741c6bf75209369f41b81dd480e52551b8 100644 (file)
 /*\r
-    FreeRTOS V7.1.1 - 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
- *******************************************************************************\r
- * -NOTE- The Win32 port is a simulation (or is that emulation?) only!  Do not\r
- * expect to get real time behaviour from the Win32 port or this demo\r
- * application.  It is provided as a convenient development and demonstration\r
- * test bed only.  This was tested using Windows XP on a dual core laptop.\r
+ * FreeRTOS Kernel V10.0.0\r
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
- * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -\r
- *******************************************************************************\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
  *\r
- * main() creates all the demo application tasks, then starts the scheduler.  \r
- * The web documentation provides more details of the standard demo application \r
- * tasks, which provide no particular functionality but do provide a good \r
- * example of how to use the FreeRTOS API.\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software. If you wish to use our Amazon\r
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
  *\r
- * In addition to the standard demo tasks, the following tasks and tests are\r
- * defined and/or created within this file:\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
  *\r
- * "Check" task - This only executes every five seconds but has a high priority\r
- * to ensure it gets processor time.  Its main function is to check that all the\r
- * standard demo tasks are still operational.  While no errors have been\r
- * discovered the check task will print out "OK" and the current simulated tick\r
- * time.  If an error is discovered in the execution of a task then the check\r
- * task will print out an appropriate error message.\r
+ * http://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
  *\r
+ * 1 tab == 4 spaces!\r
  */\r
 \r
+/******************************************************************************\r
+ * This project provides two demo applications.  A simple blinky style project,\r
+ * and a more comprehensive test and demo application.  The\r
+ * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.\r
+ * The simply blinky demo is implemented and described in main_blinky.c.  The\r
+ * more comprehensive test and demo application is implemented and described in\r
+ * main_full.c.\r
+ *\r
+ * This file implements the code that is not demo specific, including the\r
+ * hardware setup and FreeRTOS hook functions.\r
+ *\r
+ *******************************************************************************\r
+ * NOTE: Windows will not be running the FreeRTOS demo threads continuously, so\r
+ * do not expect to get real time behaviour from the FreeRTOS Windows port, or\r
+ * this demo application.  Also, the timing information in the FreeRTOS+Trace\r
+ * logs have no meaningful units.  See the documentation page for the Windows\r
+ * port for further information:\r
+ * http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html\r
+ *\r
+\r
+ *\r
+ *******************************************************************************\r
+ */\r
 \r
 /* Standard includes. */\r
 #include <stdio.h>\r
+#include <stdlib.h>\r
+#include <conio.h>\r
 \r
-/* Kernel includes. */\r
-#include <FreeRTOS.h>\r
+/* FreeRTOS kernel includes. */\r
+#include "FreeRTOS.h"\r
 #include "task.h"\r
-#include "queue.h"\r
-#include "timers.h"\r
-#include "semphr.h"\r
-\r
-/* Standard demo includes. */\r
-#include "BlockQ.h"\r
-#include "integer.h"\r
-#include "semtest.h"\r
-#include "PollQ.h"\r
-#include "GenQTest.h"\r
-#include "QPeek.h"\r
-#include "recmutex.h"\r
-#include "flop.h"\r
-#include "TimerDemo.h"\r
-#include "countsem.h"\r
-#include "death.h"\r
-#include "dynamic.h"\r
-\r
-/* Priorities at which the tasks are created. */\r
-#define mainCHECK_TASK_PRIORITY                ( configMAX_PRIORITIES - 1 )\r
-#define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
-#define mainSEM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
-#define mainBLOCK_Q_PRIORITY           ( tskIDLE_PRIORITY + 2 )\r
-#define mainCREATOR_TASK_PRIORITY   ( tskIDLE_PRIORITY + 3 )\r
-#define mainFLASH_TASK_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
-#define mainuIP_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
-#define mainINTEGER_TASK_PRIORITY   ( tskIDLE_PRIORITY )\r
-#define mainGEN_QUEUE_TASK_PRIORITY    ( tskIDLE_PRIORITY )\r
-#define mainFLOP_TASK_PRIORITY         ( tskIDLE_PRIORITY )\r
-\r
-#define mainTIMER_TEST_PERIOD                  ( 50 )\r
-\r
-/* Task function prototypes. */\r
-static void prvCheckTask( void *pvParameters );\r
-\r
-/* The variable into which error messages are latched. */\r
-static char *pcStatusMessage = "OK";\r
-\r
-/* This semaphore is created purely to test using the vSemaphoreDelete() and\r
-semaphore tracing API functions.  It has no other purpose. */\r
-static xSemaphoreHandle xMutexToDelete = NULL;\r
+\r
+/* This project provides two demo applications.  A simple blinky style demo\r
+application, and a more comprehensive test and demo application.  The\r
+mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is used to select between the two.\r
+\r
+If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is 1 then the blinky demo will be built.\r
+The blinky demo is implemented and described in main_blinky.c.\r
+\r
+If mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is not 1 then the comprehensive test and\r
+demo application will be built.  The comprehensive test and demo application is\r
+implemented and described in main_full.c. */\r
+#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY     0\r
+\r
+/* This demo uses heap_5.c, and these constants define the sizes of the regions\r
+that make up the total heap.  heap_5 is only used for test and example purposes\r
+as this demo could easily create one large heap region instead of multiple\r
+smaller heap regions - in which case heap_4.c would be the more appropriate\r
+choice.  See http://www.freertos.org/a00111.html for an explanation. */\r
+#define mainREGION_1_SIZE      7201\r
+#define mainREGION_2_SIZE      29905\r
+#define mainREGION_3_SIZE      6407\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.\r
+ * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.\r
+ */\r
+extern void main_blinky( void );\r
+extern void main_full( void );\r
+\r
+/*\r
+ * Only the comprehensive demo uses application hook (callback) functions.  See\r
+ * http://www.freertos.org/a00016.html for more information.\r
+ */\r
+void vFullDemoTickHookFunction( void );\r
+void vFullDemoIdleFunction( void );\r
+\r
+/*\r
+ * This demo uses heap_5.c, so start by defining some heap regions.  It is not\r
+ * necessary for this demo to use heap_5, as it could define one large heap\r
+ * region.  Heap_5 is only used for test and example purposes.  See\r
+ * http://www.freertos.org/a00111.html for an explanation.\r
+ */\r
+static void  prvInitialiseHeap( void );\r
+\r
+/*\r
+ * Prototypes for the standard FreeRTOS application hook (callback) functions\r
+ * implemented within this file.  See http://www.freertos.org/a00016.html .\r
+ */\r
+void vApplicationMallocFailedHook( void );\r
+void vApplicationIdleHook( void );\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );\r
+void vApplicationTickHook( void );\r
+void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );\r
+void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );\r
+\r
+/*\r
+ * Writes trace data to a disk file when the trace recording is stopped.\r
+ * This function will simply overwrite any trace files that already exist.\r
+ */\r
+static void prvSaveTraceFile( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can\r
+use a callback function to optionally provide the memory required by the idle\r
+and timer tasks.  This is the stack that will be used by the timer task.  It is\r
+declared here, as a global, so it can be checked by a test that is implemented\r
+in a different file. */\r
+StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];\r
+\r
+/* Notes if the trace is running or not. */\r
+static BaseType_t xTraceRunning = pdTRUE;\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
 int main( void )\r
 {\r
-       /* Start the check task as described at the top of this file. */\r
-       xTaskCreate( prvCheckTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
-\r
-       /* Create the standard demo tasks. */\r
-       vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
-       vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
-       vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
-       vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );\r
-       vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
-       vStartQueuePeekTasks();\r
-       vStartMathTasks( mainFLOP_TASK_PRIORITY );\r
-       vStartRecursiveMutexTasks();\r
-       vStartTimerDemoTask( mainTIMER_TEST_PERIOD );\r
-       vStartCountingSemaphoreTasks();\r
-       vStartDynamicPriorityTasks();\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
-       ascertain whether or not the correct/expected number of tasks are running at \r
-       any given time. */\r
-       vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );\r
-\r
-       /* Create the semaphore that will be deleted in the idle task hook.  This\r
-       is done purely to test the use of vSemaphoreDelete(). */\r
-       xMutexToDelete = xSemaphoreCreateMutex();\r
-\r
-       /* Start the scheduler itself. */\r
-       vTaskStartScheduler();\r
-\r
-    /* Should never get here unless there was not enough heap space to create \r
-       the idle and other system tasks. */\r
-    return 0;\r
+       /* This demo uses heap_5.c, so start by defining some heap regions.  heap_5\r
+       is only used for test and example reasons.  Heap_4 is more appropriate.  See\r
+       http://www.freertos.org/a00111.html for an explanation. */\r
+       prvInitialiseHeap();\r
+\r
+       /* Initialise the trace recorder.  Use of the trace recorder is optional.\r
+       See http://www.FreeRTOS.org/trace for more information. */\r
+       vTraceEnable( TRC_START );\r
+\r
+       /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top\r
+       of this file. */\r
+       #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )\r
+       {\r
+               main_blinky();\r
+       }\r
+       #else\r
+       {\r
+               /* Start the trace recording - the recording is written to a file if\r
+               configASSERT() is called. */\r
+               printf( "\r\nTrace started.\r\nThe trace will be dumped to disk if a call to configASSERT() fails.\r\n" );\r
+               printf( "Uncomment the call to kbhit() in this file to also dump trace with a key press.\r\n" );\r
+               uiTraceStart();\r
+\r
+               main_full();\r
+       }\r
+       #endif\r
+\r
+       return 0;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvCheckTask( void *pvParameters )\r
+void vApplicationMallocFailedHook( void )\r
 {\r
-portTickType xNextWakeTime;\r
-const portTickType xCycleFrequency = 1000 / portTICK_RATE_MS;\r
+       /* vApplicationMallocFailedHook() will only be called if\r
+       configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
+       function that will get called if a call to pvPortMalloc() fails.\r
+       pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
+       timer or semaphore is created.  It is also called by various parts of the\r
+       demo application.  If heap_1.c, heap_2.c or heap_4.c is being used, then the\r
+       size of the     heap available to pvPortMalloc() is defined by\r
+       configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()\r
+       API function can be used to query the size of free heap space that remains\r
+       (although it does not provide information on how the remaining heap might be\r
+       fragmented).  See http://www.freertos.org/a00111.html for more\r
+       information. */\r
+       vAssertCalled( __LINE__, __FILE__ );\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       /* Just to remove compiler warning. */\r
-       ( void ) pvParameters;\r
+void vApplicationIdleHook( void )\r
+{\r
+       /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set\r
+       to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle\r
+       task.  It is essential that code added to this hook function never attempts\r
+       to block in any way (for example, call xQueueReceive() with a block time\r
+       specified, or call vTaskDelay()).  If application tasks make use of the\r
+       vTaskDelete() API function to delete themselves then it is also important\r
+       that vApplicationIdleHook() is permitted to return to its calling function,\r
+       because it is the responsibility of the idle task to clean up memory\r
+       allocated by the kernel to any task that has since deleted itself. */\r
+\r
+       /* Uncomment the following code to allow the trace to be stopped with any\r
+       key press.  The code is commented out by default as the kbhit() function\r
+       interferes with the run time behaviour. */\r
+       /*\r
+               if( _kbhit() != pdFALSE )\r
+               {\r
+                       if( xTraceRunning == pdTRUE )\r
+                       {\r
+                               vTraceStop();\r
+                               prvSaveTraceFile();\r
+                               xTraceRunning = pdFALSE;\r
+                       }\r
+               }\r
+       */\r
 \r
-       /* Initialise xNextWakeTime - this only needs to be done once. */\r
-       xNextWakeTime = xTaskGetTickCount();\r
+       #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )\r
+       {\r
+               /* Call the idle task processing used by the full demo.  The simple\r
+               blinky demo does not use the idle task hook. */\r
+               vFullDemoIdleFunction();\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )\r
+{\r
+       ( void ) pcTaskName;\r
+       ( void ) pxTask;\r
+\r
+       /* Run time stack overflow checking is performed if\r
+       configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook\r
+       function is called if a stack overflow is detected.  This function is\r
+       provided as an example only as stack overflow checking does not function\r
+       when running the FreeRTOS Windows port. */\r
+       vAssertCalled( __LINE__, __FILE__ );\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       for( ;; )\r
+void vApplicationTickHook( void )\r
+{\r
+       /* This function will be called by each tick interrupt if\r
+       configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be\r
+       added here, but the tick hook is called from an interrupt context, so\r
+       code must not attempt to block, and only the interrupt safe FreeRTOS API\r
+       functions can be used (those that end in FromISR()). */\r
+\r
+       #if ( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )\r
        {\r
-               /* Place this task in the blocked state until it is time to run again. */\r
-               vTaskDelayUntil( &xNextWakeTime, xCycleFrequency );\r
+               vFullDemoTickHookFunction();\r
+       }\r
+       #endif /* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY */\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-               /* Check the standard demo tasks are running without error. */\r
-               if( xAreTimerDemoTasksStillRunning( xCycleFrequency ) != pdTRUE )\r
-               {\r
-                       pcStatusMessage = "Error: TimerDemo";\r
-               }\r
-           else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
-           {\r
-                       pcStatusMessage = "Error: IntMath";\r
-           }   \r
-               else if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
-               {                       \r
-                       pcStatusMessage = "Error: GenQueue";\r
-               }\r
-               else if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
-               {\r
-                       pcStatusMessage = "Error: QueuePeek";\r
-               }\r
-               else if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
-               {\r
-                       pcStatusMessage = "Error: BlockQueue";\r
-               }\r
-           else if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
-           {\r
-                       pcStatusMessage = "Error: SemTest";\r
-           }\r
-           else if( xArePollingQueuesStillRunning() != pdTRUE )\r
-           {\r
-                       pcStatusMessage = "Error: PollQueue";\r
-           }\r
-               else if( xAreMathsTaskStillRunning() != pdPASS )\r
-               {\r
-                       pcStatusMessage = "Error: Flop";\r
-               }\r
-           else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
-           {\r
-                       pcStatusMessage = "Error: RecMutex";\r
-               }\r
-               else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )\r
-               {\r
-                       pcStatusMessage = "Error: CountSem";\r
-               }\r
-               else if( xIsCreateTaskStillRunning() != pdTRUE )\r
+void vApplicationDaemonTaskStartupHook( void )\r
+{\r
+       /* This function will be called once only, when the daemon task starts to\r
+       execute (sometimes called the timer task).  This is useful if the\r
+       application includes initialisation code that would benefit from executing\r
+       after the scheduler has been started. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vAssertCalled( unsigned long ulLine, const char * const pcFileName )\r
+{\r
+static BaseType_t xPrinted = pdFALSE;\r
+volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;\r
+\r
+       /* Called if an assertion passed to configASSERT() fails.  See\r
+       http://www.freertos.org/a00110.html#configASSERT for more information. */\r
+\r
+       /* Parameters are not used. */\r
+       ( void ) ulLine;\r
+       ( void ) pcFileName;\r
+\r
+       printf( "ASSERT! Line %ld, file %s, GetLastError() %ld\r\n", ulLine, pcFileName, GetLastError() );\r
+\r
+       taskENTER_CRITICAL();\r
+       {\r
+               /* Stop the trace recording. */\r
+               if( xPrinted == pdFALSE )\r
                {\r
-                       pcStatusMessage = "Error: Death";\r
+                       xPrinted = pdTRUE;\r
+                       if( xTraceRunning == pdTRUE )\r
+                       {\r
+                               vTraceStop();\r
+                               prvSaveTraceFile();\r
+                       }\r
                }\r
-               else if( xAreDynamicPriorityTasksStillRunning() != pdPASS )\r
+\r
+               /* You can step out of this function to debug the assertion by using\r
+               the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero\r
+               value. */\r
+               while( ulSetToNonZeroInDebuggerToContinue == 0 )\r
                {\r
-                       pcStatusMessage = "Error: Dynamic\r\n";\r
+                       __asm{ NOP };\r
+                       __asm{ NOP };\r
                }\r
-\r
-               /* This is the only task that uses stdout so its ok to call printf() \r
-               directly. */\r
-               printf( "%s - %d\r\n", pcStatusMessage, xTaskGetTickCount() );\r
        }\r
+       taskEXIT_CRITICAL();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationIdleHook( void )\r
+static void prvSaveTraceFile( void )\r
 {\r
-const unsigned long ulMSToSleep = 5;\r
-xTaskHandle xIdleTaskHandle, xTimerTaskHandle;\r
-signed char *pcTaskName;\r
-const unsigned char ucConstQueueNumber = 0xaaU, ucConstTaskNumber = 0x55U;\r
-\r
-/* These three functions are only meant for use by trace code, and not for\r
-direct use from application code, hence their prototypes are not in queue.h. */\r
-extern void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber );\r
-extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue );\r
-extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue );\r
-extern void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle );\r
-extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );\r
-\r
-       /* Sleep to reduce CPU load, but don't sleep indefinitely in case there are\r
-       tasks waiting to be terminated by the idle task. */\r
-       Sleep( ulMSToSleep );\r
-\r
-       /* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and \r
-       xTaskGetIdleTaskHandle() functions.  Also try using the function that sets\r
-       the task number. */\r
-       xIdleTaskHandle = xTaskGetIdleTaskHandle();\r
-       xTimerTaskHandle = xTimerGetTimerDaemonTaskHandle();\r
-       vTaskSetTaskNumber( xIdleTaskHandle, ( unsigned long ) ucConstTaskNumber );\r
-       configASSERT( uxTaskGetTaskNumber( xIdleTaskHandle ) == ucConstTaskNumber );\r
-\r
-       /* This is the idle hook, so the current task handle should equal the \r
-       returned idle task handle. */\r
-       if( xTaskGetCurrentTaskHandle() != xIdleTaskHandle )\r
-       {\r
-               pcStatusMessage = "Error:  Returned idle task handle was incorrect";\r
-       }\r
+FILE* pxOutputFile;\r
+\r
+       fopen_s( &pxOutputFile, "Trace.dump", "wb");\r
 \r
-       /* Check the timer task handle was returned correctly. */\r
-       pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );\r
-       if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )\r
+       if( pxOutputFile != NULL )\r
        {\r
-               pcStatusMessage = "Error:  Returned timer task handle was incorrect";\r
+               fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );\r
+               fclose( pxOutputFile );\r
+               printf( "\r\nTrace output saved to Trace.dump\r\n" );\r
        }\r
-\r
-       /* If xMutexToDelete has not already been deleted, then delete it now.\r
-       This is done purely to demonstrate the use of, and test, the \r
-       vSemaphoreDelete() macro.  Care must be taken not to delete a semaphore\r
-       that has tasks blocked on it. */\r
-       if( xMutexToDelete != NULL )\r
+       else\r
        {\r
-               /* Before deleting the semaphore, test the function used to set its\r
-               number.  This would normally only be done from trace software, rather\r
-               than application code. */\r
-               vQueueSetQueueNumber( xMutexToDelete, ucConstQueueNumber );\r
-\r
-               /* Before deleting the semaphore, test the functions used to get its\r
-               type and number.  Again, these would normally only be done from trace\r
-               software, rather than application code. */\r
-               configASSERT( ucQueueGetQueueNumber( xMutexToDelete ) == ucConstQueueNumber );\r
-               configASSERT( ucQueueGetQueueType( xMutexToDelete ) == queueQUEUE_TYPE_MUTEX );\r
-               vSemaphoreDelete( xMutexToDelete );\r
-               xMutexToDelete = NULL;\r
+               printf( "\r\nFailed to create trace dump file\r\n" );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationMallocFailedHook( void )\r
+static void  prvInitialiseHeap( void )\r
 {\r
-       /* Can be implemented if required, but probably not required in this \r
-       environment and running this demo. */\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationStackOverflowHook( void )\r
+/* The Windows demo could create one large heap region, in which case it would\r
+be appropriate to use heap_4.  However, purely for demonstration purposes,\r
+heap_5 is used instead, so start by defining some heap regions.  No\r
+initialisation is required when any other heap implementation is used.  See\r
+http://www.freertos.org/a00111.html for more information.\r
+\r
+The xHeapRegions structure requires the regions to be defined in start address\r
+order, so this just creates one big array, then populates the structure with\r
+offsets into the array - with gaps in between and messy alignment just for test\r
+purposes. */\r
+static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];\r
+volatile uint32_t ulAdditionalOffset = 19; /* Just to prevent 'condition is always true' warnings in configASSERT(). */\r
+const HeapRegion_t xHeapRegions[] =\r
 {\r
-       /* Can be implemented if required, but not required in this \r
-       environment and running this demo. */\r
+       /* Start address with dummy offsets                                             Size */\r
+       { ucHeap + 1,                                                                                   mainREGION_1_SIZE },\r
+       { ucHeap + 15 + mainREGION_1_SIZE,                                              mainREGION_2_SIZE },\r
+       { ucHeap + 19 + mainREGION_1_SIZE + mainREGION_2_SIZE,  mainREGION_3_SIZE },\r
+       { NULL, 0 }\r
+};\r
+\r
+       /* Sanity check that the sizes and offsets defined actually fit into the\r
+       array. */\r
+       configASSERT( ( ulAdditionalOffset + mainREGION_1_SIZE + mainREGION_2_SIZE + mainREGION_3_SIZE ) < configTOTAL_HEAP_SIZE );\r
+\r
+       /* Prevent compiler warnings when configASSERT() is not defined. */\r
+       ( void ) ulAdditionalOffset;\r
+\r
+       vPortDefineHeapRegions( xHeapRegions );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationTickHook( void )\r
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an\r
+implementation of vApplicationGetIdleTaskMemory() to provide the memory that is\r
+used by the Idle task. */\r
+void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )\r
 {\r
-       /* Call the periodic timer test, which tests the timer API functions that\r
-       can be called from an ISR. */\r
-       vTimerPeriodicISRTests();\r
+/* If the buffers to be provided to the Idle task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xIdleTaskTCB;\r
+static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Idle task's\r
+       state will be stored. */\r
+       *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Idle task's stack. */\r
+       *ppxIdleTaskStackBuffer = uxIdleTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vAssertCalled( void )\r
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the\r
+application must provide an implementation of vApplicationGetTimerTaskMemory()\r
+to provide the memory that is used by the Timer service task. */\r
+void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )\r
 {\r
-       taskDISABLE_INTERRUPTS();\r
-       for( ;; );\r
+/* If the buffers to be provided to the Timer task are declared inside this\r
+function then they must be declared static - otherwise they will be allocated on\r
+the stack and so not exists after this function exits. */\r
+static StaticTask_t xTimerTaskTCB;\r
+\r
+       /* Pass out a pointer to the StaticTask_t structure in which the Timer\r
+       task's state will be stored. */\r
+       *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;\r
+\r
+       /* Pass out the array that will be used as the Timer task's stack. */\r
+       *ppxTimerTaskStackBuffer = uxTimerTaskStack;\r
+\r
+       /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.\r
+       Note that, as the array is necessarily of type StackType_t,\r
+       configMINIMAL_STACK_SIZE is specified in words, not bytes. */\r
+       *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;\r
 }\r
 \r