]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/WIN32-MSVC/main.c
Add xQueueOverwriteFromISR() and update the QueueOverwrite.c to demonstrate its use.
[freertos] / FreeRTOS / Demo / WIN32-MSVC / main.c
index 73222836eb84f4657dce8c443ffcbc923d3e3301..b57938c7ba3f6781ab628790d569556fe62f23b9 100644 (file)
@@ -1,6 +1,8 @@
 /*\r
-    FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.\r
-       \r
+    FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
+\r
+    FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
+    http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
 \r
     ***************************************************************************\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
+\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
+    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.  See the GNU General Public License for more\r
+    details. You should have received a copy of the GNU General Public License\r
+    and the FreeRTOS license exception along with FreeRTOS; if not it can be\r
+    viewed here: http://www.freertos.org/a00114.html and also obtained by\r
+    writing to Real Time Engineers Ltd., contact details for whom are available\r
+    on the 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
-     *    not run, what could be wrong?                                      *\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
+\r
+    http://www.FreeRTOS.org - Documentation, books, training, latest versions\r
+    license and Real Time Engineers Ltd. contact details.\r
+\r
     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
-    including FreeRTOS+Trace - an indispensable productivity tool.\r
+    including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
+    fully thread aware and reentrant UDP/IP stack.\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
+    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
+    Integrity Systems, who sell the code with commercial support, \r
+    indemnification and middleware, under the OpenRTOS brand.\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
 \r
 /*\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
  *\r
+ * In this example, one simulated millisecond will take approximately 40ms to\r
+ * execute, and Windows will not be running the FreeRTOS simulator threads\r
+ * continuously, so the timing information in the FreeRTOS+Trace logs have no\r
+ * meaningful units.  See the documentation page for the Windows simulator for\r
+ * an explanation of the slow timing:\r
+ * http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html\r
  * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -\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
 #include "countsem.h"\r
 #include "death.h"\r
 #include "dynamic.h"\r
+#include "QueueSet.h"\r
+#include "QueueOverwrite.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
+#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
+#define mainQUEUE_OVERWRITE_PRIORITY   ( tskIDLE_PRIORITY )\r
 \r
 #define mainTIMER_TEST_PERIOD                  ( 50 )\r
 \r
 /* Task function prototypes. */\r
 static void prvCheckTask( void *pvParameters );\r
 \r
+/* A task that is created from the idle task to test the functionality of \r
+eTaskStateGet(). */\r
+static void prvTestTask( void *pvParameters );\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
+ * Called from the idle task hook function to demonstrate a few utility\r
+ * functions that are not demonstrated by any of the standard demo tasks.\r
+ */\r
+static void prvDemonstrateTaskStateAndHandleGetFunctions( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
 /* The variable into which error messages are latched. */\r
 static char *pcStatusMessage = "OK";\r
 \r
@@ -140,10 +177,21 @@ static char *pcStatusMessage = "OK";
 semaphore tracing API functions.  It has no other purpose. */\r
 static xSemaphoreHandle xMutexToDelete = NULL;\r
 \r
+/* The user trace event posted to the trace recording on each tick interrupt.\r
+Note tick events will not appear in the trace recording with regular period\r
+because this project runs in a Windows simulator, and does not therefore\r
+exhibit deterministic behaviour. */\r
+traceLabel xTickTraceUserEvent;\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 int main( void )\r
 {\r
+       /* Initialise the trace recorder and create the label used to post user\r
+       events to the trace recording on each tick interrupt. */\r
+       vTraceInitTraceData();\r
+       xTickTraceUserEvent = xTraceOpenLabel( "tick" );\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
@@ -159,6 +207,8 @@ int main( void )
        vStartTimerDemoTask( mainTIMER_TEST_PERIOD );\r
        vStartCountingSemaphoreTasks();\r
        vStartDynamicPriorityTasks();\r
+       vStartQueueSetTasks();\r
+       vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );\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
@@ -170,6 +220,11 @@ int main( void )
        is done purely to test the use of vSemaphoreDelete(). */\r
        xMutexToDelete = xSemaphoreCreateMutex();\r
 \r
+       /* Start the trace recording - the recording is written to a file if\r
+       configASSERT() is called. */\r
+       printf( "\r\nTrace started.  Hit a key to dump trace file to disk.\r\n" );\r
+       uiTraceStart();\r
+\r
        /* Start the scheduler itself. */\r
        vTaskStartScheduler();\r
 \r
@@ -244,6 +299,14 @@ const portTickType xCycleFrequency = 1000 / portTICK_RATE_MS;
                {\r
                        pcStatusMessage = "Error: Dynamic\r\n";\r
                }\r
+               else if( xAreQueueSetTasksStillRunning() != pdPASS )\r
+               {\r
+                       pcStatusMessage = "Error: Queue set\r\n";\r
+               }\r
+               else if( xIsQueueOverwriteTaskStillRunning() != pdPASS )\r
+               {\r
+                       pcStatusMessage = "Error: Queue overwrite\r\n";\r
+               }\r
 \r
                /* This is the only task that uses stdout so its ok to call printf() \r
                directly. */\r
@@ -252,12 +315,30 @@ const portTickType xCycleFrequency = 1000 / portTICK_RATE_MS;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vApplicationIdleHook( void )\r
+static void prvTestTask( void *pvParameters )\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
+       /* Just to remove compiler warnings. */\r
+       ( void ) pvParameters;\r
+\r
+       /* This task is just used to test the eTaskStateGet() function.  It\r
+       does not have anything to do. */\r
+       for( ;; )\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
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+const unsigned long ulMSToSleep = 15;\r
+const unsigned char ucConstQueueNumber = 0xaaU;\r
+void *pvAllocated;\r
+static portBASE_TYPE xTraceRunning = pdTRUE;\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
@@ -271,27 +352,9 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
        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
-\r
-       /* Check the timer task handle was returned correctly. */\r
-       pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );\r
-       if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )\r
-       {\r
-               pcStatusMessage = "Error:  Returned timer task handle was incorrect";\r
-       }\r
+       /* Demonstrate a few utility functions that are not demonstrated by any of\r
+       the standard demo tasks. */\r
+       prvDemonstrateTaskStateAndHandleGetFunctions();\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
@@ -312,13 +375,26 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
                vSemaphoreDelete( xMutexToDelete );\r
                xMutexToDelete = NULL;\r
        }\r
