--- /dev/null
+/*\r
+ FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd.\r
+\r
+ ***************************************************************************\r
+ * *\r
+ * If you are: *\r
+ * *\r
+ * + New to FreeRTOS, *\r
+ * + Wanting to learn FreeRTOS or multitasking in general quickly *\r
+ * + Looking for basic training, *\r
+ * + Wanting to improve your FreeRTOS skills and productivity *\r
+ * *\r
+ * then take a look at the FreeRTOS books - available as PDF or paperback *\r
+ * *\r
+ * "Using the FreeRTOS Real Time Kernel - a Practical Guide" *\r
+ * http://www.FreeRTOS.org/Documentation *\r
+ * *\r
+ * A pdf reference manual is also available. Both are usually delivered *\r
+ * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+ * and 8pm GMT (although please allow up to 24 hours in case of *\r
+ * exceptional circumstances). Thank you for your support! *\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 exception to the GPL is included to allow you to distribute\r
+ a combined work that includes FreeRTOS without being obliged to provide the\r
+ source code for proprietary components outside of the FreeRTOS kernel.\r
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+ 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
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
+ contact details.\r
+\r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
+ critical systems.\r
+\r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
+ licensing and training services.\r
+*/\r
+\r
+/*\r
+ The tasks defined on this page demonstrate the use of recursive mutexes.\r
+\r
+ For recursive mutex functionality the created mutex should be created using\r
+ xSemaphoreCreateRecursiveMutex(), then be manipulated\r
+ using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API\r
+ functions.\r
+\r
+ This demo creates three tasks all of which access the same recursive mutex:\r
+\r
+ prvRecursiveMutexControllingTask() has the highest priority so executes \r
+ first and grabs the mutex. It then performs some recursive accesses - \r
+ between each of which it sleeps for a short period to let the lower \r
+ priority tasks execute. When it has completed its demo functionality\r
+ it gives the mutex back before suspending itself.\r
+\r
+ prvRecursiveMutexBlockingTask() attempts to access the mutex by performing\r
+ a blocking 'take'. The blocking task has a lower priority than the \r
+ controlling task so by the time it executes the mutex has already been\r
+ taken by the controlling task, causing the blocking task to block. It \r
+ does not unblock until the controlling task has given the mutex back, \r
+ and it does not actually run until the controlling task has suspended \r
+ itself (due to the relative priorities). When it eventually does obtain\r
+ the mutex all it does is give the mutex back prior to also suspending \r
+ itself. At this point both the controlling task and the blocking task are \r
+ suspended.\r
+\r
+ prvRecursiveMutexPollingTask() runs at the idle priority. It spins round\r
+ a tight loop attempting to obtain the mutex with a non-blocking call. As\r
+ the lowest priority task it will not successfully obtain the mutex until\r
+ both the controlling and blocking tasks are suspended. Once it eventually \r
+ does obtain the mutex it first unsuspends both the controlling task and\r
+ blocking task prior to giving the mutex back - resulting in the polling\r
+ task temporarily inheriting the controlling tasks priority.\r
+*/\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* Demo app include files. */\r
+#include "recmutex.h"\r
+\r
+/* Priorities assigned to the three tasks. */\r
+#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )\r
+\r
+/* In this version the tick period is very long, so the short delay cannot be\r
+for too many ticks, or the check task will execute and find that the recmutex\r
+tasks have not completed their functionality and then signal an error. The\r
+delay does however have to be long enough to allow the lower priority tasks\r
+a chance of executing - this is basically achieved by reducing the number\r
+of times the loop that takes/gives the recursive mutex executes. */\r
+#define recmuMAX_COUNT ( 2 )\r
+#define recmuSHORT_DELAY ( 20 )\r
+#define recmuNO_DELAY ( ( portTickType ) 0 )\r
+#define recmuFIVE_TICK_DELAY ( ( portTickType ) 5 )\r
+\r
+/* The three tasks as described at the top of this file. */\r
+static void prvRecursiveMutexControllingTask( void *pvParameters );\r
+static void prvRecursiveMutexBlockingTask( void *pvParameters );\r
+static void prvRecursiveMutexPollingTask( void *pvParameters );\r
+\r
+/* The mutex used by the demo. */\r
+static xSemaphoreHandle xMutex;\r
+\r
+/* Variables used to detect and latch errors. */\r
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE;\r
+static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0;\r
+\r
+/* Handles of the two higher priority tasks, required so they can be resumed \r
+(unsuspended). */\r
+static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartRecursiveMutexTasks( void )\r
+{\r
+ /* Just creates the mutex and the three tasks. */\r
+\r
+ xMutex = xSemaphoreCreateRecursiveMutex();\r
+\r
+ /* vQueueAddToRegistry() adds the mutex to the registry, if one is\r
+ in use. The registry is provided as a means for kernel aware \r
+ debuggers to locate mutex and has no purpose if a kernel aware debugger\r
+ is not being used. The call to vQueueAddToRegistry() will be removed\r
+ by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
+ defined to be less than 1. */\r
+ vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Recursive_Mutex" );\r
+\r
+\r
+ if( xMutex != NULL )\r
+ {\r
+ xTaskCreate( prvRecursiveMutexControllingTask, ( signed portCHAR * ) "Rec1Ctrl", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );\r
+ xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2Blck", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );\r
+ xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3Poll", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRecursiveMutexControllingTask( void *pvParameters )\r
+{\r
+unsigned portBASE_TYPE ux;\r
+\r
+ /* Just to remove compiler warning. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Should not be able to 'give' the mutex, as we have not yet 'taken'\r
+ it. The first time through, the mutex will not have been used yet,\r
+ subsequent times through, at this point the mutex will be held by the\r
+ polling task. */\r
+ if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ for( ux = 0; ux < recmuMAX_COUNT; ux++ )\r
+ {\r
+ /* We should now be able to take the mutex as many times as\r
+ we like.\r
+ \r
+ The first time through the mutex will be immediately available, on\r
+ subsequent times through the mutex will be held by the polling task\r
+ at this point and this Take will cause the polling task to inherit\r
+ the priority of this task. In this case the block time must be\r
+ long enough to ensure the polling task will execute again before the\r
+ block time expires. If the block time does expire then the error\r
+ flag will be set here. */\r
+ if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ /* Ensure the other task attempting to access the mutex (and the\r
+ other demo tasks) are able to execute to ensure they either block\r
+ (where a block time is specified) or return an error (where no \r
+ block time is specified) as the mutex is held by this task. */\r
+ vTaskDelay( recmuSHORT_DELAY );\r
+ }\r
+\r
+ /* For each time we took the mutex, give it back. */\r
+ for( ux = 0; ux < recmuMAX_COUNT; ux++ )\r
+ {\r
+ /* Ensure the other task attempting to access the mutex (and the\r
+ other demo tasks) are able to execute. */\r
+ vTaskDelay( recmuSHORT_DELAY );\r
+\r
+ /* We should now be able to give the mutex as many times as we\r
+ took it. When the mutex is available again the Blocking task\r
+ should be unblocked but not run because it has a lower priority\r
+ than this task. The polling task should also not run at this point\r
+ as it too has a lower priority than this task. */\r
+ if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ }\r
+\r
+ /* Having given it back the same number of times as it was taken, we\r
+ should no longer be the mutex owner, so the next give should fail. */\r
+ if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ /* Keep count of the number of cycles this task has performed so a \r
+ stall can be detected. */\r
+ uxControllingCycles++;\r
+\r
+ /* Suspend ourselves so the blocking task can execute. */\r
+ xControllingIsSuspended = pdTRUE;\r
+ vTaskSuspend( NULL );\r
+ xControllingIsSuspended = pdFALSE;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRecursiveMutexBlockingTask( void *pvParameters )\r
+{\r
+ /* Just to remove compiler warning. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* This task will run while the controlling task is blocked, and the\r
+ controlling task will block only once it has the mutex - therefore\r
+ this call should block until the controlling task has given up the \r
+ mutex, and not actually execute past this call until the controlling \r
+ task is suspended. */\r
+ if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS )\r
+ {\r
+ if( xControllingIsSuspended != pdTRUE )\r
+ {\r
+ /* Did not expect to execute until the controlling task was\r
+ suspended. */\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ /* Give the mutex back before suspending ourselves to allow\r
+ the polling task to obtain the mutex. */\r
+ if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ xBlockingIsSuspended = pdTRUE;\r
+ vTaskSuspend( NULL );\r
+ xBlockingIsSuspended = pdFALSE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* We should not leave the xSemaphoreTakeRecursive() function\r
+ until the mutex was obtained. */\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ /* The controlling and blocking tasks should be in lock step. */\r
+ if( uxControllingCycles != ( uxBlockingCycles + 1 ) )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ /* Keep count of the number of cycles this task has performed so a \r
+ stall can be detected. */\r
+ uxBlockingCycles++;\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRecursiveMutexPollingTask( void *pvParameters )\r
+{\r
+ /* Just to remove compiler warning. */\r
+ ( void ) pvParameters;\r
+\r
+ for( ;; )\r
+ {\r
+ /* Keep attempting to obtain the mutex. We should only obtain it when\r
+ the blocking task has suspended itself, which in turn should only\r
+ happen when the controlling task is also suspended. */\r
+ if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS )\r
+ {\r
+ /* Is the blocking task suspended? */\r
+ if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ /* Keep count of the number of cycles this task has performed \r
+ so a stall can be detected. */\r
+ uxPollingCycles++;\r
+\r
+ /* We can resume the other tasks here even though they have a\r
+ higher priority than the polling task. When they execute they\r
+ will attempt to obtain the mutex but fail because the polling\r
+ task is still the mutex holder. The polling task (this task)\r
+ will then inherit the higher priority. The Blocking task will\r
+ block indefinitely when it attempts to obtain the mutex, the\r
+ Controlling task will only block for a fixed period and an\r
+ error will be latched if the polling task has not returned the\r
+ mutex by the time this fixed period has expired. */\r
+ vTaskResume( xBlockingTaskHandle );\r
+ vTaskResume( xControllingTaskHandle );\r
+ \r
+ /* The other two tasks should now have executed and no longer\r
+ be suspended. */\r
+ if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ } \r
+ \r
+ /* Release the mutex, disinheriting the higher priority again. */\r
+ if( xSemaphoreGiveRecursive( xMutex ) != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ }\r
+ }\r
+\r
+ #if configUSE_PREEMPTION == 0\r
+ {\r
+ taskYIELD();\r
+ }\r
+ #endif\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void )\r
+{\r
+portBASE_TYPE xReturn;\r
+static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0;\r
+\r
+ /* Is the controlling task still cycling? */\r
+ if( uxLastControllingCycles == uxControllingCycles )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ uxLastControllingCycles = uxControllingCycles;\r
+ }\r
+\r
+ /* Is the blocking task still cycling? */\r
+ if( uxLastBlockingCycles == uxBlockingCycles )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ uxLastBlockingCycles = uxBlockingCycles;\r
+ }\r
+\r
+ /* Is the polling task still cycling? */\r
+ if( uxLastPollingCycles == uxPollingCycles )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ else\r
+ {\r
+ uxLastPollingCycles = uxPollingCycles;\r
+ }\r
+\r
+ if( xErrorOccurred == pdTRUE )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdTRUE;\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+\r
+\r
+\r
+\r
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
*----------------------------------------------------------*/\r
+\r
#define configUSE_PREEMPTION 1\r
#define configUSE_IDLE_HOOK 1\r
#define configUSE_TICK_HOOK 0\r
-#define configTICK_RATE_HZ ( ( portTickType ) 50 )\r
+#define configTICK_RATE_HZ ( 50 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */\r
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 50 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */\r
#define configTOTAL_HEAP_SIZE ( ( size_t ) 0 ) /* This parameter has no effect when heap_3.c is included in the project. */\r
#define configMAX_TASK_NAME_LEN ( 12 )\r
#define INCLUDE_xTaskGetSchedulerState 1\r
\r
\r
+/* When switching threads, Windows does not always seem to run the selected\r
+thread immediately. This function can be called to check if the thread\r
+that is currently running is the thread that is responsible for executing\r
+the task selected by the real time scheduler. If not then a yield is performed\r
+which will try and force the running thread to block on a semaphore, and hence\r
+allow the thread that should be running to take over. The trace macros are a\r
+convenient way of lacing the code with these checking calls. */\r
+void vPortCheckCorrectThreadIsRunning( void );\r
+\r
+#define traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceBLOCKING_ON_QUEUE_SEND(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceGIVE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex\r
+#define traceQUEUE_CREATE(pxNewQueue) vPortCheckCorrectThreadIsRunning();(void)pxNewQueue\r
+#define traceQUEUE_CREATE_FAILED() vPortCheckCorrectThreadIsRunning()\r
+#define traceCREATE_MUTEX(pxNewMutex) vPortCheckCorrectThreadIsRunning();(void)pxNewMutex\r
+#define traceCREATE_MUTEX_FAILED() vPortCheckCorrectThreadIsRunning()\r
+#define traceGIVE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex\r
+#define traceGIVE_MUTEX_RECURSIVE_FAILED(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex\r
+#define traceTAKE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex\r
+#define traceTAKE_MUTEX_RECURSIVE_FAILED(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex\r
+#define traceCREATE_COUNTING_SEMAPHORE() vPortCheckCorrectThreadIsRunning()\r
+#define traceCREATE_COUNTING_SEMAPHORE_FAILED() vPortCheckCorrectThreadIsRunning()\r
+#define traceQUEUE_SEND(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_SEND_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_RECEIVE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_RECEIVE_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_PEEK(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_SEND_FROM_ISR(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_RECEIVE_FROM_ISR(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_RECEIVE_FROM_ISR_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceQUEUE_DELETE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue\r
+#define traceTASK_CREATE(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask\r
+#define traceTASK_CREATE_FAILED(pxNewTCB) vPortCheckCorrectThreadIsRunning();(void)pxNewTCB\r
+#define traceTASK_DELETE(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask\r
+#define traceTASK_DELAY_UNTIL() vPortCheckCorrectThreadIsRunning()\r
+#define traceTASK_DELAY() vPortCheckCorrectThreadIsRunning()\r
+#define traceTASK_PRIORITY_SET(pxTask,uxNewPriority) vPortCheckCorrectThreadIsRunning();(void)pxTask;(void)uxNewPriority\r
+#define traceTASK_SUSPEND(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask\r
+#define traceTASK_RESUME(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask\r
+#define traceTASK_RESUME_FROM_ISR(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask\r
+\r
+\r
#endif /* FREERTOS_CONFIG_H */\r
licensing and training services.\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. Also, at the time of writing, a method of deleting theads \r
+ * has not been implemented, although doing so would be trivial so this\r
+ * functionality might be added in at a later date. At present, calling \r
+ * vTaskDelete() will delete the real time task from FreeRTOS but not the Win32\r
+ * thread in which the task was executing. DO NOT CALL vTaskDelete() when using \r
+ * the Win32 port! This was tested using Windows XP on a dual core laptop.\r
+ *\r
+ * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -\r
+ *******************************************************************************\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
+ *\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Check" 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
+ *\r
+ */\r
+\r
+\r
/* Standard includes. */\r
#include <stdio.h>\r
\r
#include "BlockQ.h"\r
#include "death.h"\r
#include "integer.h"\r
-//#include "blocktim.h"\r
#include "semtest.h"\r
#include "PollQ.h"\r
#include "GenQTest.h"\r
/* Task function prototypes. */\r
static void prvCheckTask( void *pvParameters );\r
\r
-/* Create a queue on which console output strings can be posted, then start the\r
-task that processes the queue - printf()'ing each string that is received. */\r
-static void prvStartStdoutTask( void );\r
-\r
-/* Post a message for output by the stdout task. Basically queues the message\r
-pointed to by pcTextToPrint for output to stdout in a thread safe manner. */\r
-void vMainConsolePrint( const char *pcTextToPrint, portTickType xTicksToWait );\r
-\r
/*-----------------------------------------------------------*/\r
\r
int main( void )\r
\r
/* Create the standard demo tasks. */\r
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
-// vCreateBlockTimeTasks();\r
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );\r
vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
vStartQueuePeekTasks();\r
- vStartRecursiveMutexTasks();\r
vStartMathTasks( mainFLOP_TASK_PRIORITY );\r
+ vStartRecursiveMutexTasks();\r
\r
/* Start the scheduler itself. */\r
vTaskStartScheduler();\r
portTickType xNextWakeTime;\r
const portTickType xCycleFrequency = 5000 / portTICK_RATE_MS;\r
char *pcStatusMessage = "OK";\r
-long lCycleCount = 0;\r
\r
/* Just to remove compiler warning. */\r
( void ) pvParameters;\r
{\r
pcStatusMessage = "Error: BlockQueue";\r
}\r
-// else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
-// {\r
-// pcStatusMessage = "Error: BlockTime";\r
-// }\r
else if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
{\r
pcStatusMessage = "Error: SemTest";\r
else if( xArePollingQueuesStillRunning() != pdTRUE )\r
{\r
pcStatusMessage = "Error: PollQueue";\r
- }\r
- else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
- {\r
- pcStatusMessage = "Error: RecMutex";\r
}\r
else if( xAreMathsTaskStillRunning() != pdPASS )\r
{\r
pcStatusMessage = "Error: Flop";\r
}\r
+ else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: RecMutex";\r
+ }\r
\r
/* This is the only task that uses stdout so its ok to call printf() \r
directly. */\r