]> git.sur5r.net Git - freertos/commitdiff
Start creating a demo task/test task for the new timer implementation. Still a work...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 9 Feb 2011 19:28:21 +0000 (19:28 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 9 Feb 2011 19:28:21 +0000 (19:28 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1286 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/Common/Minimal/TimerDemo.c [new file with mode: 0644]
Demo/Common/include/TimerDemo.h [new file with mode: 0644]

diff --git a/Demo/Common/Minimal/TimerDemo.c b/Demo/Common/Minimal/TimerDemo.c
new file mode 100644 (file)
index 0000000..00a67c4
--- /dev/null
@@ -0,0 +1,564 @@
+/*\r
+    FreeRTOS V6.1.1 - Copyright (C) 2011 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
+/* \r
+ * Tests the behaviour of timers.  Some timers are created before hte scheudler\r
+ * is started, and some after.\r
+ */\r
+\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+\r
+/* Demo program include files. */\r
+#include "TimerDemo.h"\r
+\r
+#if configTIMER_TASK_PRIORITY < 1\r
+       #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly.\r
+#endif\r
+\r
+#define tmrdemoDONT_BLOCK                              ( ( portTickType ) 0 )\r
+#define tmrdemoONE_SHOT_TIMER_FREQUENCY ( xBaseFrequency * ( portTickType ) 3 )\r
+#define trmdemoNUM_TIMER_RESETS                        ( ( unsigned char ) 10 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvFreeRunningTimerCallback( xTimerHandle pxExpiredTimer );\r
+static void prvTimerControlTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdFAIL should any unexpected behaviour be\r
+detected in any of the demo tests. */\r
+static volatile portBASE_TYPE xTestStatus = pdPASS;\r
+\r
+/* Counter that is incremented on each cycle of a test.  This is used to\r
+detect a stalled task - a test that is no longer running. */\r
+static volatile unsigned portLONG ulLoopCounter = 0;\r
+\r
+xTimerHandle xFreeRunningTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
+unsigned char ucFreeRunningTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 };\r
+unsigned char ucOneShotTimerCounter = ( unsigned char ) 0;\r
+\r
+static portTickType xBaseFrequency = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartTimerDemoTask( portTickType xBaseFrequencyIn )\r
+{\r
+portBASE_TYPE xTimer;\r
+\r
+       xBaseFrequency = xBaseFrequencyIn;\r
+\r
+       for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ )\r
+       {\r
+               /* As the timer queue is not yet full, it should be possible to both create\r
+               and start a timer.  These timers are being started before the scheduler has\r
+               been started, so their block times should get set to zero within the timer\r
+               API itself. */\r
+               xFreeRunningTimers[ xTimer ] = xTimerCreate( "FR Timer",                                                /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
+                                                                                                       ( ( xTimer + 1 ) * xBaseFrequency ),/* The period for the timer.  The plus 1 ensures a period of zero is not specified. */\r
+                                                                                                       pdTRUE,                                                         /* Autoreload is set to true. */\r
+                                                                                                       ( void * ) xTimer,                                      /* An identifier for the timer as all the free running timers use the same callback. */\r
+                                                                                                       prvFreeRunningTimerCallback );          /* The callback to be called when the timer expires. */\r
+\r
+               if( xFreeRunningTimers[ xTimer ] == NULL )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+               else\r
+               {\r
+                       /* The scheduler has not yet started, so the block period of \r
+                       portMAX_DELAY should just get set to zero in xTimerStart().  Also,\r
+                       the timer queue is not yet full so xTimerStart() should return\r
+                       pdPASS. */\r
+                       if( xTimerStart( xFreeRunningTimers[ xTimer ], portMAX_DELAY ) != pdPASS )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /* The timers queue should now be full, so it should be possible to create\r
+       another timer, but not possible to start it (the timer queue will not get\r
+       drained until the scheduler has been started. */\r
+       xFreeRunningTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer",              /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
+                                                                                                       ( configTIMER_QUEUE_LENGTH * xBaseFrequency ),  /* The period for the timer. */\r
+                                                                                                       pdTRUE,                                                 /* Autoreload is set to true. */\r
+                                                                                                       ( void * ) xTimer,                              /* An identifier for the timer as all the free running timers use the same callback. */\r
+                                                                                                       prvFreeRunningTimerCallback );  /* The callback to be called when the timer expires. */\r
+\r
+       if( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH ] == NULL )\r
+       {\r
+               xTestStatus = pdFAIL;\r
+       }\r
+       else\r
+       {\r
+               if( xTimerStart( xFreeRunningTimers[ xTimer ], portMAX_DELAY ) == pdPASS )\r
+               {\r
+                       /* This time it would not be expected that the timer could be\r
+                       started at this point. */\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+       }\r
+\r
+       /* Create the task that will control and monitor the timers.  This is \r
+       created at a lower priority than the timer service task to ensure, as\r
+       far as it is concerned, commands on timers are actioned immediately \r
+       (sending a command to the timer service task will unblock the timer service\r
+       task, which will then preempt this task). */\r
+       if( xTestStatus != pdFAIL )\r
+       {\r
+               xTaskCreate( prvTimerControlTask, ( signed portCHAR * ) "Tmr Ctl", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvFreeRunningTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+portBASE_TYPE xTimerID;\r
+\r
+       xTimerID = ( portBASE_TYPE ) pvTimerGetTimerID( pxExpiredTimer );\r
+       if( xTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) )\r
+       {\r
+               ( ucFreeRunningTimerCounters[ xTimerID ] )++;\r
+       }\r
+       else\r
+       {\r
+               /* The timer ID appears to be unexpected (invalid). */\r
+               xTestStatus = pdFAIL;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvOneShotTimerCallback( xTimerHandle pxExpiredTimer )\r
+{\r
+       /* The parameter is not used in this case as only one timer uses this\r
+       callback function. */\r
+       ( void ) pxExpiredTimer;\r
+\r
+       ucOneShotTimerCounter++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTimerControlTask( void *pvParameters )\r
+{\r
+portTickType xNextWakeTime;\r
+unsigned char ucTimer;\r
+unsigned char ucMaxAllowableValue, ucMinAllowableValue;\r
+xTimerHandle xOneShotTimer = NULL;\r
+\r
+       ( void ) pvParameters;\r
+\r
+       /* Create a one-shot timer for use later on in this test. */\r
+       xOneShotTimer = xTimerCreate(   "Oneshot Timer",                                /* Text name to facilitate debugging.  The kernel does not use this itself. */\r
+                                                                       tmrdemoONE_SHOT_TIMER_FREQUENCY,/* The period for the timer. */\r
+                                                                       pdFALSE,                                                /* Don't autoreload - hence a one shot timer. */\r
+                                                                       ( void * ) 0,                                   /* The timer identifier.  In this case this is not used as the timer has its own callback. */\r
+                                                                       prvOneShotTimerCallback );              /* The callback to be called when the timer expires. */\r
+\r
+       if( xOneShotTimer == NULL )\r
+       {\r
+               xTestStatus = pdFAIL;\r
+       }\r
+\r
+\r
+       /*-----------------------------------------------------------*/\r
+       /* Test 1 - ensure all the timers are in their expected initial state.  This\r
+       depends on the timer service task having a higher priority than this task. */\r
+\r
+       /* Free running timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now\r
+       be active, and free running timer configTIMER_QUEUE_LENGTH should not\r
+       yet be active (it could not be started prior to the scheduler being\r
+       started. */\r
+       for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+       {\r
+               if( xTimerIsTimerActive( xFreeRunningTimers[ ucTimer ] ) == pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+       }\r
+\r
+       if( xTimerIsTimerActive( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE )\r
+       {\r
+               xTestStatus = pdFAIL;\r
+       }\r
+\r
+       for( ;; )\r
+       {\r
+               /*-----------------------------------------------------------*/\r
+               /* Test 2 - Check the free running timers expire at the expcted rates. */\r
+\r
+               /* Initialise the next wake time value before the call to \r
+               vTaskDelayUntil() as this is not really a periodic task. */\r
+               xNextWakeTime = xTaskGetTickCount();\r
+\r
+               /* Delaying for configTIMER_QUEUE_LENGTH * xBaseFrequency ticks \r
+               should allow all the free running timers to expire at least once. */\r
+               vTaskDelayUntil( &xNextWakeTime, ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBaseFrequency );\r
+\r
+               /* Check that all the free running timers have called their callback \r
+               function the expected number of times. */\r
+               for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+               {\r
+                       /* The timer in array position 0 should elapse every xBaseFrequency \r
+                       ticks, the timer in array position 1 should elapse every\r
+                       ( 2 * xBaseFrequency ) ticks, etc.  This task blocked for \r
+                       configTIMER_QUEUE_LENGTH * xBaseFrequency, so the timer in array\r
+                       position 0 should have elapsed configTIMER_QUEUE_LENGTH times, the\r
+                       timer in array possition 1 should have elapsed \r
+                       ( configTIMER_QUEUE_LENGTH - 1 ) times, etc. */\r
+                       ucMaxAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer );\r
+                       ucMinAllowableValue = ( ( ( unsigned char ) configTIMER_QUEUE_LENGTH ) - ucTimer ) - 1;\r
+\r
+                       if( ( ucFreeRunningTimerCounters[ ucTimer ] < ucMinAllowableValue ) ||\r
+                               ( ucFreeRunningTimerCounters[ ucTimer ] > ucMaxAllowableValue )\r
+                         )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+               }\r
+\r
+               if( xTestStatus == pdPASS )\r
+               {\r
+                       /* No errors have been reported so increment the loop counter so\r
+                       the check task knows this task is still running. */\r
+                       ulLoopCounter++;\r
+               }\r
+\r
+\r
+\r
+\r
+               /*-----------------------------------------------------------*/\r
+               /* Test 3 - Check the free running timers can be stopped correctly, and\r
+               correctly report their state. */\r
+\r
+               /* Stop all the active timers. */\r
+               for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+               {\r
+                       /* The timer has not been stopped yet! */\r
+                       if( xTimerIsTimerActive( xFreeRunningTimers[ ucTimer ] ) == pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       /* Now stop the timer.  This will appear to happen immediately to \r
+                       this task because this task is running at a priority below the \r
+                       timer service task. */\r
+                       xTimerStop( xFreeRunningTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
+\r
+                       /* The timer should now be inactive. */\r
+                       if( xTimerIsTimerActive( xFreeRunningTimers[ ucTimer ] ) != pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+               }\r
+\r
+               taskENTER_CRITICAL();\r
+               {\r
+                       /* The timer in array position configTIMER_QUEUE_LENGTH should not \r
+                       be active.  The critical section is used to ensure the timer does \r
+                       not call its callback between the next line running and the array \r
+                       being cleared back to zero, as that would mask an error condition. */\r
+                       if( ucFreeRunningTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( unsigned char ) 0 )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       /* Clear the timer callback count. */\r
+                       memset( ( void * ) ucFreeRunningTimerCounters, 0, sizeof( ucFreeRunningTimerCounters ) );\r
+               }\r
+               taskEXIT_CRITICAL();\r
+\r
+               /* The timers are now all inactive, so this time, after delaying, none\r
+               of the callback counters should have incremented. */\r
+               vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBaseFrequency );\r
+               for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+               {\r
+                       if( ucFreeRunningTimerCounters[ ucTimer ] != ( unsigned char ) 0 )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+               }\r
+\r
+               if( xTestStatus == pdPASS )\r
+               {\r
+                       /* No errors have been reported so increment the loop counter so\r
+                       the check task knows this task is still running. */\r
+                       ulLoopCounter++;\r
+               }\r
+\r
+\r
+\r
+               /*-----------------------------------------------------------*/\r
+               /* Test 4 - Check the one shot timer only calls its callback once after\r
+               it has been started, and that it reports its state correctly. */\r
+\r
+               /* The one shot timer should not be active yet. */\r
+               if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* Start the one shot timer and check that it reports its state\r
+               correctly. */\r
+               xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+               if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* Delay for three times as long as the one shot timer period, then\r
+               check to ensure it has only called its callback once, and is now\r
+               not in the active state. */\r
+               vTaskDelay( tmrdemoONE_SHOT_TIMER_FREQUENCY * ( portTickType ) 3 );\r
+\r
+               if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+               else\r
+               {\r
+                       /* Reset the one shot timer callback count. */\r
+                       ucOneShotTimerCounter = ( unsigned char ) 0;\r
+               }\r
+\r
+               if( xTestStatus == pdPASS )\r
+               {\r
+                       /* No errors have been reported so increment the loop counter so\r
+                       the check task knows this task is still running. */\r
+                       ulLoopCounter++;\r
+               }\r
+\r
+\r
+\r
+\r
+               /*-----------------------------------------------------------*/\r
+               /* Test 5 - Check all the timers can be reset while they are running. */\r
+\r
+               /* Restart the one shot timer and check it reports its status \r
+               correctly. */\r
+               xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+               if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* Restart one of the free running timers and check that it reports its\r
+               status correctly. */\r
+               xTimerStart( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+               if( xTimerIsTimerActive( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ )\r
+               {\r
+                       /* Delay for half as long as the one shot timer period, then\r
+                       reset it.  It should never expire while this is done, so its callback\r
+                       count should never increment. */\r
+                       vTaskDelay( tmrdemoONE_SHOT_TIMER_FREQUENCY / 2 );\r
+\r
+                       /* Check both running timers are still active, but have not called their\r
+                       callback functions. */\r
+                       if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       if( ucOneShotTimerCounter != ( unsigned char ) 0 )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       if( xTimerIsTimerActive( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       if( ucFreeRunningTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( unsigned char ) 0 )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       /* Reset both running timers. */\r
+                       xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK );\r
+                       xTimerReset( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+\r
+                       if( xTestStatus == pdPASS )\r
+                       {\r
+                               /* No errors have been reported so increment the loop counter so\r
+                               the check task knows this task is still running. */\r
+                               ulLoopCounter++;\r
+                       }\r
+               }\r
+\r
+               /* Finally delay long enough for both running timers to expire. */\r
+               vTaskDelay( ( ( portTickType ) configTIMER_QUEUE_LENGTH ) * xBaseFrequency );\r
+\r
+               /* The timers were not reset during the above delay period so should now\r
+               both have called their callback functions. */\r
+               if( ucOneShotTimerCounter != ( unsigned char ) 1 )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               if( ucFreeRunningTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* The one shot timer should no longer be active, while the free running\r
+               timer should still be active. */\r
+               if( xTimerIsTimerActive( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* Stop the free running timer again. */\r
+               xTimerStop( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK );\r
+\r
+               if( xTimerIsTimerActive( xFreeRunningTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE )\r
+               {\r
+                       xTestStatus = pdFAIL;\r
+               }\r
+\r
+               /* Clear the timer callback counts, ready for another iteration of these\r
+               tests. */\r
+               ucFreeRunningTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( unsigned char ) 0;\r
+               ucOneShotTimerCounter = ( unsigned char ) 0;\r
+\r
+               if( xTestStatus == pdPASS )\r
+               {\r
+                       /* No errors have been reported so increment the loop counter so\r
+                       the check task knows this task is still running. */\r
+                       ulLoopCounter++;\r
+               }\r
+\r
+\r
+\r
+\r
+               /*-----------------------------------------------------------*/\r
+               /* Start the timers again to start all the tests over again. */\r
+\r
+\r
+               /* Start the timers again. */\r
+               for( ucTimer = 0; ucTimer < ( unsigned char ) configTIMER_QUEUE_LENGTH; ucTimer++ )\r
+               {\r
+                       /* The timer has not been started yet! */\r
+                       if( xTimerIsTimerActive( xFreeRunningTimers[ ucTimer ] ) != pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+\r
+                       /* Now start the timer.  This will appear to happen immediately to \r
+                       this task because this task is running at a priority below the \r
+                       timer service task. */\r
+                       xTimerStart( xFreeRunningTimers[ ucTimer ], tmrdemoDONT_BLOCK );\r
+\r
+                       /* The timer should now be active. */\r
+                       if( xTimerIsTimerActive( xFreeRunningTimers[ ucTimer ] ) == pdFALSE )\r
+                       {\r
+                               xTestStatus = pdFAIL;\r
+                       }\r
+               }\r
+\r
+               if( xTestStatus == pdPASS )\r
+               {\r
+                       /* No errors have been reported so increment the loop counter so\r
+                       the check task knows this task is still running. */\r
+                       ulLoopCounter++;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that the created task is still running and has not\r
+detected any errors. */\r
+portBASE_TYPE xAreTimerDemoTasksStillRunning( void )\r
+{\r
+static unsigned portLONG ulLastLoopCounter = 0;\r
+\r
+       /* If the demo task is still running then we expect the loopcounter to\r
+       have incremented since this function was last called. */\r
+       if( ulLastLoopCounter == ulLoopCounter )\r
+       {\r
+               xTestStatus = pdFAIL;\r
+       }\r
+\r
+       ulLastLoopCounter = ulLoopCounter;\r
+\r
+       /* Errors detected in the task itself will have latched xTestStatus\r
+       to pdFAIL. */\r
+\r
+       return xTestStatus;\r
+}\r
+\r
diff --git a/Demo/Common/include/TimerDemo.h b/Demo/Common/include/TimerDemo.h
new file mode 100644 (file)
index 0000000..1c2c539
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+    FreeRTOS V6.1.1 - Copyright (C) 2011 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
+#ifndef TIMER_DEMO_H\r
+#define TIMER_DEMO_H\r
+\r
+void vStartTimerDemoTask( portTickType xBaseFrequencyIn );\r
+portBASE_TYPE xAreTimerDemoTasksStillRunning( void );\r
+\r
+#endif /* TIMER_DEMO_H */\r
+\r
+\r
+\r