+\r
+       /* Exercise heap_4 a bit.  The malloc failed hook will trap failed \r
+       allocations so there is no need to test here. */\r
+       pvAllocated = pvPortMalloc( ( rand() % 100 ) + 1 );\r
+       vPortFree( pvAllocated );\r
+\r
+       if( _kbhit() != pdFALSE )\r
+       {\r
+               if( xTraceRunning == pdTRUE )\r
+               {\r
+                       prvSaveTraceFile();\r
+                       xTraceRunning = pdFALSE;\r
+               }\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void vApplicationMallocFailedHook( void )\r
 {\r
-       /* Can be implemented if required, but probably not required in this \r
-       environment and running this demo. */\r
+       vAssertCalled();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -334,12 +410,126 @@ void vApplicationTickHook( void )
        /* Call the periodic timer test, which tests the timer API functions that\r
        can be called from an ISR. */\r
        vTimerPeriodicISRTests();\r
+\r
+       /* Call the periodic queue overwrite from ISR demo. */\r
+       vQueueOverwritePeriodicISRDemo();\r
+\r
+       /* Write to a queue that is in use as part of the queue set demo to \r
+       demonstrate using queue sets from an ISR. */\r
+       vQueueSetAccessQueueSetFromISR();\r
+\r
+       /* Write a user event to the trace log.  \r
+       Note tick events will not appear in the trace recording with regular period\r
+       because this project runs in a Windows simulator, and does not therefore\r
+       exhibit deterministic behaviour. */\r
+       vTraceUserEvent( xTickTraceUserEvent );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 void vAssertCalled( void )\r
 {\r
        taskDISABLE_INTERRUPTS();\r
+\r
+       /* Stop the trace recording. */\r
+       vTraceStop();\r
+       prvSaveTraceFile();\r
+               \r
        for( ;; );\r
 }\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSaveTraceFile( void )\r
+{\r
+FILE* pxOutputFile;\r
+\r
+       fopen_s( &pxOutputFile, "Trace.dump", "wb");\r
+\r
+       if( pxOutputFile != NULL )\r
+       {\r
+               fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );\r
+               fclose( pxOutputFile );\r
+               printf( "\r\nTrace output saved to Trace.dump\r\n" );\r
+       }\r
+       else\r
+       {\r
+               printf( "\r\nFailed to create trace dump file\r\n" );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvDemonstrateTaskStateAndHandleGetFunctions( void )\r
+{\r
+xTaskHandle xIdleTaskHandle, xTimerTaskHandle;\r
+const unsigned char ucConstTaskNumber = 0x55U;\r
+signed char *pcTaskName;\r
+static portBASE_TYPE xPerformedOneShotTests = pdFALSE;\r
+xTaskHandle xTestTask;\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
+\r
+       /* Check the timer task handle was returned correctly. */\r
+       pcTaskName = pcTaskGetTaskName( xTimerTaskHandle );\r
+       if( strcmp( pcTaskName, "Tmr Svc" ) != 0 )\r
+       {\r
+               pcStatusMessage = "Error:  Returned timer task handle was incorrect";\r
+       }\r
+\r
+       /* This task is running, make sure it's state is returned as running. */\r
+       if( eTaskStateGet( xIdleTaskHandle ) != eRunning )\r
+       {\r
+               pcStatusMessage = "Error:  Returned idle task state was incorrect";\r
+       }\r
+\r
+       /* If this task is running, then the timer task must be blocked. */\r
+       if( eTaskStateGet( xTimerTaskHandle ) != eBlocked )\r
+       {\r
+               pcStatusMessage = "Error:  Returned timer task state was incorrect";\r
+       }\r
+\r
+       /* Other tests that should only be performed once follow.  The test task\r
+       is not created on each iteration because to do so would cause the death\r
+       task to report an error (too many tasks running). */\r
+       if( xPerformedOneShotTests == pdFALSE )\r
+       {\r
+               /* Don't run this part of the test again. */\r
+               xPerformedOneShotTests = pdTRUE;\r
+\r
+               /* Create a test task to use to test other eTaskStateGet() return values. */\r
+               if( xTaskCreate( prvTestTask, "Test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xTestTask ) == pdPASS )\r
+               {\r
+                       /* If this task is running, the test task must be in the ready state. */\r
+                       if( eTaskStateGet( xTestTask ) != eReady )\r
+                       {\r
+                               pcStatusMessage = "Error: Returned test task state was incorrect 1";\r
+                       }\r
+\r
+                       /* Now suspend the test task and check its state is reported correctly. */\r
+                       vTaskSuspend( xTestTask );\r
+                       if( eTaskStateGet( xTestTask ) != eSuspended )\r
+                       {\r
+                               pcStatusMessage = "Error: Returned test task state was incorrect 2";\r
+                       }\r
+\r
+                       /* Now delete the task and check its state is reported correctly. */\r
+                       vTaskDelete( xTestTask );\r
+                       if( eTaskStateGet( xTestTask ) != eDeleted )\r
+                       {\r
+                               pcStatusMessage = "Error: Returned test task state was incorrect 3";\r
+                       }\r
+               }\r
+       }\r
+}\r
 \r