From: richardbarry Date: Sun, 21 Nov 2010 14:35:36 +0000 (+0000) Subject: Updated the Win32 MSVC demo files. X-Git-Tag: V6.1.1~105 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=7ec5fa3c6821260f50df706993e68ece686cdbbd;p=freertos Updated the Win32 MSVC demo files. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1152 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Demo/WIN32-MSVC/DemosModifiedForLowTickRate/recmutex.c b/Demo/WIN32-MSVC/DemosModifiedForLowTickRate/recmutex.c new file mode 100644 index 000000000..600906790 --- /dev/null +++ b/Demo/WIN32-MSVC/DemosModifiedForLowTickRate/recmutex.c @@ -0,0 +1,398 @@ +/* + FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS books - available as PDF or paperback * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + The tasks defined on this page demonstrate the use of recursive mutexes. + + For recursive mutex functionality the created mutex should be created using + xSemaphoreCreateRecursiveMutex(), then be manipulated + using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API + functions. + + This demo creates three tasks all of which access the same recursive mutex: + + prvRecursiveMutexControllingTask() has the highest priority so executes + first and grabs the mutex. It then performs some recursive accesses - + between each of which it sleeps for a short period to let the lower + priority tasks execute. When it has completed its demo functionality + it gives the mutex back before suspending itself. + + prvRecursiveMutexBlockingTask() attempts to access the mutex by performing + a blocking 'take'. The blocking task has a lower priority than the + controlling task so by the time it executes the mutex has already been + taken by the controlling task, causing the blocking task to block. It + does not unblock until the controlling task has given the mutex back, + and it does not actually run until the controlling task has suspended + itself (due to the relative priorities). When it eventually does obtain + the mutex all it does is give the mutex back prior to also suspending + itself. At this point both the controlling task and the blocking task are + suspended. + + prvRecursiveMutexPollingTask() runs at the idle priority. It spins round + a tight loop attempting to obtain the mutex with a non-blocking call. As + the lowest priority task it will not successfully obtain the mutex until + both the controlling and blocking tasks are suspended. Once it eventually + does obtain the mutex it first unsuspends both the controlling task and + blocking task prior to giving the mutex back - resulting in the polling + task temporarily inheriting the controlling tasks priority. +*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "recmutex.h" + +/* Priorities assigned to the three tasks. */ +#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/* In this version the tick period is very long, so the short delay cannot be +for too many ticks, or the check task will execute and find that the recmutex +tasks have not completed their functionality and then signal an error. The +delay does however have to be long enough to allow the lower priority tasks +a chance of executing - this is basically achieved by reducing the number +of times the loop that takes/gives the recursive mutex executes. */ +#define recmuMAX_COUNT ( 2 ) +#define recmuSHORT_DELAY ( 20 ) +#define recmuNO_DELAY ( ( portTickType ) 0 ) +#define recmuFIVE_TICK_DELAY ( ( portTickType ) 5 ) + +/* The three tasks as described at the top of this file. */ +static void prvRecursiveMutexControllingTask( void *pvParameters ); +static void prvRecursiveMutexBlockingTask( void *pvParameters ); +static void prvRecursiveMutexPollingTask( void *pvParameters ); + +/* The mutex used by the demo. */ +static xSemaphoreHandle xMutex; + +/* Variables used to detect and latch errors. */ +static volatile portBASE_TYPE xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE; +static volatile unsigned portBASE_TYPE uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0; + +/* Handles of the two higher priority tasks, required so they can be resumed +(unsuspended). */ +static xTaskHandle xControllingTaskHandle, xBlockingTaskHandle; + +/*-----------------------------------------------------------*/ + +void vStartRecursiveMutexTasks( void ) +{ + /* Just creates the mutex and the three tasks. */ + + xMutex = xSemaphoreCreateRecursiveMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Recursive_Mutex" ); + + + if( xMutex != NULL ) + { + xTaskCreate( prvRecursiveMutexControllingTask, ( signed portCHAR * ) "Rec1Ctrl", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); + xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2Blck", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); + xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3Poll", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexControllingTask( void *pvParameters ) +{ +unsigned portBASE_TYPE ux; + + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Should not be able to 'give' the mutex, as we have not yet 'taken' + it. The first time through, the mutex will not have been used yet, + subsequent times through, at this point the mutex will be held by the + polling task. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* We should now be able to take the mutex as many times as + we like. + + The first time through the mutex will be immediately available, on + subsequent times through the mutex will be held by the polling task + at this point and this Take will cause the polling task to inherit + the priority of this task. In this case the block time must be + long enough to ensure the polling task will execute again before the + block time expires. If the block time does expire then the error + flag will be set here. */ + if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute to ensure they either block + (where a block time is specified) or return an error (where no + block time is specified) as the mutex is held by this task. */ + vTaskDelay( recmuSHORT_DELAY ); + } + + /* For each time we took the mutex, give it back. */ + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute. */ + vTaskDelay( recmuSHORT_DELAY ); + + /* We should now be able to give the mutex as many times as we + took it. When the mutex is available again the Blocking task + should be unblocked but not run because it has a lower priority + than this task. The polling task should also not run at this point + as it too has a lower priority than this task. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Having given it back the same number of times as it was taken, we + should no longer be the mutex owner, so the next give should fail. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxControllingCycles++; + + /* Suspend ourselves so the blocking task can execute. */ + xControllingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xControllingIsSuspended = pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexBlockingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This task will run while the controlling task is blocked, and the + controlling task will block only once it has the mutex - therefore + this call should block until the controlling task has given up the + mutex, and not actually execute past this call until the controlling + task is suspended. */ + if( xSemaphoreTakeRecursive( xMutex, portMAX_DELAY ) == pdPASS ) + { + if( xControllingIsSuspended != pdTRUE ) + { + /* Did not expect to execute until the controlling task was + suspended. */ + xErrorOccurred = pdTRUE; + } + else + { + /* Give the mutex back before suspending ourselves to allow + the polling task to obtain the mutex. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + xBlockingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xBlockingIsSuspended = pdFALSE; + } + } + else + { + /* We should not leave the xSemaphoreTakeRecursive() function + until the mutex was obtained. */ + xErrorOccurred = pdTRUE; + } + + /* The controlling and blocking tasks should be in lock step. */ + if( uxControllingCycles != ( uxBlockingCycles + 1 ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxBlockingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexPollingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Keep attempting to obtain the mutex. We should only obtain it when + the blocking task has suspended itself, which in turn should only + happen when the controlling task is also suspended. */ + if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS ) + { + /* Is the blocking task suspended? */ + if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + else + { + /* Keep count of the number of cycles this task has performed + so a stall can be detected. */ + uxPollingCycles++; + + /* We can resume the other tasks here even though they have a + higher priority than the polling task. When they execute they + will attempt to obtain the mutex but fail because the polling + task is still the mutex holder. The polling task (this task) + will then inherit the higher priority. The Blocking task will + block indefinitely when it attempts to obtain the mutex, the + Controlling task will only block for a fixed period and an + error will be latched if the polling task has not returned the + mutex by the time this fixed period has expired. */ + vTaskResume( xBlockingTaskHandle ); + vTaskResume( xControllingTaskHandle ); + + /* The other two tasks should now have executed and no longer + be suspended. */ + if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Release the mutex, disinheriting the higher priority again. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + } + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void ) +{ +portBASE_TYPE xReturn; +static unsigned portBASE_TYPE uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0; + + /* Is the controlling task still cycling? */ + if( uxLastControllingCycles == uxControllingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastControllingCycles = uxControllingCycles; + } + + /* Is the blocking task still cycling? */ + if( uxLastBlockingCycles == uxBlockingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastBlockingCycles = uxBlockingCycles; + } + + /* Is the polling task still cycling? */ + if( uxLastPollingCycles == uxPollingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastPollingCycles = uxPollingCycles; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + + + + diff --git a/Demo/WIN32-MSVC/FreeRTOSConfig.h b/Demo/WIN32-MSVC/FreeRTOSConfig.h index 3d657bf94..a83b8abff 100644 --- a/Demo/WIN32-MSVC/FreeRTOSConfig.h +++ b/Demo/WIN32-MSVC/FreeRTOSConfig.h @@ -64,10 +64,11 @@ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. *----------------------------------------------------------*/ + #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 -#define configTICK_RATE_HZ ( ( portTickType ) 50 ) +#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. */ #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. */ #define configTOTAL_HEAP_SIZE ( ( size_t ) 0 ) /* This parameter has no effect when heap_3.c is included in the project. */ #define configMAX_TASK_NAME_LEN ( 12 ) @@ -105,4 +106,47 @@ to exclude the API function. */ #define INCLUDE_xTaskGetSchedulerState 1 +/* When switching threads, Windows does not always seem to run the selected +thread immediately. This function can be called to check if the thread +that is currently running is the thread that is responsible for executing +the task selected by the real time scheduler. If not then a yield is performed +which will try and force the running thread to block on a semaphore, and hence +allow the thread that should be running to take over. The trace macros are a +convenient way of lacing the code with these checking calls. */ +void vPortCheckCorrectThreadIsRunning( void ); + +#define traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceBLOCKING_ON_QUEUE_SEND(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceGIVE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex +#define traceQUEUE_CREATE(pxNewQueue) vPortCheckCorrectThreadIsRunning();(void)pxNewQueue +#define traceQUEUE_CREATE_FAILED() vPortCheckCorrectThreadIsRunning() +#define traceCREATE_MUTEX(pxNewMutex) vPortCheckCorrectThreadIsRunning();(void)pxNewMutex +#define traceCREATE_MUTEX_FAILED() vPortCheckCorrectThreadIsRunning() +#define traceGIVE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex +#define traceGIVE_MUTEX_RECURSIVE_FAILED(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex +#define traceTAKE_MUTEX_RECURSIVE(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex +#define traceTAKE_MUTEX_RECURSIVE_FAILED(pxMutex) vPortCheckCorrectThreadIsRunning();(void)pxMutex +#define traceCREATE_COUNTING_SEMAPHORE() vPortCheckCorrectThreadIsRunning() +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() vPortCheckCorrectThreadIsRunning() +#define traceQUEUE_SEND(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_SEND_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_RECEIVE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_RECEIVE_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_PEEK(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_SEND_FROM_ISR(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_RECEIVE_FROM_ISR(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_RECEIVE_FROM_ISR_FAILED(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceQUEUE_DELETE(pxQueue) vPortCheckCorrectThreadIsRunning();(void)pxQueue +#define traceTASK_CREATE(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask +#define traceTASK_CREATE_FAILED(pxNewTCB) vPortCheckCorrectThreadIsRunning();(void)pxNewTCB +#define traceTASK_DELETE(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask +#define traceTASK_DELAY_UNTIL() vPortCheckCorrectThreadIsRunning() +#define traceTASK_DELAY() vPortCheckCorrectThreadIsRunning() +#define traceTASK_PRIORITY_SET(pxTask,uxNewPriority) vPortCheckCorrectThreadIsRunning();(void)pxTask;(void)uxNewPriority +#define traceTASK_SUSPEND(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask +#define traceTASK_RESUME(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask +#define traceTASK_RESUME_FROM_ISR(pxTask) vPortCheckCorrectThreadIsRunning();(void)pxTask + + #endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/WIN32-MSVC/WIN32.suo b/Demo/WIN32-MSVC/WIN32.suo index f78c1bfeb..fc93ff8c2 100644 Binary files a/Demo/WIN32-MSVC/WIN32.suo and b/Demo/WIN32-MSVC/WIN32.suo differ diff --git a/Demo/WIN32-MSVC/WIN32.vcxproj b/Demo/WIN32-MSVC/WIN32.vcxproj index bc4b02e9f..a92b9185f 100644 --- a/Demo/WIN32-MSVC/WIN32.vcxproj +++ b/Demo/WIN32-MSVC/WIN32.vcxproj @@ -95,7 +95,7 @@ MaxSpeed OnlyExplicitInline - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true MultiThreaded true @@ -105,13 +105,14 @@ .\Release/ Level3 true + ..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\Include;.;%(AdditionalIncludeDirectories) NDEBUG;%(PreprocessorDefinitions) 0x0c09 - .\Release/WIN32.exe + .\Release/RTOSDemo.exe true .\Release/WIN32.pdb Console @@ -131,8 +132,8 @@ - + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) diff --git a/Demo/WIN32-MSVC/WIN32.vcxproj.filters b/Demo/WIN32-MSVC/WIN32.vcxproj.filters index f57f15453..3d075c58a 100644 --- a/Demo/WIN32-MSVC/WIN32.vcxproj.filters +++ b/Demo/WIN32-MSVC/WIN32.vcxproj.filters @@ -29,6 +29,9 @@ {88f409e6-d396-4ac5-94bd-7a99c914be46} + + {143cf5a3-f134-4439-9f71-a201ae23b44b} + @@ -64,9 +67,6 @@ Demo App Source\Common Demo Tasks - - Demo App Source\Common Demo Tasks - Demo App Source\Common Demo Tasks @@ -76,6 +76,9 @@ Demo App Source\Common Demo Tasks + + Demo App Source\Common Demo Tasks\ModifiedForLowTickRate + diff --git a/Demo/WIN32-MSVC/main.c b/Demo/WIN32-MSVC/main.c index 6685e2fed..a8f09742d 100644 --- a/Demo/WIN32-MSVC/main.c +++ b/Demo/WIN32-MSVC/main.c @@ -51,6 +51,39 @@ licensing and training services. */ +/* + ******************************************************************************* + * -NOTE- The Win32 port is a simulation (or is that emulation?) only! Do not + * expect to get real time behaviour from the Win32 port or this demo + * application. It is provided as a convenient development and demonstration + * test bed only. Also, at the time of writing, a method of deleting theads + * has not been implemented, although doing so would be trivial so this + * functionality might be added in at a later date. At present, calling + * vTaskDelete() will delete the real time task from FreeRTOS but not the Win32 + * thread in which the task was executing. DO NOT CALL vTaskDelete() when using + * the Win32 port! This was tested using Windows XP on a dual core laptop. + * + * - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT - + ******************************************************************************* + * + * main() creates all the demo application tasks, then starts the scheduler. + * The web documentation provides more details of the standard demo application + * tasks, which provide no particular functionality but do provide a good + * example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Check" task - This only executes every five seconds but has a high priority + * to ensure it gets processor time. Its main function is to check that all the + * standard demo tasks are still operational. While no errors have been + * discovered the check task will print out "OK" and the current simulated tick + * time. If an error is discovered in the execution of a task then the check + * task will print out an appropriate error message. + * + */ + + /* Standard includes. */ #include @@ -64,7 +97,6 @@ #include "BlockQ.h" #include "death.h" #include "integer.h" -//#include "blocktim.h" #include "semtest.h" #include "PollQ.h" #include "GenQTest.h" @@ -94,14 +126,6 @@ static xQueueHandle xStdoutQueue = NULL; /* Task function prototypes. */ static void prvCheckTask( void *pvParameters ); -/* Create a queue on which console output strings can be posted, then start the -task that processes the queue - printf()'ing each string that is received. */ -static void prvStartStdoutTask( void ); - -/* Post a message for output by the stdout task. Basically queues the message -pointed to by pcTextToPrint for output to stdout in a thread safe manner. */ -void vMainConsolePrint( const char *pcTextToPrint, portTickType xTicksToWait ); - /*-----------------------------------------------------------*/ int main( void ) @@ -111,14 +135,13 @@ int main( void ) /* Create the standard demo tasks. */ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); -// vCreateBlockTimeTasks(); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartQueuePeekTasks(); - vStartRecursiveMutexTasks(); vStartMathTasks( mainFLOP_TASK_PRIORITY ); + vStartRecursiveMutexTasks(); /* Start the scheduler itself. */ vTaskStartScheduler(); @@ -134,7 +157,6 @@ static void prvCheckTask( void *pvParameters ) portTickType xNextWakeTime; const portTickType xCycleFrequency = 5000 / portTICK_RATE_MS; char *pcStatusMessage = "OK"; -long lCycleCount = 0; /* Just to remove compiler warning. */ ( void ) pvParameters; @@ -164,10 +186,6 @@ long lCycleCount = 0; { pcStatusMessage = "Error: BlockQueue"; } -// else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) -// { -// pcStatusMessage = "Error: BlockTime"; -// } else if( xAreSemaphoreTasksStillRunning() != pdTRUE ) { pcStatusMessage = "Error: SemTest"; @@ -175,15 +193,15 @@ long lCycleCount = 0; else if( xArePollingQueuesStillRunning() != pdTRUE ) { pcStatusMessage = "Error: PollQueue"; - } - else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) - { - pcStatusMessage = "Error: RecMutex"; } else if( xAreMathsTaskStillRunning() != pdPASS ) { pcStatusMessage = "Error: Flop"; } + else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + pcStatusMessage = "Error: RecMutex"; + } /* This is the only task that uses stdout so its ok to call printf() directly. */