/*\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
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
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
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
{\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
}\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
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
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
/* 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