]> git.sur5r.net Git - freertos/commitdiff
Add the common demo files to the MicroBlaze project - this directory will be removed...
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 16 Jun 2011 19:47:49 +0000 (19:47 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 16 Jun 2011 19:47:49 +0000 (19:47 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1463 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

23 files changed:
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/BlockQ.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/GenQTest.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/PollQ.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/QPeek.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/blocktim.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/death.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/dynamic.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/flash.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/BlockQ.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/GenQTest.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/PollQ.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/QPeek.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/blocktim.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/death.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/dynamic.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flash.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flop.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/partest.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/recmutex.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/semtest.h [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/recmutex.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/semtest.c [new file with mode: 0644]
Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/sp_flop.c [new file with mode: 0644]

diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/BlockQ.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/BlockQ.c
new file mode 100644 (file)
index 0000000..cc9e35c
--- /dev/null
@@ -0,0 +1,308 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * Creates six tasks that operate on three queues as follows:\r
+ *\r
+ * The first two tasks send and receive an incrementing number to/from a queue.\r
+ * One task acts as a producer and the other as the consumer.  The consumer is a\r
+ * higher priority than the producer and is set to block on queue reads.  The queue\r
+ * only has space for one item - as soon as the producer posts a message on the\r
+ * queue the consumer will unblock, pre-empt the producer, and remove the item.\r
+ *\r
+ * The second two tasks work the other way around.  Again the queue used only has\r
+ * enough space for one item.  This time the consumer has a lower priority than the\r
+ * producer.  The producer will try to post on the queue blocking when the queue is\r
+ * full.  When the consumer wakes it will remove the item from the queue, causing\r
+ * the producer to unblock, pre-empt the consumer, and immediately re-fill the\r
+ * queue.\r
+ *\r
+ * The last two tasks use the same queue producer and consumer functions.  This time the queue has\r
+ * enough space for lots of items and the tasks operate at the same priority.  The\r
+ * producer will execute, placing items into the queue.  The consumer will start\r
+ * executing when either the queue becomes full (causing the producer to block) or\r
+ * a context switch occurs (tasks of the same priority will time slice).\r
+ *\r
+ */\r
+\r
+/*\r
+\r
+Changes from V4.1.1\r
+\r
+       + The second set of tasks were created the wrong way around.  This has been\r
+         corrected.\r
+*/\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Demo program include files. */\r
+#include "BlockQ.h"\r
+\r
+#define blckqSTACK_SIZE                configMINIMAL_STACK_SIZE\r
+#define blckqNUM_TASK_SETS     ( 3 )\r
+\r
+/* Structure used to pass parameters to the blocking queue tasks. */\r
+typedef struct BLOCKING_QUEUE_PARAMETERS\r
+{\r
+       xQueueHandle xQueue;                                    /*< The queue to be used by the task. */\r
+       portTickType xBlockTime;                                /*< The block time to use on queue reads/writes. */\r
+       volatile short *psCheckVariable;        /*< Incremented on each successful cycle to check the task is still running. */\r
+} xBlockingQueueParameters;\r
+\r
+/* Task function that creates an incrementing number and posts it on a queue. */\r
+static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters );\r
+\r
+/* Task function that removes the incrementing number from a queue and checks that\r
+it is the expected number. */\r
+static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters );\r
+\r
+/* Variables which are incremented each time an item is removed from a queue, and\r
+found to be the expected value.\r
+These are used to check that the tasks are still running. */\r
+static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };\r
+\r
+/* Variable which are incremented each time an item is posted on a queue.   These\r
+are used to check that the tasks are still running. */\r
+static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2;\r
+xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4;\r
+xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6;\r
+const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5;\r
+const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS;\r
+const portTickType xDontBlock = ( portTickType ) 0;\r
+\r
+       /* Create the first two tasks as described at the top of the file. */\r
+       \r
+       /* First create the structure used to pass parameters to the consumer tasks. */\r
+       pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+\r
+       /* Create the queue used by the first two tasks to pass the incrementing number.\r
+       Pass a pointer to the queue in the parameter structure. */\r
+       pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );\r
+\r
+       /* The consumer is created first so gets a block time as described above. */\r
+       pxQueueParameters1->xBlockTime = xBlockTime;\r
+\r
+       /* Pass in the variable that this task is going to increment so we can check it\r
+       is still running. */\r
+       pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] );\r
+               \r
+       /* Create the structure used to pass parameters to the producer task. */\r
+       pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+\r
+       /* Pass the queue to this task also, using the parameter structure. */\r
+       pxQueueParameters2->xQueue = pxQueueParameters1->xQueue;\r
+\r
+       /* The producer is not going to block - as soon as it posts the consumer will\r
+       wake and remove the item so the producer should always have room to post. */\r
+       pxQueueParameters2->xBlockTime = xDontBlock;\r
+\r
+       /* Pass in the variable that this task is going to increment so we can check\r
+       it is still running. */\r
+       pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] );\r
+\r
+\r
+       /* Note the producer has a lower priority than the consumer when the tasks are\r
+       spawned. */\r
+       xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );\r
+       xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL );\r
+\r
+       \r
+\r
+       /* Create the second two tasks as described at the top of the file.   This uses\r
+       the same mechanism but reverses the task priorities. */\r
+\r
+       pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+       pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );\r
+       pxQueueParameters3->xBlockTime = xDontBlock;\r
+       pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] );\r
+\r
+       pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+       pxQueueParameters4->xQueue = pxQueueParameters3->xQueue;\r
+       pxQueueParameters4->xBlockTime = xBlockTime;\r
+       pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] );\r
+\r
+       xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL );\r
+\r
+\r
+\r
+       /* Create the last two tasks as described above.  The mechanism is again just\r
+       the same.  This time both parameter structures are given a block time. */\r
+       pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+       pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );\r
+       pxQueueParameters5->xBlockTime = xBlockTime;\r
+       pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] );\r
+\r
+       pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) );\r
+       pxQueueParameters6->xQueue = pxQueueParameters5->xQueue;\r
+       pxQueueParameters6->xBlockTime = xBlockTime;\r
+       pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); \r
+\r
+       xTaskCreate( vBlockingQueueProducer, ( signed char * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vBlockingQueueConsumer, ( signed char * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )\r
+{\r
+unsigned short usValue = 0;\r
+xBlockingQueueParameters *pxQueueParameters;\r
+short sErrorEverOccurred = pdFALSE;\r
+\r
+       pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;\r
+\r
+       for( ;; )\r
+       {               \r
+               if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )\r
+               {\r
+                       sErrorEverOccurred = pdTRUE;\r
+               }\r
+               else\r
+               {\r
+                       /* We have successfully posted a message, so increment the variable\r
+                       used to check we are still running. */\r
+                       if( sErrorEverOccurred == pdFALSE )\r
+                       {\r
+                               ( *pxQueueParameters->psCheckVariable )++;\r
+                       }\r
+\r
+                       /* Increment the variable we are going to post next time round.  The\r
+                       consumer will expect the numbers to     follow in numerical order. */\r
+                       ++usValue;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters )\r
+{\r
+unsigned short usData, usExpectedValue = 0;\r
+xBlockingQueueParameters *pxQueueParameters;\r
+short sErrorEverOccurred = pdFALSE;\r
+\r
+       pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;\r
+\r
+       for( ;; )\r
+       {       \r
+               if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS )\r
+               {\r
+                       if( usData != usExpectedValue )\r
+                       {\r
+                               /* Catch-up. */\r
+                               usExpectedValue = usData;\r
+\r
+                               sErrorEverOccurred = pdTRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               /* We have successfully received a message, so increment the\r
+                               variable used to check we are still running. */ \r
+                               if( sErrorEverOccurred == pdFALSE )\r
+                               {\r
+                                       ( *pxQueueParameters->psCheckVariable )++;\r
+                               }\r
+                                                       \r
+                               /* Increment the value we expect to remove from the queue next time\r
+                               round. */\r
+                               ++usExpectedValue;\r
+                       }                       \r
+               }               \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreBlockingQueuesStillRunning( void )\r
+{\r
+static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };\r
+static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned short ) 0, ( unsigned short ) 0, ( unsigned short ) 0 };\r
+portBASE_TYPE xReturn = pdPASS, xTasks;\r
+\r
+       /* Not too worried about mutual exclusion on these variables as they are 16\r
+       bits and we are only reading them. We also only care to see if they have\r
+       changed or not.\r
+       \r
+       Loop through each check variable to and return pdFALSE if any are found not\r
+       to have changed since the last call. */\r
+\r
+       for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ )\r
+       {\r
+               if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ]  )\r
+               {\r
+                       xReturn = pdFALSE;\r
+               }\r
+               sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ];\r
+\r
+\r
+               if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ]  )\r
+               {\r
+                       xReturn = pdFALSE;\r
+               }\r
+               sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ];\r
+       }\r
+\r
+       return xReturn;\r
+}\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/GenQTest.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/GenQTest.c
new file mode 100644 (file)
index 0000000..285620a
--- /dev/null
@@ -0,0 +1,572 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 extra queue functionality introduced in FreeRTOS.org V4.5.0 - \r
+ * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and \r
+ * mutex behaviour. \r
+ *\r
+ * See the comments above the prvSendFrontAndBackTest() and \r
+ * prvLowPriorityMutexTask() prototypes below for more information.\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Demo program include files. */\r
+#include "GenQTest.h"\r
+\r
+#define genqQUEUE_LENGTH               ( 5 )\r
+#define genqNO_BLOCK                   ( 0 )\r
+\r
+#define genqMUTEX_LOW_PRIORITY         ( tskIDLE_PRIORITY )\r
+#define genqMUTEX_TEST_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
+#define genqMUTEX_MEDIUM_PRIORITY      ( tskIDLE_PRIORITY + 2 )\r
+#define genqMUTEX_HIGH_PRIORITY                ( tskIDLE_PRIORITY + 3 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()\r
+ * macros by using both to fill a queue, then reading from the queue to\r
+ * check the resultant queue order is as expected.  Queue data is also\r
+ * peeked.\r
+ */\r
+static void prvSendFrontAndBackTest( void *pvParameters );\r
+\r
+/*\r
+ * The following three tasks are used to demonstrate the mutex behaviour.\r
+ * Each task is given a different priority to demonstrate the priority\r
+ * inheritance mechanism.\r
+ *\r
+ * The low priority task obtains a mutex.  After this a high priority task\r
+ * attempts to obtain the same mutex, causing its priority to be inherited\r
+ * by the low priority task.  The task with the inherited high priority then\r
+ * resumes a medium priority task to ensure it is not blocked by the medium\r
+ * priority task while it holds the inherited high priority.  Once the mutex\r
+ * is returned the task with the inherited priority returns to its original\r
+ * low priority, and is therefore immediately preempted by first the high\r
+ * priority task and then the medium prioroity task before it can continue.\r
+ */\r
+static void prvLowPriorityMutexTask( void *pvParameters );\r
+static void prvMediumPriorityMutexTask( void *pvParameters );\r
+static void prvHighPriorityMutexTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
+detected in any of the tasks. */\r
+static portBASE_TYPE xErrorDetected = pdFALSE;\r
+\r
+/* Counters that are 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
+static volatile unsigned portLONG ulLoopCounter2 = 0;\r
+\r
+/* The variable that is guarded by the mutex in the mutex demo tasks. */\r
+static volatile unsigned portLONG ulGuardedVariable = 0;\r
+\r
+/* Handles used in the mutext test to suspend and resume the high and medium\r
+priority mutex test tasks. */\r
+static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xQueueHandle xQueue;\r
+xSemaphoreHandle xMutex;\r
+\r
+       /* Create the queue that we are going to use for the\r
+       prvSendFrontAndBackTest demo. */\r
+       xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );\r
+\r
+       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+       in use.  The queue registry is provided as a means for kernel aware \r
+       debuggers to locate queues 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( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" );\r
+\r
+       /* Create the demo task and pass it the queue just created.  We are\r
+       passing the queue handle by value so it does not matter that it is\r
+       declared on the stack here. */\r
+       xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );\r
+\r
+       /* Create the mutex used by the prvMutexTest task. */\r
+       xMutex = xSemaphoreCreateMutex();\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 mutexes 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 * ) "Gen_Queue_Mutex" );\r
+\r
+       /* Create the mutex demo tasks and pass it the mutex just created.  We are\r
+       passing the mutex handle by value so it does not matter that it is declared\r
+       on the stack here. */\r
+       xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );\r
+       xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );\r
+       xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSendFrontAndBackTest( void *pvParameters )\r
+{\r
+unsigned portLONG ulData, ulData2;\r
+xQueueHandle xQueue;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       xQueue = ( xQueueHandle ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* The queue is empty, so sending an item to the back of the queue\r
+               should have the same efect as sending it to the front of the queue.\r
+\r
+               First send to the front and check everything is as expected. */\r
+               xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* The data we sent to the queue should equal the data we just received\r
+               from the queue. */\r
+               if( ulLoopCounter != ulData )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Then do the same, sending the data to the back, checking everything\r
+               is as expected. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* The data we sent to the queue should equal the data we just received\r
+               from the queue. */\r
+               if( ulLoopCounter != ulData )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+\r
+\r
+               /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */\r
+               for( ulData = 2; ulData < 5; ulData++ )\r
+               {\r
+                       xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               }\r
+\r
+               /* Now the order in the queue should be 2, 3, 4, with 2 being the first\r
+               thing to be read out.  Now add 1 then 0 to the front of the queue. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 3 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+               ulData = 1;\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               ulData = 0;\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+\r
+               /* Now the queue should be full, and when we read the data out we\r
+               should receive 0, 1, 2, 3, 4. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               /* Check the data we read out is in the expected order. */\r
+               for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )\r
+               {\r
+                       /* Try peeking the data first. */\r
+                       if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+                       \r
+\r
+                       /* Now try receiving the data for real.  The value should be the\r
+                       same.  Clobber the value first so we know we really received it. */\r
+                       ulData2 = ~ulData2;\r
+                       if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* The queue should now be empty again. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+\r
+               /* Our queue is empty once more, add 10, 11 to the back. */\r
+               ulData = 10;\r
+               if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+               ulData = 11;\r
+               if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 2 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now we should have 10, 11 in the queue.  Add 7, 8, 9 to the\r
+               front. */\r
+               for( ulData = 9; ulData >= 7; ulData-- )\r
+               {\r
+                       if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Now check that the queue is full, and that receiving data provides\r
+               the expected sequence of 7, 8, 9, 10, 11. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               /* Check the data we read out is in the expected order. */\r
+               for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )\r
+               {\r
+                       if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               ulLoopCounter++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       for( ;; )\r
+       {\r
+               /* Take the mutex.  It should be available now. */\r
+               if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Set our guarded variable to a known start value. */\r
+               ulGuardedVariable = 0;\r
+\r
+               /* Our priority should be as per that assigned when the task was\r
+               created. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now unsuspend the high priority task.  This will attempt to take the\r
+               mutex, and block when it finds it cannot obtain it. */\r
+               vTaskResume( xHighPriorityMutexTask );\r
+\r
+               /* We should now have inherited the prioritoy of the high priority task,\r
+               as by now it will have attempted to get the mutex. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* We can attempt to set our priority to the test priority - between the\r
+               idle priority and the medium/high test priorities, but our actual\r
+               prioroity should remain at the high priority. */\r
+               vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now unsuspend the medium priority task.  This should not run as our\r
+               inherited priority is above that of the medium priority task. */\r
+               vTaskResume( xMediumPriorityMutexTask );\r
+\r
+               /* If the did run then it will have incremented our guarded variable. */\r
+               if( ulGuardedVariable != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we give back the semaphore our priority should be disinherited\r
+               back to the priority to which we attempted to set ourselves.  This means\r
+               that when the high priority task next blocks, the medium priority task\r
+               should execute and increment the guarded variable.   When we next run\r
+               both the high and medium priority tasks will have been suspended again. */\r
+               if( xSemaphoreGive( xMutex ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Check that the guarded variable did indeed increment... */\r
+               if( ulGuardedVariable != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* ... and that our priority has been disinherited to\r
+               genqMUTEX_TEST_PRIORITY. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Set our priority back to our original priority ready for the next\r
+               loop around this test. */\r
+               vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );\r
+\r
+               /* Just to show we are still running. */\r
+               ulLoopCounter2++;\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif          \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMediumPriorityMutexTask( void *pvParameters )\r
+{\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* The medium priority task starts by suspending itself.  The low\r
+               priority task will unsuspend this task when required. */\r
+               vTaskSuspend( NULL );\r
+\r
+               /* When this task unsuspends all it does is increment the guarded\r
+               variable, this is so the low priority task knows that it has\r
+               executed. */\r
+               ulGuardedVariable++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHighPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* The high priority task starts by suspending itself.  The low\r
+               priority task will unsuspend this task when required. */\r
+               vTaskSuspend( NULL );\r
+\r
+               /* When this task unsuspends all it does is attempt to obtain\r
+               the mutex.  It should find the mutex is not available so a\r
+               block time is specified. */\r
+               if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we eventually obtain the mutex we just give it back then\r
+               return to suspend ready for the next test. */\r
+               if( xSemaphoreGive( xMutex ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }               \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void )\r
+{\r
+static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;\r
+\r
+       /* If the demo task is still running then we expect the loopcounters to\r
+       have incremented since this function was last called. */\r
+       if( ulLastLoopCounter == ulLoopCounter )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       if( ulLastLoopCounter2 == ulLoopCounter2 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       ulLastLoopCounter = ulLoopCounter;\r
+       ulLastLoopCounter2 = ulLoopCounter2;    \r
+\r
+       /* Errors detected in the task itself will have latched xErrorDetected\r
+       to true. */\r
+\r
+       return !xErrorDetected;\r
+}\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/PollQ.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/PollQ.c
new file mode 100644 (file)
index 0000000..78ada9d
--- /dev/null
@@ -0,0 +1,246 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * This version of PollQ. c is for use on systems that have limited stack\r
+ * space and no display facilities.  The complete version can be found in\r
+ * the Demo/Common/Full directory.\r
+ *\r
+ * Creates two tasks that communicate over a single queue.  One task acts as a\r
+ * producer, the other a consumer.\r
+ *\r
+ * The producer loops for three iteration, posting an incrementing number onto the\r
+ * queue each cycle.  It then delays for a fixed period before doing exactly the\r
+ * same again.\r
+ *\r
+ * The consumer loops emptying the queue.  Each item removed from the queue is\r
+ * checked to ensure it contains the expected value.  When the queue is empty it\r
+ * blocks for a fixed period, then does the same again.\r
+ *\r
+ * All queue access is performed without blocking.  The consumer completely empties\r
+ * the queue each time it runs so the producer should never find the queue full.\r
+ *\r
+ * An error is flagged if the consumer obtains an unexpected value or the producer\r
+ * find the queue is full.\r
+ */\r
+\r
+/*\r
+Changes from V2.0.0\r
+\r
+       + Delay periods are now specified using variables and constants of\r
+         portTickType rather than unsigned long.\r
+*/\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Demo program include files. */\r
+#include "PollQ.h"\r
+\r
+#define pollqSTACK_SIZE                        configMINIMAL_STACK_SIZE\r
+#define pollqQUEUE_SIZE                        ( 10 )\r
+#define pollqPRODUCER_DELAY            ( ( portTickType ) 200 / portTICK_RATE_MS )\r
+#define pollqCONSUMER_DELAY            ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) )\r
+#define pollqNO_DELAY                  ( ( portTickType ) 0 )\r
+#define pollqVALUES_TO_PRODUCE ( ( signed portBASE_TYPE ) 3 )\r
+#define pollqINITIAL_VALUE             ( ( signed portBASE_TYPE ) 0 )\r
+\r
+/* The task that posts the incrementing number onto the queue. */\r
+static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters );\r
+\r
+/* The task that empties the queue. */\r
+static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters );\r
+\r
+/* Variables that are used to check that the tasks are still running with no\r
+errors. */\r
+static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+static xQueueHandle xPolledQueue;\r
+\r
+       /* Create the queue used by the producer and consumer. */\r
+       xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );\r
+\r
+       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+       in use.  The queue registry is provided as a means for kernel aware \r
+       debuggers to locate queues 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( xPolledQueue, ( signed char * ) "Poll_Test_Queue" );\r
+\r
+       /* Spawn the producer and consumer. */\r
+       xTaskCreate( vPolledQueueConsumer, ( signed char * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
+       xTaskCreate( vPolledQueueProducer, ( signed char * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )\r
+{\r
+unsigned short usValue = ( unsigned short ) 0;\r
+signed portBASE_TYPE xError = pdFALSE, xLoop;\r
+\r
+       for( ;; )\r
+       {               \r
+               for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )\r
+               {\r
+                       /* Send an incrementing number on the queue without blocking. */\r
+                       if( xQueueSend( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )\r
+                       {\r
+                               /* We should never find the queue full so if we get here there\r
+                               has been an error. */\r
+                               xError = pdTRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               if( xError == pdFALSE )\r
+                               {\r
+                                       /* If an error has ever been recorded we stop incrementing the\r
+                                       check variable. */\r
+                                       portENTER_CRITICAL();\r
+                                               xPollingProducerCount++;\r
+                                       portEXIT_CRITICAL();\r
+                               }\r
+\r
+                               /* Update the value we are going to post next time around. */\r
+                               usValue++;\r
+                       }\r
+               }\r
+\r
+               /* Wait before we start posting again to ensure the consumer runs and\r
+               empties the queue. */\r
+               vTaskDelay( pollqPRODUCER_DELAY );\r
+       }\r
+}  /*lint !e818 Function prototype must conform to API. */\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )\r
+{\r
+unsigned short usData, usExpectedValue = ( unsigned short ) 0;\r
+signed portBASE_TYPE xError = pdFALSE;\r
+\r
+       for( ;; )\r
+       {               \r
+               /* Loop until the queue is empty. */\r
+               while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) )\r
+               {\r
+                       if( xQueueReceive( *( ( xQueueHandle * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS )\r
+                       {\r
+                               if( usData != usExpectedValue )\r
+                               {\r
+                                       /* This is not what we expected to receive so an error has\r
+                                       occurred. */\r
+                                       xError = pdTRUE;\r
+\r
+                                       /* Catch-up to the value we received so our next expected\r
+                                       value should again be correct. */\r
+                                       usExpectedValue = usData;\r
+                               }\r
+                               else\r
+                               {\r
+                                       if( xError == pdFALSE )\r
+                                       {\r
+                                               /* Only increment the check variable if no errors have\r
+                                               occurred. */\r
+                                               portENTER_CRITICAL();\r
+                                                       xPollingConsumerCount++;\r
+                                               portEXIT_CRITICAL();\r
+                                       }\r
+                               }\r
+\r
+                               /* Next time round we would expect the number to be one higher. */\r
+                               usExpectedValue++;\r
+                       }\r
+               }\r
+\r
+               /* Now the queue is empty we block, allowing the producer to place more\r
+               items in the queue. */\r
+               vTaskDelay( pollqCONSUMER_DELAY );\r
+       }\r
+} /*lint !e818 Function prototype must conform to API. */\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running with no errors. */\r
+portBASE_TYPE xArePollingQueuesStillRunning( void )\r
+{\r
+portBASE_TYPE xReturn;\r
+\r
+       /* Check both the consumer and producer poll count to check they have both\r
+       been changed since out last trip round.  We do not need a critical section\r
+       around the check variables as this is called from a higher priority than\r
+       the other tasks that access the same variables. */\r
+       if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) ||\r
+               ( xPollingProducerCount == pollqINITIAL_VALUE )\r
+         )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+       else\r
+       {\r
+               xReturn = pdTRUE;\r
+       }\r
+\r
+       /* Set the check variables back down so we know if they have been\r
+       incremented the next time around. */\r
+       xPollingConsumerCount = pollqINITIAL_VALUE;\r
+       xPollingProducerCount = pollqINITIAL_VALUE;\r
+\r
+       return xReturn;\r
+}\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/QPeek.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/QPeek.c
new file mode 100644 (file)
index 0000000..a0edc61
--- /dev/null
@@ -0,0 +1,446 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 when data is peeked from a queue when there are\r
+ * multiple tasks blocked on the queue.\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Demo program include files. */\r
+#include "QPeek.h"\r
+\r
+#define qpeekQUEUE_LENGTH              ( 5 )\r
+#define qpeekNO_BLOCK                  ( 0 )\r
+#define qpeekSHORT_DELAY               ( 10 )\r
+\r
+#define qpeekLOW_PRIORITY                      ( tskIDLE_PRIORITY + 0 )\r
+#define qpeekMEDIUM_PRIORITY           ( tskIDLE_PRIORITY + 1 )\r
+#define qpeekHIGH_PRIORITY                     ( tskIDLE_PRIORITY + 2 )\r
+#define qpeekHIGHEST_PRIORITY          ( tskIDLE_PRIORITY + 3 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The following three tasks are used to demonstrate the peeking behaviour.\r
+ * Each task is given a different priority to demonstrate the order in which\r
+ * tasks are woken as data is peeked from a queue.\r
+ */\r
+static void prvLowPriorityPeekTask( void *pvParameters );\r
+static void prvMediumPriorityPeekTask( void *pvParameters );\r
+static void prvHighPriorityPeekTask( void *pvParameters );\r
+static void prvHighestPriorityPeekTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
+detected in any of the tasks. */\r
+static volatile portBASE_TYPE xErrorDetected = pdFALSE;\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
+/* Handles to the test tasks. */\r
+xTaskHandle xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask;\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartQueuePeekTasks( void )\r
+{\r
+xQueueHandle xQueue;\r
+\r
+       /* Create the queue that we are going to use for the test/demo. */\r
+       xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( unsigned portLONG ) );\r
+\r
+       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+       in use.  The queue registry is provided as a means for kernel aware \r
+       debuggers to locate queues 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( xQueue, ( signed portCHAR * ) "QPeek_Test_Queue" );\r
+\r
+       /* Create the demo tasks and pass it the queue just created.  We are\r
+       passing the queue handle by value so it does not matter that it is declared\r
+       on the stack here. */\r
+       xTaskCreate( prvLowPriorityPeekTask, ( signed portCHAR * )"PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );\r
+       xTaskCreate( prvMediumPriorityPeekTask, ( signed portCHAR * )"PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );\r
+       xTaskCreate( prvHighPriorityPeekTask, ( signed portCHAR * )"PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );\r
+       xTaskCreate( prvHighestPriorityPeekTask, ( signed portCHAR * )"PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHighestPriorityPeekTask( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;\r
+unsigned portLONG ulValue;\r
+\r
+       #ifdef USE_STDIO\r
+       {\r
+               void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Queue peek test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       }\r
+       #endif\r
+\r
+       for( ;; )\r
+       {\r
+               /* Try peeking from the queue.  The queue should be empty so we will\r
+               block, allowing the high priority task to execute. */\r
+               if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       /* We expected to have received something by the time we unblock. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we reach here the high and medium priority tasks should still\r
+               be blocked on the queue.  We unblocked because the low priority task\r
+               wrote a value to the queue, which we should have peeked.  Peeking the\r
+               data (rather than receiving it) will leave the data on the queue, so\r
+               the high priority task should then have also been unblocked, but not\r
+               yet executed. */\r
+               if( ulValue != 0x11223344 )\r
+               {\r
+                       /* We did not receive the expected value. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       /* The message should have been left on the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now we are going to actually receive the data, so when the high\r
+               priority task runs it will find the queue empty and return to the\r
+               blocked state. */\r
+               ulValue = 0;\r
+               if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )\r
+               {\r
+                       /* We expected to receive the value. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( ulValue != 0x11223344 )\r
+               {\r
+                       /* We did not receive the expected value - which should have been\r
+                       the same value as was peeked. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now we will block again as the queue is once more empty.  The low \r
+               priority task can then execute again. */\r
+               if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       /* We expected to have received something by the time we unblock. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we get here the low priority task should have again written to the\r
+               queue. */\r
+               if( ulValue != 0x01234567 )\r
+               {\r
+                       /* We did not receive the expected value. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       /* The message should have been left on the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* We only peeked the data, so suspending ourselves now should enable\r
+               the high priority task to also peek the data.  The high priority task\r
+               will have been unblocked when we peeked the data as we left the data\r
+               in the queue. */\r
+               vTaskSuspend( NULL );\r
+\r
+\r
+\r
+               /* This time we are going to do the same as the above test, but the\r
+               high priority task is going to receive the data, rather than peek it.\r
+               This means that the medium priority task should never peek the value. */\r
+               if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( ulValue != 0xaabbaabb )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               vTaskSuspend( NULL );           \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHighPriorityPeekTask( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;\r
+unsigned portLONG ulValue;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Try peeking from the queue.  The queue should be empty so we will\r
+               block, allowing the medium priority task to execute.  Both the high\r
+               and highest priority tasks will then be blocked on the queue. */\r
+               if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       /* We expected to have received something by the time we unblock. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we get here the highest priority task should have peeked the data\r
+               (unblocking this task) then suspended (allowing this task to also peek\r
+               the data). */\r
+               if( ulValue != 0x01234567 )\r
+               {\r
+                       /* We did not receive the expected value. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       /* The message should have been left on the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* We only peeked the data, so suspending ourselves now should enable\r
+               the medium priority task to also peek the data.  The medium priority task\r
+               will have been unblocked when we peeked the data as we left the data\r
+               in the queue. */\r
+               vTaskSuspend( NULL );\r
+\r
+\r
+               /* This time we are going actually receive the value, so the medium\r
+               priority task will never peek the data - we removed it from the queue. */\r
+               if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( ulValue != 0xaabbaabb )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               vTaskSuspend( NULL );                           \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMediumPriorityPeekTask( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;\r
+unsigned portLONG ulValue;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Try peeking from the queue.  The queue should be empty so we will\r
+               block, allowing the low priority task to execute.  The highest, high\r
+               and medium priority tasks will then all be blocked on the queue. */\r
+               if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       /* We expected to have received something by the time we unblock. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we get here the high priority task should have peeked the data\r
+               (unblocking this task) then suspended (allowing this task to also peek\r
+               the data). */\r
+               if( ulValue != 0x01234567 )\r
+               {\r
+                       /* We did not receive the expected value. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       /* The message should have been left on the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Just so we know the test is still running. */\r
+               ulLoopCounter++;\r
+\r
+               /* Now we can suspend ourselves so the low priority task can execute\r
+               again. */\r
+               vTaskSuspend( NULL );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowPriorityPeekTask( void *pvParameters )\r
+{\r
+xQueueHandle xQueue = ( xQueueHandle ) pvParameters;\r
+unsigned portLONG ulValue;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Write some data to the queue.  This should unblock the highest \r
+               priority task that is waiting to peek data from the queue. */\r
+               ulValue = 0x11223344;\r
+               if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )\r
+               {\r
+                       /* We were expecting the queue to be empty so we should not of\r
+                       had a problem writing to the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* By the time we get here the data should have been removed from\r
+               the queue. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Write another value to the queue, again waking the highest priority\r
+               task that is blocked on the queue. */\r
+               ulValue = 0x01234567;\r
+               if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )\r
+               {\r
+                       /* We were expecting the queue to be empty so we should not of\r
+                       had a problem writing to the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* All the other tasks should now have successfully peeked the data.\r
+               The data is still in the queue so we should be able to receive it. */\r
+               ulValue = 0;\r
+               if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )\r
+               {\r
+                       /* We expected to receive the data. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( ulValue != 0x01234567 )\r
+               {\r
+                       /* We did not receive the expected value. */\r
+               }\r
+               \r
+               /* Lets just delay a while as this is an intensive test as we don't\r
+               want to starve other tests of processing time. */\r
+               vTaskDelay( qpeekSHORT_DELAY );\r
+\r
+               /* Unsuspend the other tasks so we can repeat the test - this time\r
+               however not all the other tasks will peek the data as the high\r
+               priority task is actually going to remove it from the queue.  Send\r
+               to front is used just to be different.  As the queue is empty it\r
+               makes no difference to the result. */\r
+               vTaskResume( xMediumPriorityTask );\r
+               vTaskResume( xHighPriorityTask );\r
+               vTaskResume( xHighestPriorityTask );\r
+\r
+               ulValue = 0xaabbaabb;\r
+               if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )\r
+               {\r
+                       /* We were expecting the queue to be empty so we should not of\r
+                       had a problem writing to the queue. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* This time we should find that the queue is empty.  The high priority\r
+               task actually removed the data rather than just peeking it. */\r
+               if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY )\r
+               {\r
+                       /* We expected to receive the data. */\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Unsuspend the highest and high priority tasks so we can go back\r
+               and repeat the whole thing.  The medium priority task should not be\r
+               suspended as it was not able to peek the data in this last case. */\r
+               vTaskResume( xHighPriorityTask );\r
+               vTaskResume( xHighestPriorityTask );            \r
+\r
+               /* Lets just delay a while as this is an intensive test as we don't\r
+               want to starve other tests of processing time. */\r
+               vTaskDelay( qpeekSHORT_DELAY );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreQueuePeekTasksStillRunning( 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
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       ulLastLoopCounter = ulLoopCounter;\r
+\r
+       /* Errors detected in the task itself will have latched xErrorDetected\r
+       to true. */\r
+\r
+       return !xErrorDetected;\r
+}\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/blocktim.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/blocktim.c
new file mode 100644 (file)
index 0000000..d1606f3
--- /dev/null
@@ -0,0 +1,493 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * This file contains some test scenarios that ensure tasks do not exit queue\r
+ * send or receive functions prematurely.  A description of the tests is\r
+ * included within the code.\r
+ */\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+\r
+/* Demo includes. */\r
+#include "blocktim.h"\r
+\r
+/* Task priorities.  Allow these to be overridden. */\r
+#ifndef bktPRIMARY_PRIORITY\r
+       #define bktPRIMARY_PRIORITY             ( configMAX_PRIORITIES - 3 )\r
+#endif\r
+\r
+#ifndef bktSECONDARY_PRIORITY\r
+       #define bktSECONDARY_PRIORITY   ( configMAX_PRIORITIES - 4 )\r
+#endif\r
+\r
+/* Task behaviour. */\r
+#define bktQUEUE_LENGTH                                ( 5 )\r
+#define bktSHORT_WAIT                          ( ( ( portTickType ) 20 ) / portTICK_RATE_MS )\r
+#define bktPRIMARY_BLOCK_TIME          ( 10 )\r
+#define bktALLOWABLE_MARGIN                    ( 15 )\r
+#define bktTIME_TO_BLOCK                       ( 175 )\r
+#define bktDONT_BLOCK                          ( ( portTickType ) 0 )\r
+#define bktRUN_INDICATOR                       ( ( unsigned portBASE_TYPE ) 0x55 )\r
+\r
+/* The queue on which the tasks block. */\r
+static xQueueHandle xTestQueue;\r
+\r
+/* Handle to the secondary task is required by the primary task for calls\r
+to vTaskSuspend/Resume(). */\r
+static xTaskHandle xSecondary;\r
+\r
+/* Used to ensure that tasks are still executing without error. */\r
+static volatile portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;\r
+static volatile portBASE_TYPE xErrorOccurred = pdFALSE;\r
+\r
+/* Provides a simple mechanism for the primary task to know when the\r
+secondary task has executed. */\r
+static volatile unsigned portBASE_TYPE xRunIndicator;\r
+\r
+/* The two test tasks.  Their behaviour is commented within the files. */\r
+static void vPrimaryBlockTimeTestTask( void *pvParameters );\r
+static void vSecondaryBlockTimeTestTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCreateBlockTimeTasks( void )\r
+{\r
+       /* Create the queue on which the two tasks block. */\r
+    xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) );\r
+\r
+       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+       in use.  The queue registry is provided as a means for kernel aware\r
+       debuggers to locate queues 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( xTestQueue, ( signed char * ) "Block_Time_Queue" );\r
+\r
+       /* Create the two test tasks. */\r
+       xTaskCreate( vPrimaryBlockTimeTestTask, ( signed char * )"BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
+       xTaskCreate( vSecondaryBlockTimeTestTask, ( signed char * )"BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vPrimaryBlockTimeTestTask( void *pvParameters )\r
+{\r
+portBASE_TYPE xItem, xData;\r
+portTickType xTimeWhenBlocking;\r
+portTickType xTimeToBlock, xBlockedTime;\r
+\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /*********************************************************************\r
+        Test 1\r
+\r
+        Simple block time wakeup test on queue receives. */\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       /* The queue is empty. Attempt to read from the queue using a block\r
+                       time.  When we wake, ensure the delta in time is as expected. */\r
+                       xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;\r
+\r
+                       xTimeWhenBlocking = xTaskGetTickCount();\r
+\r
+                       /* We should unblock after xTimeToBlock having not received\r
+                       anything on the queue. */\r
+                       if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* How long were we blocked for? */\r
+                       xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+\r
+                       if( xBlockedTime < xTimeToBlock )\r
+                       {\r
+                               /* Should not have blocked for less than we requested. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
+                       {\r
+                               /* Should not have blocked for longer than we requested,\r
+                               although we would not necessarily run as soon as we were\r
+                               unblocked so a margin is allowed. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /*********************************************************************\r
+        Test 2\r
+\r
+        Simple block time wakeup test on queue sends.\r
+\r
+               First fill the queue.  It should be empty so all sends should pass. */\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       #if configUSE_PREEMPTION == 0\r
+                               taskYIELD();\r
+                       #endif\r
+               }\r
+\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       /* The queue is full. Attempt to write to the queue using a block\r
+                       time.  When we wake, ensure the delta in time is as expected. */\r
+                       xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem;\r
+\r
+                       xTimeWhenBlocking = xTaskGetTickCount();\r
+\r
+                       /* We should unblock after xTimeToBlock having not received\r
+                       anything on the queue. */\r
+                       if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* How long were we blocked for? */\r
+                       xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+\r
+                       if( xBlockedTime < xTimeToBlock )\r
+                       {\r
+                               /* Should not have blocked for less than we requested. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) )\r
+                       {\r
+                               /* Should not have blocked for longer than we requested,\r
+                               although we would not necessarily run as soon as we were\r
+                               unblocked so a margin is allowed. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /*********************************************************************\r
+        Test 3\r
+\r
+               Wake the other task, it will block attempting to post to the queue.\r
+               When we read from the queue the other task will wake, but before it\r
+               can run we will post to the queue again.  When the other task runs it\r
+               will find the queue still full, even though it was woken.  It should\r
+               recognise that its block time has not expired and return to block for\r
+               the remains of its block time.\r
+\r
+               Wake the other task so it blocks attempting to post to the already\r
+               full queue. */\r
+               xRunIndicator = 0;\r
+               vTaskResume( xSecondary );\r
+\r
+               /* We need to wait a little to ensure the other task executes. */\r
+               while( xRunIndicator != bktRUN_INDICATOR )\r
+               {\r
+                       /* The other task has not yet executed. */\r
+                       vTaskDelay( bktSHORT_WAIT );\r
+               }\r
+               /* Make sure the other task is blocked on the queue. */\r
+               vTaskDelay( bktSHORT_WAIT );\r
+               xRunIndicator = 0;\r
+\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       /* Now when we make space on the queue the other task should wake\r
+                       but not execute as this task has higher priority. */\r
+                       if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* Now fill the queue again before the other task gets a chance to\r
+                       execute.  If the other task had executed we would find the queue\r
+                       full ourselves, and the other task have set xRunIndicator. */\r
+                       if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( xRunIndicator == bktRUN_INDICATOR )\r
+                       {\r
+                               /* The other task should not have executed. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* Raise the priority of the other task so it executes and blocks\r
+                       on the queue again. */\r
+                       vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
+\r
+                       /* The other task should now have re-blocked without exiting the\r
+                       queue function. */\r
+                       if( xRunIndicator == bktRUN_INDICATOR )\r
+                       {\r
+                               /* The other task should not have executed outside of the\r
+                               queue function. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* Set the priority back down. */\r
+                       vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
+               }\r
+\r
+               /* Let the other task timeout.  When it unblockes it will check that it\r
+               unblocked at the correct time, then suspend itself. */\r
+               while( xRunIndicator != bktRUN_INDICATOR )\r
+               {\r
+                       vTaskDelay( bktSHORT_WAIT );\r
+               }\r
+               vTaskDelay( bktSHORT_WAIT );\r
+               xRunIndicator = 0;\r
+\r
+\r
+               /*********************************************************************\r
+        Test 4\r
+\r
+               As per test 3 - but with the send and receive the other way around.\r
+               The other task blocks attempting to read from the queue.\r
+\r
+               Empty the queue.  We should find that it is full. */\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Wake the other task so it blocks attempting to read from  the\r
+               already empty queue. */\r
+               vTaskResume( xSecondary );\r
+\r
+               /* We need to wait a little to ensure the other task executes. */\r
+               while( xRunIndicator != bktRUN_INDICATOR )\r
+               {\r
+                       vTaskDelay( bktSHORT_WAIT );\r
+               }\r
+               vTaskDelay( bktSHORT_WAIT );\r
+               xRunIndicator = 0;\r
+\r
+               for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ )\r
+               {\r
+                       /* Now when we place an item on the queue the other task should\r
+                       wake but not execute as this task has higher priority. */\r
+                       if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* Now empty the queue again before the other task gets a chance to\r
+                       execute.  If the other task had executed we would find the queue\r
+                       empty ourselves, and the other task would be suspended. */\r
+                       if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( xRunIndicator == bktRUN_INDICATOR )\r
+                       {\r
+                               /* The other task should not have executed. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       /* Raise the priority of the other task so it executes and blocks\r
+                       on the queue again. */\r
+                       vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 );\r
+\r
+                       /* The other task should now have re-blocked without exiting the\r
+                       queue function. */\r
+                       if( xRunIndicator == bktRUN_INDICATOR )\r
+                       {\r
+                               /* The other task should not have executed outside of the\r
+                               queue function. */\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+                       vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY );\r
+               }\r
+\r
+               /* Let the other task timeout.  When it unblockes it will check that it\r
+               unblocked at the correct time, then suspend itself. */\r
+               while( xRunIndicator != bktRUN_INDICATOR )\r
+               {\r
+                       vTaskDelay( bktSHORT_WAIT );\r
+               }\r
+               vTaskDelay( bktSHORT_WAIT );\r
+\r
+               xPrimaryCycles++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void vSecondaryBlockTimeTestTask( void *pvParameters )\r
+{\r
+portTickType xTimeWhenBlocking, xBlockedTime;\r
+portBASE_TYPE xData;\r
+\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /*********************************************************************\r
+        Test 1 and 2\r
+\r
+               This task does does not participate in these tests. */\r
+               vTaskSuspend( NULL );\r
+\r
+               /*********************************************************************\r
+        Test 3\r
+\r
+               The first thing we do is attempt to read from the queue.  It should be\r
+               full so we block.  Note the time before we block so we can check the\r
+               wake time is as per that expected. */\r
+               xTimeWhenBlocking = xTaskGetTickCount();\r
+\r
+               /* We should unblock after bktTIME_TO_BLOCK having not sent\r
+               anything to the queue. */\r
+               xData = 0;\r
+               xRunIndicator = bktRUN_INDICATOR;\r
+               if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* How long were we inside the send function? */\r
+               xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+\r
+               /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
+               if( xBlockedTime < bktTIME_TO_BLOCK )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
+               either.  A margin is permitted as we would not necessarily run as\r
+               soon as we unblocked. */\r
+               if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Suspend ready for test 3. */\r
+               xRunIndicator = bktRUN_INDICATOR;\r
+               vTaskSuspend( NULL );\r
+\r
+               /*********************************************************************\r
+        Test 4\r
+\r
+               As per test three, but with the send and receive reversed. */\r
+               xTimeWhenBlocking = xTaskGetTickCount();\r
+\r
+               /* We should unblock after bktTIME_TO_BLOCK having not received\r
+               anything on the queue. */\r
+               xRunIndicator = bktRUN_INDICATOR;\r
+               if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+\r
+               /* We should not have blocked for less time than bktTIME_TO_BLOCK. */\r
+               if( xBlockedTime < bktTIME_TO_BLOCK )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* We should of not blocked for much longer than bktALLOWABLE_MARGIN\r
+               either.  A margin is permitted as we would not necessarily run as soon\r
+               as we unblocked. */\r
+               if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               xRunIndicator = bktRUN_INDICATOR;\r
+\r
+               xSecondaryCycles++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void )\r
+{\r
+static portBASE_TYPE xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0;\r
+portBASE_TYPE xReturn = pdPASS;\r
+\r
+       /* Have both tasks performed at least one cycle since this function was\r
+       last called? */\r
+       if( xPrimaryCycles == xLastPrimaryCycleCount )\r
+       {\r
+               xReturn = pdFAIL;\r
+       }\r
+\r
+       if( xSecondaryCycles == xLastSecondaryCycleCount )\r
+       {\r
+               xReturn = pdFAIL;\r
+       }\r
+\r
+       if( xErrorOccurred == pdTRUE )\r
+       {\r
+               xReturn = pdFAIL;\r
+       }\r
+\r
+       xLastSecondaryCycleCount = xSecondaryCycles;\r
+       xLastPrimaryCycleCount = xPrimaryCycles;\r
+\r
+       return xReturn;\r
+}\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/death.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/death.c
new file mode 100644 (file)
index 0000000..f3b0523
--- /dev/null
@@ -0,0 +1,255 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * Create a single persistent task which periodically dynamically creates another\r
+ * two tasks.  The original task is called the creator task, the two tasks it\r
+ * creates are called suicidal tasks.\r
+ *\r
+ * One of the created suicidal tasks kill one other suicidal task before killing\r
+ * itself - leaving just the original task remaining.\r
+ *\r
+ * The creator task must be spawned after all of the other demo application tasks\r
+ * as it keeps a check on the number of tasks under the scheduler control.  The\r
+ * number of tasks it expects to see running should never be greater than the\r
+ * number of tasks that were in existence when the creator task was spawned, plus\r
+ * one set of four suicidal tasks.  If this number is exceeded an error is flagged.\r
+ *\r
+ * \page DeathC death.c\r
+ * \ingroup DemoFiles\r
+ * <HR>\r
+ */\r
+\r
+/*\r
+Changes from V3.0.0\r
+       + CreationCount sizes changed from unsigned portBASE_TYPE to\r
+         unsigned short to minimize the risk of overflowing.\r
+       \r
+       + Reset of usLastCreationCount added\r
+       \r
+Changes from V3.1.0\r
+       + Changed the dummy calculation to use variables of type long, rather than\r
+         float.  This allows the file to be used with ports that do not support\r
+         floating point.\r
+\r
+*/\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo program include files. */\r
+#include "death.h"\r
+\r
+#define deathSTACK_SIZE                ( configMINIMAL_STACK_SIZE + 60 )\r
+\r
+/* The task originally created which is responsible for periodically dynamically\r
+creating another four tasks. */\r
+static portTASK_FUNCTION_PROTO( vCreateTasks, pvParameters );\r
+\r
+/* The task function of the dynamically created tasks. */\r
+static portTASK_FUNCTION_PROTO( vSuicidalTask, pvParameters );\r
+\r
+/* A variable which is incremented every time the dynamic tasks are created.  This\r
+is used to check that the task is still running. */\r
+static volatile unsigned short usCreationCount = 0;\r
+\r
+/* Used to store the number of tasks that were originally running so the creator\r
+task can tell if any of the suicidal tasks have failed to die.\r
+*/\r
+static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0;\r
+\r
+/* Tasks are deleted by the idle task.  Under heavy load the idle task might\r
+not get much processing time, so it would be legitimate for several tasks to\r
+remain undeleted for a short period. */\r
+static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 2;\r
+\r
+/* Used to store a handle to the task that should be killed by a suicidal task,\r
+before it kills itself. */\r
+xTaskHandle xCreatedTask;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+unsigned portBASE_TYPE *puxPriority;\r
+\r
+       /* Create the Creator tasks - passing in as a parameter the priority at which\r
+       the suicidal tasks should be created. */\r
+       puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );\r
+       *puxPriority = uxPriority;\r
+\r
+       xTaskCreate( vCreateTasks, ( signed char * ) "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );\r
+\r
+       /* Record the number of tasks that are running now so we know if any of the\r
+       suicidal tasks have failed to be killed. */\r
+       uxTasksRunningAtStart = ( unsigned portBASE_TYPE ) uxTaskGetNumberOfTasks();\r
+       \r
+       /* FreeRTOS.org versions before V3.0 started the idle-task as the very\r
+       first task. The idle task was then already included in uxTasksRunningAtStart.\r
+       From FreeRTOS V3.0 on, the idle task is started when the scheduler is\r
+       started. Therefore the idle task is not yet accounted for. We correct\r
+       this by increasing uxTasksRunningAtStart by 1. */\r
+       uxTasksRunningAtStart++;\r
+       \r
+       /* From FreeRTOS version 7.0.0 can optionally create a timer service task.  \r
+       If this is done, then uxTasksRunningAtStart needs incrementing again as that\r
+       too is created when the scheduler is started. */\r
+       #if configUSE_TIMERS == 1\r
+               uxTasksRunningAtStart++;\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+                                       \r
+static portTASK_FUNCTION( vSuicidalTask, pvParameters )\r
+{\r
+volatile long l1, l2;\r
+xTaskHandle xTaskToKill;\r
+const portTickType xDelay = ( portTickType ) 200 / portTICK_RATE_MS;\r
+\r
+       if( pvParameters != NULL )\r
+       {\r
+               /* This task is periodically created four times.  Two created tasks are\r
+               passed a handle to the other task so it can kill it before killing itself.\r
+               The other task is passed in null. */\r
+               xTaskToKill = *( xTaskHandle* )pvParameters;\r
+       }\r
+       else\r
+       {\r
+               xTaskToKill = NULL;\r
+       }\r
+\r
+       for( ;; )\r
+       {\r
+               /* Do something random just to use some stack and registers. */\r
+               l1 = 2;\r
+               l2 = 89;\r
+               l2 *= l1;\r
+               vTaskDelay( xDelay );\r
+\r
+               if( xTaskToKill != NULL )\r
+               {\r
+                       /* Make sure the other task has a go before we delete it. */\r
+                       vTaskDelay( ( portTickType ) 0 );\r
+\r
+                       /* Kill the other task that was created by vCreateTasks(). */\r
+                       vTaskDelete( xTaskToKill );\r
+\r
+                       /* Kill ourselves. */\r
+                       vTaskDelete( NULL );\r
+               }\r
+       }\r
+}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCreateTasks, pvParameters )\r
+{\r
+const portTickType xDelay = ( portTickType ) 1000 / portTICK_RATE_MS;\r
+unsigned portBASE_TYPE uxPriority;\r
+\r
+       uxPriority = *( unsigned portBASE_TYPE * ) pvParameters;\r
+       vPortFree( pvParameters );\r
+\r
+       for( ;; )\r
+       {\r
+               /* Just loop round, delaying then creating the four suicidal tasks. */\r
+               vTaskDelay( xDelay );\r
+\r
+               xCreatedTask = NULL;\r
+\r
+               xTaskCreate( vSuicidalTask, ( signed char * ) "SUICID1", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xCreatedTask );\r
+               xTaskCreate( vSuicidalTask, ( signed char * ) "SUICID2", configMINIMAL_STACK_SIZE, &xCreatedTask, uxPriority, NULL );\r
+\r
+               ++usCreationCount;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that the creator task is still running and that there\r
+are not any more than four extra tasks. */\r
+portBASE_TYPE xIsCreateTaskStillRunning( void )\r
+{\r
+static unsigned short usLastCreationCount = 0xfff;\r
+portBASE_TYPE xReturn = pdTRUE;\r
+static unsigned portBASE_TYPE uxTasksRunningNow;\r
+\r
+       if( usLastCreationCount == usCreationCount )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+       else\r
+       {\r
+               usLastCreationCount = usCreationCount;\r
+       }\r
+       \r
+       uxTasksRunningNow = ( unsigned portBASE_TYPE ) uxTaskGetNumberOfTasks();\r
+\r
+       if( uxTasksRunningNow < uxTasksRunningAtStart )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+       else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+       else\r
+       {\r
+               /* Everything is okay. */\r
+       }\r
+\r
+       return xReturn;\r
+}\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/dynamic.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/dynamic.c
new file mode 100644 (file)
index 0000000..c2df481
--- /dev/null
@@ -0,0 +1,427 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 first test creates three tasks - two counter tasks (one continuous count \r
+ * and one limited count) and one controller.  A "count" variable is shared \r
+ * between all three tasks.  The two counter tasks should never be in a "ready" \r
+ * state at the same time.  The controller task runs at the same priority as \r
+ * the continuous count task, and at a lower priority than the limited count \r
+ * task.\r
+ *\r
+ * One counter task loops indefinitely, incrementing the shared count variable\r
+ * on each iteration.  To ensure it has exclusive access to the variable it\r
+ * raises it's priority above that of the controller task before each \r
+ * increment, lowering it again to it's original priority before starting the\r
+ * next iteration.\r
+ *\r
+ * The other counter task increments the shared count variable on each\r
+ * iteration of it's loop until the count has reached a limit of 0xff - at\r
+ * which point it suspends itself.  It will not start a new loop until the \r
+ * controller task has made it "ready" again by calling vTaskResume ().  \r
+ * This second counter task operates at a higher priority than controller \r
+ * task so does not need to worry about mutual exclusion of the counter \r
+ * variable.\r
+ *\r
+ * The controller task is in two sections.  The first section controls and\r
+ * monitors the continuous count task.  When this section is operational the \r
+ * limited count task is suspended.  Likewise, the second section controls \r
+ * and monitors the limited count task.  When this section is operational the \r
+ * continuous count task is suspended.\r
+ *\r
+ * In the first section the controller task first takes a copy of the shared\r
+ * count variable.  To ensure mutual exclusion on the count variable it\r
+ * suspends the continuous count task, resuming it again when the copy has been\r
+ * taken.  The controller task then sleeps for a fixed period - during which\r
+ * the continuous count task will execute and increment the shared variable.\r
+ * When the controller task wakes it checks that the continuous count task\r
+ * has executed by comparing the copy of the shared variable with its current\r
+ * value.  This time, to ensure mutual exclusion, the scheduler itself is \r
+ * suspended with a call to vTaskSuspendAll ().  This is for demonstration \r
+ * purposes only and is not a recommended technique due to its inefficiency.\r
+ *\r
+ * After a fixed number of iterations the controller task suspends the \r
+ * continuous count task, and moves on to its second section.\r
+ *\r
+ * At the start of the second section the shared variable is cleared to zero.\r
+ * The limited count task is then woken from it's suspension by a call to\r
+ * vTaskResume ().  As this counter task operates at a higher priority than\r
+ * the controller task the controller task should not run again until the\r
+ * shared variable has been counted up to the limited value causing the counter\r
+ * task to suspend itself.  The next line after vTaskResume () is therefore\r
+ * a check on the shared variable to ensure everything is as expected.\r
+ *\r
+ *\r
+ * The second test consists of a couple of very simple tasks that post onto a \r
+ * queue while the scheduler is suspended.  This test was added to test parts\r
+ * of the scheduler not exercised by the first test.\r
+ *\r
+ */\r
+\r
+#include <stdlib.h>\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 "dynamic.h"\r
+\r
+/* Function that implements the "limited count" task as described above. */\r
+static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters );\r
+\r
+/* Function that implements the "continuous count" task as described above. */\r
+static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters );\r
+\r
+/* Function that implements the controller task as described above. */\r
+static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters );\r
+\r
+static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters );\r
+\r
+/* Demo task specific constants. */\r
+#define priSTACK_SIZE                          ( configMINIMAL_STACK_SIZE )\r
+#define priSLEEP_TIME                          ( ( portTickType ) 128 / portTICK_RATE_MS )\r
+#define priLOOPS                                       ( 5 )\r
+#define priMAX_COUNT                           ( ( unsigned long ) 0xff )\r
+#define priNO_BLOCK                                    ( ( portTickType ) 0 )\r
+#define priSUSPENDED_QUEUE_LENGTH      ( 1 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Handles to the two counter tasks.  These could be passed in as parameters\r
+to the controller task to prevent them having to be file scope. */\r
+static xTaskHandle xContinousIncrementHandle, xLimitedIncrementHandle;\r
+\r
+/* The shared counter variable.  This is passed in as a parameter to the two \r
+counter variables for demonstration purposes. */\r
+static unsigned long ulCounter;\r
+\r
+/* Variables used to check that the tasks are still operating without error.\r
+Each complete iteration of the controller task increments this variable\r
+provided no errors have been found.  The variable maintaining the same value\r
+is therefore indication of an error. */\r
+static volatile unsigned short usCheckVariable = ( unsigned short ) 0;\r
+static volatile portBASE_TYPE xSuspendedQueueSendError = pdFALSE;\r
+static volatile portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE;\r
+\r
+/* Queue used by the second test. */\r
+xQueueHandle xSuspendedTestQueue;\r
+\r
+/*-----------------------------------------------------------*/\r
+/*\r
+ * Start the three tasks as described at the top of the file.\r
+ * Note that the limited count task is given a higher priority.\r
+ */\r
+void vStartDynamicPriorityTasks( void )\r
+{\r
+       xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) );\r
+\r
+       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
+       in use.  The queue registry is provided as a means for kernel aware \r
+       debuggers to locate queues 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( xSuspendedTestQueue, ( signed char * ) "Suspended_Test_Queue" );\r
+\r
+       xTaskCreate( vContinuousIncrementTask, ( signed char * ) "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinousIncrementHandle );\r
+       xTaskCreate( vLimitedIncrementTask, ( signed char * ) "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle );\r
+       xTaskCreate( vCounterControlTask, ( signed char * ) "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vQueueSendWhenSuspendedTask, ( signed char * ) "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vQueueReceiveWhenSuspendedTask, ( signed char * ) "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Just loops around incrementing the shared variable until the limit has been\r
+ * reached.  Once the limit has been reached it suspends itself. \r
+ */\r
+static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters )\r
+{\r
+unsigned long *pulCounter;\r
+\r
+       /* Take a pointer to the shared variable from the parameters passed into\r
+       the task. */\r
+       pulCounter = ( unsigned long * ) pvParameters;\r
+\r
+       /* This will run before the control task, so the first thing it does is\r
+       suspend - the control task will resume it when ready. */\r
+       vTaskSuspend( NULL );\r
+\r
+       for( ;; )\r
+       {\r
+               /* Just count up to a value then suspend. */\r
+               ( *pulCounter )++;      \r
+               \r
+               if( *pulCounter >= priMAX_COUNT )\r
+               {\r
+                       vTaskSuspend( NULL );\r
+               }       \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Just keep counting the shared variable up.  The control task will suspend\r
+ * this task when it wants.\r
+ */\r
+static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters )\r
+{\r
+unsigned long *pulCounter;\r
+unsigned portBASE_TYPE uxOurPriority;\r
+\r
+       /* Take a pointer to the shared variable from the parameters passed into\r
+       the task. */\r
+       pulCounter = ( unsigned long * ) pvParameters;\r
+\r
+       /* Query our priority so we can raise it when exclusive access to the \r
+       shared variable is required. */\r
+       uxOurPriority = uxTaskPriorityGet( NULL );\r
+\r
+       for( ;; )\r
+       {\r
+               /* Raise our priority above the controller task to ensure a context\r
+               switch does not occur while we are accessing this variable. */\r
+               vTaskPrioritySet( NULL, uxOurPriority + 1 );\r
+                       ( *pulCounter )++;              \r
+               vTaskPrioritySet( NULL, uxOurPriority );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Controller task as described above.\r
+ */\r
+static portTASK_FUNCTION( vCounterControlTask, pvParameters )\r
+{\r
+unsigned long ulLastCounter;\r
+short sLoops;\r
+short sError = pdFALSE;\r
+\r
+       /* Just to stop warning messages. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Start with the counter at zero. */\r
+               ulCounter = ( unsigned long ) 0;\r
+\r
+               /* First section : */\r
+\r
+               /* Check the continuous count task is running. */\r
+               for( sLoops = 0; sLoops < priLOOPS; sLoops++ )\r
+               {\r
+                       /* Suspend the continuous count task so we can take a mirror of the\r
+                       shared variable without risk of corruption. */\r
+                       vTaskSuspend( xContinousIncrementHandle );\r
+                               ulLastCounter = ulCounter;\r
+                       vTaskResume( xContinousIncrementHandle );\r
+                       \r
+                       /* Now delay to ensure the other task has processor time. */\r
+                       vTaskDelay( priSLEEP_TIME );\r
+\r
+                       /* Check the shared variable again.  This time to ensure mutual \r
+                       exclusion the whole scheduler will be locked.  This is just for\r
+                       demo purposes! */\r
+                       vTaskSuspendAll();\r
+                       {\r
+                               if( ulLastCounter == ulCounter )\r
+                               {\r
+                                       /* The shared variable has not changed.  There is a problem\r
+                                       with the continuous count task so flag an error. */\r
+                                       sError = pdTRUE;\r
+                               }\r
+                       }\r
+                       xTaskResumeAll();\r
+               }\r
+\r
+\r
+               /* Second section: */\r
+\r
+               /* Suspend the continuous counter task so it stops accessing the shared variable. */\r
+               vTaskSuspend( xContinousIncrementHandle );\r
+\r
+               /* Reset the variable. */\r
+               ulCounter = ( unsigned long ) 0;\r
+\r
+               /* Resume the limited count task which has a higher priority than us.\r
+               We should therefore not return from this call until the limited count\r
+               task has suspended itself with a known value in the counter variable. */\r
+               vTaskResume( xLimitedIncrementHandle );\r
+\r
+               /* Does the counter variable have the expected value? */\r
+               if( ulCounter != priMAX_COUNT )\r
+               {\r
+                       sError = pdTRUE;\r
+               }\r
+\r
+               if( sError == pdFALSE )\r
+               {\r
+                       /* If no errors have occurred then increment the check variable. */\r
+                       portENTER_CRITICAL();\r
+                               usCheckVariable++;\r
+                       portEXIT_CRITICAL();\r
+               }\r
+\r
+               /* Resume the continuous count task and do it all again. */\r
+               vTaskResume( xContinousIncrementHandle );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters )\r
+{\r
+static unsigned long ulValueToSend = ( unsigned long ) 0;\r
+\r
+       /* Just to stop warning messages. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               vTaskSuspendAll();\r
+               {\r
+                       /* We must not block while the scheduler is suspended! */\r
+                       if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE )\r
+                       {\r
+                               xSuspendedQueueSendError = pdTRUE;\r
+                       }\r
+               }\r
+               xTaskResumeAll();\r
+\r
+               vTaskDelay( priSLEEP_TIME );\r
+\r
+               ++ulValueToSend;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters )\r
+{\r
+static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue;\r
+portBASE_TYPE xGotValue;\r
+\r
+       /* Just to stop warning messages. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               do\r
+               {\r
+                       /* Suspending the scheduler here is fairly pointless and \r
+                       undesirable for a normal application.  It is done here purely\r
+                       to test the scheduler.  The inner xTaskResumeAll() should\r
+                       never return pdTRUE as the scheduler is still locked by the\r
+                       outer call. */\r
+                       vTaskSuspendAll();\r
+                       {\r
+                               vTaskSuspendAll();\r
+                               {\r
+                                       xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK );\r
+                               }\r
+                               if( xTaskResumeAll() )\r
+                               {\r
+                                       xSuspendedQueueReceiveError = pdTRUE;\r
+                               }\r
+                       }\r
+                       xTaskResumeAll();\r
+\r
+                       #if configUSE_PREEMPTION == 0\r
+                       {\r
+                               taskYIELD();\r
+                       }\r
+                       #endif\r
+\r
+               } while( xGotValue == pdFALSE );\r
+\r
+               if( ulReceivedValue != ulExpectedValue )\r
+               {\r
+                       xSuspendedQueueReceiveError = pdTRUE;\r
+               }\r
+\r
+               ++ulExpectedValue;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Called to check that all the created tasks are still running without error. */\r
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void )\r
+{\r
+/* Keep a history of the check variables so we know if it has been incremented \r
+since the last call. */\r
+static unsigned short usLastTaskCheck = ( unsigned short ) 0;\r
+portBASE_TYPE xReturn = pdTRUE;\r
+\r
+       /* Check the tasks are still running by ensuring the check variable\r
+       is still incrementing. */\r
+\r
+       if( usCheckVariable == usLastTaskCheck )\r
+       {\r
+               /* The check has not incremented so an error exists. */\r
+               xReturn = pdFALSE;\r
+       }\r
+\r
+       if( xSuspendedQueueSendError == pdTRUE )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+\r
+       if( xSuspendedQueueReceiveError == pdTRUE )\r
+       {\r
+               xReturn = pdFALSE;\r
+       }\r
+\r
+       usLastTaskCheck = usCheckVariable;\r
+       return xReturn;\r
+}\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/flash.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/flash.c
new file mode 100644 (file)
index 0000000..3d73d17
--- /dev/null
@@ -0,0 +1,145 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * This version of flash .c is for use on systems that have limited stack space\r
+ * and no display facilities.  The complete version can be found in the \r
+ * Demo/Common/Full directory.\r
+ * \r
+ * Three tasks are created, each of which flash an LED at a different rate.  The first \r
+ * LED flashes every 200ms, the second every 400ms, the third every 600ms.\r
+ *\r
+ * The LED flash tasks provide instant visual feedback.  They show that the scheduler \r
+ * is still operational.\r
+ *\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo program include files. */\r
+#include "partest.h"\r
+#include "flash.h"\r
+\r
+#define ledSTACK_SIZE          configMINIMAL_STACK_SIZE\r
+#define ledNUMBER_OF_LEDS      ( 3 )\r
+#define ledFLASH_RATE_BASE     ( ( portTickType ) 333 )\r
+\r
+/* Variable used by the created tasks to calculate the LED number to use, and\r
+the rate at which they should flash the LED. */\r
+static volatile unsigned portBASE_TYPE uxFlashTaskNumber = 0;\r
+\r
+/* The task that is created three times. */\r
+static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+signed portBASE_TYPE xLEDTask;\r
+\r
+       /* Create the three tasks. */\r
+       for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )\r
+       {\r
+               /* Spawn the task. */\r
+               xTaskCreate( vLEDFlashTask, ( signed char * ) "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vLEDFlashTask, pvParameters )\r
+{\r
+portTickType xFlashRate, xLastFlashTime;\r
+unsigned portBASE_TYPE uxLED;\r
+\r
+       /* The parameters are not used. */\r
+       ( void ) pvParameters;\r
+\r
+       /* Calculate the LED and flash rate. */\r
+       portENTER_CRITICAL();\r
+       {\r
+               /* See which of the eight LED's we should use. */\r
+               uxLED = uxFlashTaskNumber;\r
+\r
+               /* Update so the next task uses the next LED. */\r
+               uxFlashTaskNumber++;\r
+       }\r
+       portEXIT_CRITICAL();\r
+\r
+       xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( portTickType ) uxLED );\r
+       xFlashRate /= portTICK_RATE_MS;\r
+\r
+       /* We will turn the LED on and off again in the delay period, so each\r
+       delay is only half the total period. */\r
+       xFlashRate /= ( portTickType ) 2;\r
+\r
+       /* We need to initialise xLastFlashTime prior to the first call to \r
+       vTaskDelayUntil(). */\r
+       xLastFlashTime = xTaskGetTickCount();\r
+\r
+       for(;;)\r
+       {\r
+               /* Delay for half the flash period then turn the LED on. */\r
+               vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
+               vParTestToggleLED( uxLED );\r
+\r
+               /* Delay for half the flash period then turn the LED off. */\r
+               vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
+               vParTestToggleLED( uxLED );\r
+       }\r
+} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/BlockQ.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/BlockQ.h
new file mode 100644 (file)
index 0000000..58a9a57
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 BLOCK_Q_H\r
+#define BLOCK_Q_H\r
+\r
+void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreBlockingQueuesStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/GenQTest.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/GenQTest.h
new file mode 100644 (file)
index 0000000..799ff8f
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 GEN_Q_TEST_H\r
+#define GEN_Q_TEST_H\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void );\r
+\r
+#endif /* GEN_Q_TEST_H */\r
+\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/PollQ.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/PollQ.h
new file mode 100644 (file)
index 0000000..e4f213a
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 POLLED_Q_H\r
+#define POLLED_Q_H\r
+\r
+void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xArePollingQueuesStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/QPeek.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/QPeek.h
new file mode 100644 (file)
index 0000000..c18977d
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 Q_PEEK_TEST_H\r
+#define Q_PEEK_TEST_H\r
+\r
+void vStartQueuePeekTasks( void );\r
+portBASE_TYPE xAreQueuePeekTasksStillRunning( void );\r
+\r
+#endif /* Q_PEEK_TEST_H */\r
+\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/blocktim.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/blocktim.h
new file mode 100644 (file)
index 0000000..04cd947
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 BLOCK_TIME_TEST_H\r
+#define BLOCK_TIME_TEST_H\r
+\r
+void vCreateBlockTimeTasks( void );\r
+portBASE_TYPE xAreBlockTimeTestTasksStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/death.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/death.h
new file mode 100644 (file)
index 0000000..7985ed3
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 SUICIDE_TASK_H\r
+#define SUICIDE_TASK_H\r
+\r
+void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xIsCreateTaskStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/dynamic.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/dynamic.h
new file mode 100644 (file)
index 0000000..51b58fd
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 DYNAMIC_MANIPULATION_H\r
+#define DYNAMIC_MANIPULATION_H\r
+\r
+void vStartDynamicPriorityTasks( void );\r
+portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flash.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flash.h
new file mode 100644 (file)
index 0000000..63cc809
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 FLASH_LED_H\r
+#define FLASH_LED_H\r
+\r
+void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority );\r
+\r
+#endif\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flop.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/flop.h
new file mode 100644 (file)
index 0000000..066a404
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 FLOP_TASKS_H\r
+#define FLOP_TASKS_H\r
+\r
+void vStartMathTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreMathsTaskStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/partest.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/partest.h
new file mode 100644 (file)
index 0000000..b49e385
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 PARTEST_H\r
+#define PARTEST_H\r
+\r
+#define partstDEFAULT_PORT_ADDRESS             ( ( unsigned short ) 0x378 )\r
+\r
+void vParTestInitialise( void );\r
+void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue );\r
+void vParTestToggleLED( unsigned portBASE_TYPE uxLED );\r
+\r
+#endif\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/recmutex.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/recmutex.h
new file mode 100644 (file)
index 0000000..813f046
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 RECURSIVE_MUTEX_TEST_H\r
+#define RECURSIVE_MUTEX_TEST_H\r
+\r
+void vStartRecursiveMutexTasks( void );\r
+portBASE_TYPE xAreRecursiveMutexTasksStillRunning( void );\r
+\r
+#endif\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/semtest.h b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/include/semtest.h
new file mode 100644 (file)
index 0000000..6b1a179
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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 SEMAPHORE_TEST_H\r
+#define SEMAPHORE_TEST_H\r
+\r
+void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreSemaphoreTasksStillRunning( void );\r
+\r
+#endif\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/recmutex.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/recmutex.c
new file mode 100644 (file)
index 0000000..51c5071
--- /dev/null
@@ -0,0 +1,395 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+/* The recursive call depth. */\r
+#define recmuMAX_COUNT                                 ( 10 )\r
+\r
+/* Misc. */\r
+#define recmuSHORT_DELAY                               ( 20 / portTICK_RATE_MS )\r
+#define recmuNO_DELAY                                  ( ( portTickType ) 0 )\r
+#define recmuTWO_TICK_DELAY                            ( ( portTickType ) 2 )\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 * ) "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle );\r
+        xTaskCreate( prvRecursiveMutexBlockingTask, ( signed portCHAR * ) "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle );\r
+        xTaskCreate( prvRecursiveMutexPollingTask, ( signed portCHAR * ) "Rec3", 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, recmuTWO_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 sh ould 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 to 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
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/semtest.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/semtest.c
new file mode 100644 (file)
index 0000000..4f3901f
--- /dev/null
@@ -0,0 +1,284 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * Creates two sets of two tasks.  The tasks within a set share a variable, access \r
+ * to which is guarded by a semaphore.\r
+ * \r
+ * Each task starts by attempting to obtain the semaphore.  On obtaining a \r
+ * semaphore a task checks to ensure that the guarded variable has an expected \r
+ * value.  It then clears the variable to zero before counting it back up to the \r
+ * expected value in increments of 1.  After each increment the variable is checked \r
+ * to ensure it contains the value to which it was just set. When the starting \r
+ * value is again reached the task releases the semaphore giving the other task in \r
+ * the set a chance to do exactly the same thing.  The starting value is high \r
+ * enough to ensure that a tick is likely to occur during the incrementing loop.\r
+ *\r
+ * An error is flagged if at any time during the process a shared variable is \r
+ * found to have a value other than that expected.  Such an occurrence would \r
+ * suggest an error in the mutual exclusion mechanism by which access to the \r
+ * variable is restricted.\r
+ *\r
+ * The first set of two tasks poll their semaphore.  The second set use blocking \r
+ * calls.\r
+ *\r
+ */\r
+\r
+\r
+#include <stdlib.h>\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 "semtest.h"\r
+\r
+/* The value to which the shared variables are counted. */\r
+#define semtstBLOCKING_EXPECTED_VALUE          ( ( unsigned long ) 0xfff )\r
+#define semtstNON_BLOCKING_EXPECTED_VALUE      ( ( unsigned long ) 0xff  )\r
+\r
+#define semtstSTACK_SIZE                       configMINIMAL_STACK_SIZE\r
+\r
+#define semtstNUM_TASKS                                ( 4 )\r
+\r
+#define semtstDELAY_FACTOR                     ( ( portTickType ) 10 )\r
+\r
+/* The task function as described at the top of the file. */\r
+static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters );\r
+\r
+/* Structure used to pass parameters to each task. */\r
+typedef struct SEMAPHORE_PARAMETERS\r
+{\r
+       xSemaphoreHandle xSemaphore;\r
+       volatile unsigned long *pulSharedVariable;\r
+       portTickType xBlockTime;\r
+} xSemaphoreParameters;\r
+\r
+/* Variables used to check that all the tasks are still running without errors. */\r
+static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 };\r
+static volatile short sNextCheckVariable = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters;\r
+const portTickType xBlockTime = ( portTickType ) 100;\r
+\r
+       /* Create the structure used to pass parameters to the first two tasks. */\r
+       pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );\r
+\r
+       if( pxFirstSemaphoreParameters != NULL )\r
+       {\r
+               /* Create the semaphore used by the first two tasks. */\r
+               vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore );\r
+\r
+               if( pxFirstSemaphoreParameters->xSemaphore != NULL )\r
+               {\r
+                       /* Create the variable which is to be shared by the first two tasks. */\r
+                       pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );\r
+\r
+                       /* Initialise the share variable to the value the tasks expect. */\r
+                       *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE;\r
+\r
+                       /* The first two tasks do not block on semaphore calls. */\r
+                       pxFirstSemaphoreParameters->xBlockTime = ( portTickType ) 0;\r
+\r
+                       /* Spawn the first two tasks.  As they poll they operate at the idle priority. */\r
+                       xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );\r
+                       xTaskCreate( prvSemaphoreTest, ( signed char * ) "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );\r
+               }\r
+       }\r
+\r
+       /* Do exactly the same to create the second set of tasks, only this time \r
+       provide a block time for the semaphore calls. */\r
+       pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) );\r
+       if( pxSecondSemaphoreParameters != NULL )\r
+       {\r
+               vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore );\r
+\r
+               if( pxSecondSemaphoreParameters->xSemaphore != NULL )\r
+               {\r
+                       pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) );\r
+                       *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE;\r
+                       pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_RATE_MS;\r
+\r
+                       xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );\r
+                       xTaskCreate( prvSemaphoreTest, ( signed char * ) "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( xTaskHandle * ) NULL );\r
+               }\r
+       }\r
+\r
+       /* vQueueAddToRegistry() adds the semaphore to the registry, if one is\r
+       in use.  The registry is provided as a means for kernel aware \r
+       debuggers to locate semaphores 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 ) pxFirstSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_1" );\r
+       vQueueAddToRegistry( ( xQueueHandle ) pxSecondSemaphoreParameters->xSemaphore, ( signed char * ) "Counting_Sem_2" );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( prvSemaphoreTest, pvParameters )\r
+{\r
+xSemaphoreParameters *pxParameters;\r
+volatile unsigned long *pulSharedVariable, ulExpectedValue;\r
+unsigned long ulCounter;\r
+short sError = pdFALSE, sCheckVariableToUse;\r
+\r
+       /* See which check variable to use.  sNextCheckVariable is not semaphore \r
+       protected! */\r
+       portENTER_CRITICAL();\r
+               sCheckVariableToUse = sNextCheckVariable;\r
+               sNextCheckVariable++;\r
+       portEXIT_CRITICAL();\r
+\r
+       /* A structure is passed in as the parameter.  This contains the shared \r
+       variable being guarded. */\r
+       pxParameters = ( xSemaphoreParameters * ) pvParameters;\r
+       pulSharedVariable = pxParameters->pulSharedVariable;\r
+\r
+       /* If we are blocking we use a much higher count to ensure loads of context\r
+       switches occur during the count. */\r
+       if( pxParameters->xBlockTime > ( portTickType ) 0 )\r
+       {\r
+               ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE;\r
+       }\r
+       else\r
+       {\r
+               ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE;\r
+       }\r
+\r
+       for( ;; )\r
+       {\r
+               /* Try to obtain the semaphore. */\r
+               if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS )\r
+               {\r
+                       /* We have the semaphore and so expect any other tasks using the\r
+                       shared variable to have left it in the state we expect to find\r
+                       it. */\r
+                       if( *pulSharedVariable != ulExpectedValue )\r
+                       {\r
+                               sError = pdTRUE;\r
+                       }\r
+                       \r
+                       /* Clear the variable, then count it back up to the expected value\r
+                       before releasing the semaphore.  Would expect a context switch or\r
+                       two during this time. */\r
+                       for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ )\r
+                       {\r
+                               *pulSharedVariable = ulCounter;\r
+                               if( *pulSharedVariable != ulCounter )\r
+                               {\r
+                                       sError = pdTRUE;\r
+                               }\r
+                       }\r
+\r
+                       /* Release the semaphore, and if no errors have occurred increment the check\r
+                       variable. */\r
+                       if(     xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE )\r
+                       {\r
+                               sError = pdTRUE;\r
+                       }\r
+\r
+                       if( sError == pdFALSE )\r
+                       {\r
+                               if( sCheckVariableToUse < semtstNUM_TASKS )\r
+                               {\r
+                                       ( sCheckVariables[ sCheckVariableToUse ] )++;\r
+                               }\r
+                       }\r
+\r
+                       /* If we have a block time then we are running at a priority higher\r
+                       than the idle priority.  This task takes a long time to complete\r
+                       a cycle (deliberately so to test the guarding) so will be starving\r
+                       out lower priority tasks.  Block for some time to allow give lower\r
+                       priority tasks some processor time. */\r
+                       vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR );\r
+               }\r
+               else\r
+               {\r
+                       if( pxParameters->xBlockTime == ( portTickType ) 0 )\r
+                       {\r
+                               /* We have not got the semaphore yet, so no point using the\r
+                               processor.  We are not blocking when attempting to obtain the\r
+                               semaphore. */\r
+                               taskYIELD();\r
+                       }\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreSemaphoreTasksStillRunning( void )\r
+{\r
+static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 };\r
+portBASE_TYPE xTask, xReturn = pdTRUE;\r
+\r
+       for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ )\r
+       {\r
+               if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] )\r
+               {\r
+                       xReturn = pdFALSE;\r
+               }\r
+\r
+               sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ];\r
+       }\r
+\r
+       return xReturn;\r
+}\r
+\r
+\r
diff --git a/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/sp_flop.c b/Demo/MicroBlaze_Spartan-6_EthernetLite/SDKProjects/RTOSDemoSource/Demo_Source/sp_flop.c
new file mode 100644 (file)
index 0000000..33b4536
--- /dev/null
@@ -0,0 +1,353 @@
+/*\r
+    FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
+       \r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
+     *    Complete, revised, and edited pdf reference manuals are also       *\r
+     *    available.                                                         *\r
+     *                                                                       *\r
+     *    Purchasing FreeRTOS documentation will not only help you, by       *\r
+     *    ensuring you get running as quickly as possible and with an        *\r
+     *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
+     *    the FreeRTOS project to continue with its mission of providing     *\r
+     *    professional grade, cross platform, de facto standard solutions    *\r
+     *    for microcontrollers - completely free of charge!                  *\r
+     *                                                                       *\r
+     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
+     *                                                                       *\r
+     *    Thank you for using FreeRTOS, and thank you for your support!      *\r
+     *                                                                       *\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 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
+\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
+ * Creates eight tasks, each of which loops continuously performing a floating \r
+ * point calculation - using single precision variables.\r
+ *\r
+ * All the tasks run at the idle priority and never block or yield.  This causes \r
+ * all eight tasks to time slice with the idle task.  Running at the idle priority \r
+ * means that these tasks will get pre-empted any time another task is ready to run\r
+ * or a time slice occurs.  More often than not the pre-emption will occur mid \r
+ * calculation, creating a good test of the schedulers context switch mechanism - a \r
+ * calculation producing an unexpected result could be a symptom of a corruption in \r
+ * the context of a task.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <math.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* Demo program include files. */\r
+#include "flop.h"\r
+\r
+#define mathSTACK_SIZE         configMINIMAL_STACK_SIZE\r
+#define mathNUMBER_OF_TASKS  ( 8 )\r
+\r
+/* Four tasks, each of which performs a different floating point calculation.  \r
+Each of the four is created twice. */\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters );\r
+static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters );\r
+\r
+/* These variables are used to check that all the tasks are still running.  If a \r
+task gets a calculation wrong it will\r
+stop incrementing its check variable. */\r
+static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartMathTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+       xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask1, ( signed char * ) "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask2, ( signed char * ) "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask3, ( signed char * ) "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );\r
+       xTaskCreate( vCompetingMathTask4, ( signed char * ) "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask1, pvParameters )\r
+{\r
+volatile float f1, f2, f3, f4;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+volatile float fAnswer;\r
+short sError = pdFALSE;\r
+\r
+       f1 = 123.4567F;\r
+       f2 = 2345.6789F;\r
+       f3 = -918.222F;\r
+\r
+       fAnswer = ( f1 + f2 ) * f3;\r
+\r
+       /* The variable this task increments to show it is still running is passed in \r
+       as the parameter. */\r
+       pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+       /* Keep performing a calculation and checking the result against a constant. */\r
+       for(;;)\r
+       {\r
+               f1 = 123.4567F;\r
+               f2 = 2345.6789F;\r
+               f3 = -918.222F;\r
+\r
+               f4 = ( f1 + f2 ) * f3;\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               /* If the calculation does not match the expected constant, stop the \r
+               increment of the check variable. */\r
+               if( fabs( f4 - fAnswer ) > 0.001F )\r
+               {\r
+                       sError = pdTRUE;\r
+               }\r
+\r
+               if( sError == pdFALSE )\r
+               {\r
+                       /* If the calculation has always been correct, increment the check \r
+                       variable so we know this task is still running okay. */\r
+                       ( *pusTaskCheckVariable )++;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask2, pvParameters )\r
+{\r
+volatile float f1, f2, f3, f4;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+volatile float fAnswer;\r
+short sError = pdFALSE;\r
+\r
+       f1 = -389.38F;\r
+       f2 = 32498.2F;\r
+       f3 = -2.0001F;\r
+\r
+       fAnswer = ( f1 / f2 ) * f3;\r
+\r
+\r
+       /* The variable this task increments to show it is still running is passed in \r
+       as the parameter. */\r
+       pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+       /* Keep performing a calculation and checking the result against a constant. */\r
+       for( ;; )\r
+       {\r
+               f1 = -389.38F;\r
+               f2 = 32498.2F;\r
+               f3 = -2.0001F;\r
+\r
+               f4 = ( f1 / f2 ) * f3;\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+               \r
+               /* If the calculation does not match the expected constant, stop the \r
+               increment of the check variable. */\r
+               if( fabs( f4 - fAnswer ) > 0.001F )\r
+               {\r
+                       sError = pdTRUE;\r
+               }\r
+\r
+               if( sError == pdFALSE )\r
+               {\r
+                       /* If the calculation has always been correct, increment the check \r
+                       variable so we know\r
+                       this task is still running okay. */\r
+                       ( *pusTaskCheckVariable )++;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask3, pvParameters )\r
+{\r
+volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+const size_t xArraySize = 10;\r
+size_t xPosition;\r
+short sError = pdFALSE;\r
+\r
+       /* The variable this task increments to show it is still running is passed in \r
+       as the parameter. */\r
+       pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+       pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) );\r
+\r
+       /* Keep filling an array, keeping a running total of the values placed in the \r
+       array.  Then run through the array adding up all the values.  If the two totals \r
+       do not match, stop the check variable from incrementing. */\r
+       for( ;; )\r
+       {\r
+               fTotal1 = 0.0F;\r
+               fTotal2 = 0.0F;\r
+               fPosition = 0.0F;\r
+               \r
+               for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+               {\r
+                       pfArray[ xPosition ] = fPosition + 5.5F;\r
+                       fTotal1 += fPosition + 5.5F;    \r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+               {\r
+                       fTotal2 += pfArray[ xPosition ];\r
+               }\r
+\r
+               fDifference = fTotal1 - fTotal2;\r
+               if( fabs( fDifference ) > 0.001F )\r
+               {\r
+                       sError = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               if( sError == pdFALSE )\r
+               {\r
+                       /* If the calculation has always been correct, increment the check \r
+                       variable so we know     this task is still running okay. */\r
+                       ( *pusTaskCheckVariable )++;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vCompetingMathTask4, pvParameters )\r
+{\r
+volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition;\r
+volatile unsigned short *pusTaskCheckVariable;\r
+const size_t xArraySize = 10;\r
+size_t xPosition;\r
+short sError = pdFALSE;\r
+\r
+       /* The variable this task increments to show it is still running is passed in \r
+       as the parameter. */\r
+       pusTaskCheckVariable = ( unsigned short * ) pvParameters;\r
+\r
+       pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) );\r
+\r
+       /* Keep filling an array, keeping a running total of the values placed in the \r
+       array.  Then run through the array adding up all the values.  If the two totals \r
+       do not match, stop the check variable from incrementing. */\r
+       for( ;; )\r
+       {\r
+               fTotal1 = 0.0F;\r
+               fTotal2 = 0.0F;\r
+               fPosition = 0.0F;\r
+\r
+               for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+               {\r
+                       pfArray[ xPosition ] = fPosition * 12.123F;\r
+                       fTotal1 += fPosition * 12.123F; \r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               for( xPosition = 0; xPosition < xArraySize; xPosition++ )\r
+               {\r
+                       fTotal2 += pfArray[ xPosition ];\r
+               }\r
+\r
+               fDifference = fTotal1 - fTotal2;\r
+               if( fabs( fDifference ) > 0.001F )\r
+               {\r
+                       sError = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               if( sError == pdFALSE )\r
+               {\r
+                       /* If the calculation has always been correct, increment the check \r
+                       variable so we know     this task is still running okay. */\r
+                       ( *pusTaskCheckVariable )++;\r
+               }\r
+       }\r
+}                               \r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreMathsTaskStillRunning( void )\r
+{\r
+/* Keep a history of the check variables so we know if they have been incremented \r
+since the last call. */\r
+static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };\r
+portBASE_TYPE xReturn = pdTRUE, xTask;\r
+\r
+       /* Check the maths tasks are still running by ensuring their check variables \r
+       are still incrementing. */\r
+       for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ )\r
+       {\r
+               if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )\r
+               {\r
+                       /* The check has not incremented so an error exists. */\r
+                       xReturn = pdFALSE;\r
+               }\r
+\r
+               usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];\r
+       }\r
+\r
+       return xReturn;\r
+}\r
+\r
+\r
+\r