]> git.sur5r.net Git - freertos/commitdiff
Add first version of alternative API.
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 2 Dec 2007 18:37:43 +0000 (18:37 +0000)
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 2 Dec 2007 18:37:43 +0000 (18:37 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@123 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

17 files changed:
Demo/Common/Minimal/AltBlckQ.c [new file with mode: 0644]
Demo/Common/Minimal/AltBlock.c [new file with mode: 0644]
Demo/Common/Minimal/AltPollQ.c [new file with mode: 0644]
Demo/Common/Minimal/AltQTest.c [new file with mode: 0644]
Demo/Common/include/AltBlckQ.h [new file with mode: 0644]
Demo/Common/include/AltBlock.h [new file with mode: 0644]
Demo/Common/include/AltPollQ.h [new file with mode: 0644]
Demo/Common/include/AltQTest.h [new file with mode: 0644]
Demo/PC/FreeRTOSConfig.h
Demo/PC/main.c
Demo/PC/rtosdemo.tgt
Demo/PC/rtosdemo.wpj
Source/include/FreeRTOS.h
Source/include/queue.h
Source/include/semphr.h
Source/portable/Paradigm/Tern_EE/large_untested/port.c
Source/queue.c

diff --git a/Demo/Common/Minimal/AltBlckQ.c b/Demo/Common/Minimal/AltBlckQ.c
new file mode 100644 (file)
index 0000000..4eda203
--- /dev/null
@@ -0,0 +1,303 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license\r
+       and contact details.  Please ensure to read the configuration and relevant\r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+/*\r
+ * This is a version of BlockQ.c that uses the alternative (Alt) API.\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
+#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 "AltBlckQ.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 portSHORT *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 portSHORT sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 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 portSHORT sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 };\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartAltBlockingQueueTasks( 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 portSHORT ) );\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 portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL );\r
+       xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "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 portSHORT ) );\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 portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "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 portSHORT ) );\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 portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters )\r
+{\r
+unsigned portSHORT usValue = 0;\r
+xBlockingQueueParameters *pxQueueParameters;\r
+portSHORT sErrorEverOccurred = pdFALSE;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt blocking queue producer task started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;\r
+\r
+       for( ;; )\r
+       {               \r
+               if( xQueueAltSendToBack( 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 portSHORT usData, usExpectedValue = 0;\r
+xBlockingQueueParameters *pxQueueParameters;\r
+portSHORT sErrorEverOccurred = pdFALSE;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters;\r
+\r
+       for( ;; )\r
+       {       \r
+               if( xQueueAltReceive( 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 xAreAltBlockingQueuesStillRunning( void )\r
+{\r
+static portSHORT sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0 };\r
+static portSHORT sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 0, ( unsigned portSHORT ) 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/Common/Minimal/AltBlock.c b/Demo/Common/Minimal/AltBlock.c
new file mode 100644 (file)
index 0000000..5690e6e
--- /dev/null
@@ -0,0 +1,498 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license\r
+       and contact details.  Please ensure to read the configuration and relevant\r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+/*\r
+ * This is a version of BlockTim.c that uses the light weight API.\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 "AltBlock.h"\r
+\r
+/* Task priorities. */\r
+#define bktPRIMARY_PRIORITY                    ( 3 )\r
+#define bktSECONDARY_PRIORITY          ( 2 )\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                    ( 12 )\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 portBASE_TYPE xPrimaryCycles = 0, xSecondaryCycles = 0;\r
+static 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 vCreateAltBlockTimeTasks( void )\r
+{\r
+       /* Create the queue on which the two tasks block. */\r
+    xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( portBASE_TYPE ) );\r
+\r
+       /* Create the two test tasks. */\r
+       xTaskCreate( vPrimaryBlockTimeTestTask, ( signed portCHAR * )"FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL );\r
+       xTaskCreate( vSecondaryBlockTimeTestTask, ( signed portCHAR * )"FBTest2", 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
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt primary block time test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\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
+                       /* A critical section is used to minimise the jitter in the time\r
+                       measurements. */\r
+                       portENTER_CRITICAL();\r
+                       {\r
+                               xTimeWhenBlocking = xTaskGetTickCount();\r
+                               \r
+                               /* We should unblock after xTimeToBlock having not received\r
+                               anything on the queue. */\r
+                               if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY )\r
+                               {\r
+                                       xErrorOccurred = pdTRUE;\r
+                               }\r
+\r
+                               /* How long were we blocked for? */\r
+                               xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+                       }\r
+                       portEXIT_CRITICAL();\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( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\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
+                       portENTER_CRITICAL();\r
+                       {\r
+                               xTimeWhenBlocking = xTaskGetTickCount();\r
+                               \r
+                               /* We should unblock after xTimeToBlock having not received\r
+                               anything on the queue. */\r
+                               if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL )\r
+                               {\r
+                                       xErrorOccurred = pdTRUE;\r
+                               }\r
+\r
+                               /* How long were we blocked for? */\r
+                               xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+                       }\r
+                       portEXIT_CRITICAL();\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
+               /*********************************************************************\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( xQueueAltReceive( 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( xQueueAltSendToBack( 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( xQueueAltReceive( 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( xQueueAltSendToBack( 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( xQueueAltReceive( 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
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt secondary block time test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\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
+               portENTER_CRITICAL();\r
+               {\r
+                       xTimeWhenBlocking = xTaskGetTickCount();\r
+                       \r
+                       /* We should unblock after bktTIME_TO_BLOCK having not received\r
+                       anything on the queue. */\r
+                       xData = 0;\r
+                       xRunIndicator = bktRUN_INDICATOR;\r
+                       if( xQueueAltSendToBack( 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
+               portEXIT_CRITICAL();\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
+               portENTER_CRITICAL();\r
+               {\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( xQueueAltReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking;\r
+               }\r
+               portEXIT_CRITICAL();\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 xAreAltBlockTimeTestTasksStillRunning( 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/Common/Minimal/AltPollQ.c b/Demo/Common/Minimal/AltPollQ.c
new file mode 100644 (file)
index 0000000..52f46bf
--- /dev/null
@@ -0,0 +1,237 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license\r
+       and contact details.  Please ensure to read the configuration and relevant\r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+/*\r
+ * This is a version of PollQ.c that uses the alternative (Alt) API.\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 portLONG.\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 "AltPollQ.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 vStartAltPolledQueueTasks( 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 portSHORT ) );\r
+\r
+       /* Spawn the producer and consumer. */\r
+       xTaskCreate( vPolledQueueConsumer, ( signed portCHAR * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
+       xTaskCreate( vPolledQueueProducer, ( signed portCHAR * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )\r
+{\r
+unsigned portSHORT usValue = ( unsigned portSHORT ) 0;\r
+signed portBASE_TYPE xError = pdFALSE, xLoop;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt polling queue producer task 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
+               for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )\r
+               {\r
+                       /* Send an incrementing number on the queue without blocking. */\r
+                       if( xQueueAltSendToBack( *( ( 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 portSHORT usData, usExpectedValue = ( unsigned portSHORT ) 0;\r
+signed portBASE_TYPE xError = pdFALSE;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task 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
+               /* Loop until the queue is empty. */\r
+               while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) )\r
+               {\r
+                       if( xQueueAltReceive( *( ( 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 xAreAltPollingQueuesStillRunning( 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/Common/Minimal/AltQTest.c b/Demo/Common/Minimal/AltQTest.c
new file mode 100644 (file)
index 0000000..029f805
--- /dev/null
@@ -0,0 +1,542 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license\r
+       and contact details.  Please ensure to read the configuration and relevant\r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+\r
+/* \r
+ * This file implements the same demo and test as GenQTest.c, but uses the \r
+ * light weight API in place of the fully featured API.\r
+ *\r
+ * See the comments at the top of GenQTest.c for a description.\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 "AltQTest.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 xQueueAltSendToFront() and xQueueAltSendToBack()\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 vStartAltGenericQueueTasks( 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
+       /* 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 * ) "FGenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );\r
+\r
+       /* Create the mutex used by the prvMutexTest task. */\r
+       xMutex = xSemaphoreCreateMutex();\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 * ) "FMuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );\r
+       xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * ) "FMuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );\r
+       xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * ) "FMuHigh", 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 = "Alt 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
+               xQueueAltSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueAltReceive( 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
+               xQueueAltSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueAltReceive( 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
+                       xQueueAltSendToBack( 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
+               xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               ulData = 0;\r
+               xQueueAltSendToFront( 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( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueAltSendToBack( 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( xQueueAltPeek( 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( xQueueAltReceive( 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( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+               ulData = 11;\r
+               if( xQueueAltSendToBack( 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( xQueueAltSendToFront( 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( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueAltSendToBack( 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( xQueueAltReceive( 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 = "Fast 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
+       ( void ) pvParameters;\r
+\r
+\r
+       for( ;; )\r
+       {\r
+               /* Take the mutex.  It should be available now. */\r
+               if( xSemaphoreAltTake( 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( xSemaphoreAltGive( 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
+       ( void ) 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( xSemaphoreAltTake( 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( xSemaphoreAltGive( 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 xAreAltGenericQueueTasksStillRunning( 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/Common/include/AltBlckQ.h b/Demo/Common/include/AltBlckQ.h
new file mode 100644 (file)
index 0000000..c1b97c9
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef ALT_BLOCK_Q_H\r
+#define ALT_BLOCK_Q_H\r
+\r
+void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreAltBlockingQueuesStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/Common/include/AltBlock.h b/Demo/Common/include/AltBlock.h
new file mode 100644 (file)
index 0000000..6697d03
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef FAST_BLOCK_TIME_TEST_H\r
+#define FAST_BLOCK_TIME_TEST_H\r
+\r
+void vCreateAltBlockTimeTasks( void );\r
+portBASE_TYPE xAreAltBlockTimeTestTasksStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/Common/include/AltPollQ.h b/Demo/Common/include/AltPollQ.h
new file mode 100644 (file)
index 0000000..0b1c373
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef ALT_POLLED_Q_H\r
+#define ALT_POLLED_Q_H\r
+\r
+void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreAltPollingQueuesStillRunning( void );\r
+\r
+#endif\r
+\r
+\r
diff --git a/Demo/Common/include/AltQTest.h b/Demo/Common/include/AltQTest.h
new file mode 100644 (file)
index 0000000..ee15048
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+       FreeRTOS.org V4.6.1 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS.org distribution.\r
+\r
+       FreeRTOS.org is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS.org is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS.org; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS.org, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license\r
+       and contact details.  Please ensure to read the configuration and relevant\r
+       port sections of the online documentation.\r
+\r
+       Also see http://www.SafeRTOS.com a version that has been certified for use\r
+       in safety critical systems, plus commercial licensing, development and\r
+       support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef FAST_GEN_Q_TEST_H\r
+#define FAST_GEN_Q_TEST_H\r
+\r
+void vStartAltGenericQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreAltGenericQueueTasksStillRunning( void );\r
+\r
+#endif /* GEN_Q_TEST_H */\r
+\r
+\r
+\r
index 4b8f5623c7a0200936320926e600cbacb6402632..682173d79f2c139014e64050c4bc107941b83652 100644 (file)
@@ -63,6 +63,7 @@
 #define configUSE_CO_ROUTINES                  1\r
 #define configUSE_MUTEXES                              1\r
 #define configUSE_COUNTING_SEMAPHORES  1\r
+#define configUSE_ALTERNATIVE_API              1\r
 \r
 #define configMAX_PRIORITIES           ( ( unsigned portBASE_TYPE ) 10 )\r
 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
index 981ab9b578937b90f58d75f57c63a611216e88df..bba2d4a792f62417fe80afdc4d60da008f240662 100644 (file)
 #include "mevents.h"\r
 #include "crhook.h"\r
 #include "blocktim.h"\r
+#include "AltBlock.h"\r
 #include "GenQTest.h"\r
 #include "QPeek.h"\r
 #include "countsem.h"\r
+#include "AltQTest.h"\r
+#include "AltPollQ.h"\r
+#include "AltBlckQ.h"\r
 \r
 /* Priority definitions for the tasks in the demo application. */\r
 #define mainLED_TASK_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
@@ -155,7 +159,11 @@ portSHORT main( void )
        vStartMultiEventTasks();\r
        vStartQueuePeekTasks();\r
        vStartCountingSemaphoreTasks();\r
-\r
+       vStartAltGenericQueueTasks( mainGENERIC_QUEUE_PRIORITY );\r
+       vCreateAltBlockTimeTasks();\r
+       vStartAltBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );        \r
+       vStartAltPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+               \r
        /* Create the "Print" task as described at the top of the file. */\r
        xTaskCreate( vErrorChecks, "Print", mainPRINT_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL );\r
 \r
@@ -318,12 +326,24 @@ static portSHORT sErrorHasOccurred = pdFALSE;
                sErrorHasOccurred = pdTRUE;\r
        }\r
 \r
+       if( xAreAltBlockingQueuesStillRunning() != pdTRUE )\r
+       {\r
+               vDisplayMessage( "Alt blocking queues count unchanged!\r\n" );\r
+               sErrorHasOccurred = pdTRUE;\r
+       }\r
+\r
        if( xArePollingQueuesStillRunning() != pdTRUE )\r
        {\r
                vDisplayMessage( "Polling queue count unchanged!\r\n" );\r
                sErrorHasOccurred = pdTRUE;\r
        }\r
 \r
+       if( xAreAltPollingQueuesStillRunning() != pdTRUE )\r
+       {\r
+               vDisplayMessage( "Alt polling queue count unchanged!\r\n" );\r
+               sErrorHasOccurred = pdTRUE;\r
+       }\r
+\r
        if( xIsCreateTaskStillRunning() != pdTRUE )\r
        {\r
                vDisplayMessage( "Incorrect number of tasks running!\r\n" );\r
@@ -366,12 +386,24 @@ static portSHORT sErrorHasOccurred = pdFALSE;
                sErrorHasOccurred = pdTRUE;\r
        }\r
 \r
+       if( xAreAltBlockTimeTestTasksStillRunning() != pdTRUE )\r
+       {\r
+               vDisplayMessage( "Error in fast block time test tasks!\r\n" );\r
+               sErrorHasOccurred = pdTRUE;\r
+       }\r
+\r
        if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
        {\r
                vDisplayMessage( "Error in generic queue test task!\r\n" );\r
                sErrorHasOccurred = pdTRUE;             \r
        }\r
 \r
+       if( xAreAltGenericQueueTasksStillRunning() != pdTRUE )\r
+       {\r
+               vDisplayMessage( "Error in fast generic queue test task!\r\n" );\r
+               sErrorHasOccurred = pdTRUE;             \r
+       }\r
+\r
        if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
        {\r
                vDisplayMessage( "Error in queue peek test task!\r\n" );\r
index 022052d9925d2518fc77de32d3d6c01b80388b51..90a5900ac8955588476ccb899ce937bd5ed31367 100644 (file)
@@ -75,7 +75,7 @@ WVList
 0\r
 19\r
 WPickList\r
-55\r
+63\r
 20\r
 MItem\r
 3\r
@@ -707,7 +707,7 @@ WVList
 168\r
 MItem\r
 28\r
-..\COMMON\MINIMAL\blocktim.c\r
+..\COMMON\MINIMAL\AltBlckQ.c\r
 169\r
 WString\r
 4\r
@@ -725,7 +725,7 @@ WVList
 172\r
 MItem\r
 28\r
-..\COMMON\MINIMAL\countsem.c\r
+..\COMMON\MINIMAL\AltBlock.c\r
 173\r
 WString\r
 4\r
@@ -742,8 +742,8 @@ WVList
 0\r
 176\r
 MItem\r
-27\r
-..\COMMON\MINIMAL\crflash.c\r
+28\r
+..\COMMON\MINIMAL\AltPollQ.c\r
 177\r
 WString\r
 4\r
@@ -760,8 +760,8 @@ WVList
 0\r
 180\r
 MItem\r
-26\r
-..\COMMON\MINIMAL\crhook.c\r
+28\r
+..\COMMON\MINIMAL\AltQTest.c\r
 181\r
 WString\r
 4\r
@@ -779,7 +779,7 @@ WVList
 184\r
 MItem\r
 28\r
-..\COMMON\MINIMAL\GenQTest.c\r
+..\COMMON\MINIMAL\blocktim.c\r
 185\r
 WString\r
 4\r
@@ -796,8 +796,8 @@ WVList
 0\r
 188\r
 MItem\r
-25\r
-..\COMMON\MINIMAL\QPeek.c\r
+28\r
+..\COMMON\MINIMAL\countsem.c\r
 189\r
 WString\r
 4\r
@@ -814,8 +814,8 @@ WVList
 0\r
 192\r
 MItem\r
-15\r
-fileio\fileio.c\r
+27\r
+..\COMMON\MINIMAL\crflash.c\r
 193\r
 WString\r
 4\r
@@ -832,8 +832,8 @@ WVList
 0\r
 196\r
 MItem\r
-6\r
-main.c\r
+26\r
+..\COMMON\MINIMAL\crhook.c\r
 197\r
 WString\r
 4\r
@@ -850,8 +850,8 @@ WVList
 0\r
 200\r
 MItem\r
-17\r
-partest\partest.c\r
+28\r
+..\COMMON\MINIMAL\GenQTest.c\r
 201\r
 WString\r
 4\r
@@ -868,8 +868,8 @@ WVList
 0\r
 204\r
 MItem\r
-15\r
-serial\serial.c\r
+25\r
+..\COMMON\MINIMAL\QPeek.c\r
 205\r
 WString\r
 4\r
@@ -886,80 +886,80 @@ WVList
 0\r
 208\r
 MItem\r
-3\r
-*.h\r
+15\r
+fileio\fileio.c\r
 209\r
 WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
 210\r
 WVList\r
 0\r
 211\r
 WVList\r
 0\r
--1\r
+20\r
+1\r
 1\r
-0\r
 0\r
 212\r
 MItem\r
-31\r
-..\..\SOURCE\INCLUDE\croutine.h\r
+6\r
+main.c\r
 213\r
 WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
 214\r
 WVList\r
 0\r
 215\r
 WVList\r
 0\r
-208\r
+20\r
 1\r
 1\r
 0\r
 216\r
 MItem\r
-27\r
-..\..\source\include\list.h\r
+17\r
+partest\partest.c\r
 217\r
 WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
 218\r
 WVList\r
 0\r
 219\r
 WVList\r
 0\r
-208\r
+20\r
 1\r
 1\r
 0\r
 220\r
 MItem\r
-31\r
-..\..\source\include\portable.h\r
+15\r
+serial\serial.c\r
 221\r
 WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
 222\r
 WVList\r
 0\r
 223\r
 WVList\r
 0\r
-208\r
+20\r
 1\r
 1\r
 0\r
 224\r
 MItem\r
-31\r
-..\..\source\include\projdefs.h\r
+3\r
+*.h\r
 225\r
 WString\r
 3\r
@@ -970,14 +970,14 @@ WVList
 227\r
 WVList\r
 0\r
-208\r
-1\r
+-1\r
 1\r
 0\r
+0\r
 228\r
 MItem\r
-28\r
-..\..\source\include\queue.h\r
+31\r
+..\..\SOURCE\INCLUDE\croutine.h\r
 229\r
 WString\r
 3\r
@@ -988,14 +988,14 @@ WVList
 231\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 232\r
 MItem\r
-29\r
-..\..\source\include\semphr.h\r
+27\r
+..\..\source\include\list.h\r
 233\r
 WString\r
 3\r
@@ -1006,14 +1006,14 @@ WVList
 235\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 236\r
 MItem\r
-27\r
-..\..\source\include\task.h\r
+31\r
+..\..\source\include\portable.h\r
 237\r
 WString\r
 3\r
@@ -1024,14 +1024,14 @@ WVList
 239\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 240\r
 MItem\r
-55\r
-..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
+31\r
+..\..\source\include\projdefs.h\r
 241\r
 WString\r
 3\r
@@ -1042,14 +1042,14 @@ WVList
 243\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 244\r
 MItem\r
-53\r
-..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
+28\r
+..\..\source\include\queue.h\r
 245\r
 WString\r
 3\r
@@ -1060,14 +1060,14 @@ WVList
 247\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 248\r
 MItem\r
-26\r
-..\common\include\blockq.h\r
+29\r
+..\..\source\include\semphr.h\r
 249\r
 WString\r
 3\r
@@ -1078,14 +1078,14 @@ WVList
 251\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 252\r
 MItem\r
-28\r
-..\COMMON\INCLUDE\blocktim.h\r
+27\r
+..\..\source\include\task.h\r
 253\r
 WString\r
 3\r
@@ -1096,14 +1096,14 @@ WVList
 255\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 256\r
 MItem\r
-27\r
-..\common\include\comtest.h\r
+55\r
+..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
 257\r
 WString\r
 3\r
@@ -1114,14 +1114,14 @@ WVList
 259\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 260\r
 MItem\r
-28\r
-..\COMMON\INCLUDE\countsem.h\r
+53\r
+..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
 261\r
 WString\r
 3\r
@@ -1132,14 +1132,14 @@ WVList
 263\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 264\r
 MItem\r
-26\r
-..\COMMON\INCLUDE\crhook.h\r
+28\r
+..\COMMON\INCLUDE\AltBlckQ.h\r
 265\r
 WString\r
 3\r
@@ -1150,14 +1150,14 @@ WVList
 267\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 268\r
 MItem\r
-25\r
-..\common\include\death.h\r
+28\r
+..\COMMON\INCLUDE\AltBlock.h\r
 269\r
 WString\r
 3\r
@@ -1168,14 +1168,14 @@ WVList
 271\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 272\r
 MItem\r
-27\r
-..\COMMON\INCLUDE\dynamic.h\r
+28\r
+..\COMMON\INCLUDE\AltPollQ.h\r
 273\r
 WString\r
 3\r
@@ -1186,14 +1186,14 @@ WVList
 275\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 276\r
 MItem\r
-26\r
-..\common\include\fileio.h\r
+28\r
+..\COMMON\INCLUDE\AltQTest.h\r
 277\r
 WString\r
 3\r
@@ -1204,14 +1204,14 @@ WVList
 279\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 280\r
 MItem\r
-25\r
-..\common\include\flash.h\r
+26\r
+..\common\include\blockq.h\r
 281\r
 WString\r
 3\r
@@ -1222,14 +1222,14 @@ WVList
 283\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 284\r
 MItem\r
-24\r
-..\common\include\flop.h\r
+28\r
+..\COMMON\INCLUDE\blocktim.h\r
 285\r
 WString\r
 3\r
@@ -1240,14 +1240,14 @@ WVList
 287\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 288\r
 MItem\r
-28\r
-..\COMMON\INCLUDE\GenQTest.h\r
+27\r
+..\common\include\comtest.h\r
 289\r
 WString\r
 3\r
@@ -1258,14 +1258,14 @@ WVList
 291\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 292\r
 MItem\r
-27\r
-..\common\include\partest.h\r
+28\r
+..\COMMON\INCLUDE\countsem.h\r
 293\r
 WString\r
 3\r
@@ -1276,14 +1276,14 @@ WVList
 295\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 296\r
 MItem\r
-25\r
-..\common\include\pollq.h\r
+26\r
+..\COMMON\INCLUDE\crhook.h\r
 297\r
 WString\r
 3\r
@@ -1294,14 +1294,14 @@ WVList
 299\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 300\r
 MItem\r
 25\r
-..\common\include\print.h\r
+..\common\include\death.h\r
 301\r
 WString\r
 3\r
@@ -1312,14 +1312,14 @@ WVList
 303\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 304\r
 MItem\r
 27\r
-..\common\include\semtest.h\r
+..\COMMON\INCLUDE\dynamic.h\r
 305\r
 WString\r
 3\r
@@ -1330,14 +1330,14 @@ WVList
 307\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 308\r
 MItem\r
 26\r
-..\common\include\serial.h\r
+..\common\include\fileio.h\r
 309\r
 WString\r
 3\r
@@ -1348,14 +1348,14 @@ WVList
 311\r
 WVList\r
 0\r
-208\r
+224\r
 1\r
 1\r
 0\r
 312\r
 MItem\r
-16\r
-FreeRTOSConfig.h\r
+25\r
+..\common\include\flash.h\r
 313\r
 WString\r
 3\r
@@ -1366,7 +1366,151 @@ WVList
 315\r
 WVList\r
 0\r
-208\r
+224\r
+1\r
+1\r
+0\r
+316\r
+MItem\r
+24\r
+..\common\include\flop.h\r
+317\r
+WString\r
+3\r
+NIL\r
+318\r
+WVList\r
+0\r
+319\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+320\r
+MItem\r
+28\r
+..\COMMON\INCLUDE\GenQTest.h\r
+321\r
+WString\r
+3\r
+NIL\r
+322\r
+WVList\r
+0\r
+323\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+324\r
+MItem\r
+27\r
+..\common\include\partest.h\r
+325\r
+WString\r
+3\r
+NIL\r
+326\r
+WVList\r
+0\r
+327\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+328\r
+MItem\r
+25\r
+..\common\include\pollq.h\r
+329\r
+WString\r
+3\r
+NIL\r
+330\r
+WVList\r
+0\r
+331\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+332\r
+MItem\r
+25\r
+..\common\include\print.h\r
+333\r
+WString\r
+3\r
+NIL\r
+334\r
+WVList\r
+0\r
+335\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+336\r
+MItem\r
+27\r
+..\common\include\semtest.h\r
+337\r
+WString\r
+3\r
+NIL\r
+338\r
+WVList\r
+0\r
+339\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+340\r
+MItem\r
+26\r
+..\common\include\serial.h\r
+341\r
+WString\r
+3\r
+NIL\r
+342\r
+WVList\r
+0\r
+343\r
+WVList\r
+0\r
+224\r
+1\r
+1\r
+0\r
+344\r
+MItem\r
+16\r
+FreeRTOSConfig.h\r
+345\r
+WString\r
+3\r
+NIL\r
+346\r
+WVList\r
+0\r
+347\r
+WVList\r
+0\r
+224\r
 1\r
 1\r
 0\r
index 3c869d9bc3d459b5a5678cc4b93e8bba034b9abd..f02b7811a189f900e4c0e20dc3515a83c455e2a2 100644 (file)
@@ -4,10 +4,10 @@ projectIdent
 VpeMain\r
 1\r
 WRect\r
-6\r
-9\r
-6229\r
-7197\r
+0\r
+0\r
+6209\r
+7168\r
 2\r
 MProject\r
 3\r
@@ -31,7 +31,7 @@ WRect
 0\r
 0\r
 7168\r
-8270\r
+8192\r
 0\r
 0\r
 9\r
@@ -39,5 +39,5 @@ WFileName
 12\r
 rtosdemo.tgt\r
 0\r
-25\r
+0\r
 7\r
index ea8b46ad4ea7944b1a65af77eecfeb0d2d611418..f5829b07a902de6be953d429c5f9832630d56eb1 100644 (file)
        #error Missing definition:  configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.\r
 #endif\r
 \r
+#ifndef configUSE_MUTEXES\r
+       #define configUSE_MUTEXES 0\r
+#endif\r
+\r
 #ifndef configUSE_COUNTING_SEMAPHORES\r
        #define configUSE_COUNTING_SEMAPHORES 0\r
 #endif\r
 \r
-#ifndef configUSE_MUTEXES\r
-       #define configUSE_MUTEXES 0\r
+#ifndef configUSE_ALTERNATIVE_API\r
+       #define configUSE_ALTERNATIVE_API 0\r
 #endif\r
 \r
 #if ( configUSE_MUTEXES == 1 )\r
index 611389f1997e13d86f8825e8a8f272737cfb607e..0bd23fc0ba05ca08b9893534483988d924583587 100644 (file)
@@ -1159,6 +1159,30 @@ signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void
  */\r
 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
 \r
+/* \r
+ * xQueueAltGenericSend() is a light weight version of xQueueGenericSend().\r
+ * Likewise xQueueAltGenericReceive() is a light weight version of\r
+ * xQueueGenericReceive().\r
+ *\r
+ * The source code that implements the light weight (fast) API is much \r
+ * simpler     because it executes everything from within a critical section.  \r
+ * This is     the approach taken by many other RTOSes, but FreeRTOS.org has the \r
+ * fully featured API as an alternative.  The fully featured API has more \r
+ * complex     code that takes longer to execute, but makes much less use of \r
+ * critical sections.  Therefore the light weight API sacrifices interrupt \r
+ * responsiveness to gain execution speed, whereas the fully featured API\r
+ * sacrifices execution speed to ensure better interrupt responsiveness.\r
+ */\r
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
+\r
+/*\r
+ * The light weight versions of the fully featured macros.\r
+ */\r
+#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )\r
+#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )\r
+#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )\r
+#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )\r
 \r
 /*\r
  * The functions defined above are for passing data to and from tasks.  The\r
index a1ada86aabdf65610f6e141eced208ff221032bf..6cf63061cd7c532fe9e2bbedaa578d6e25f3f258 100644 (file)
@@ -154,7 +154,8 @@ typedef xQueueHandle xSemaphoreHandle;
  * \defgroup xSemaphoreTake xSemaphoreTake\r
  * \ingroup Semaphores\r
  */\r
-#define xSemaphoreTake( xSemaphore, xBlockTime )       xQueueReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime )\r
+#define xSemaphoreTake( xSemaphore, xBlockTime )               xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )\r
+#define xSemaphoreAltTake( xSemaphore, xBlockTime )            xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE )\r
 \r
 /**\r
  * semphr. h\r
@@ -213,7 +214,8 @@ typedef xQueueHandle xSemaphoreHandle;
  * \defgroup xSemaphoreGive xSemaphoreGive\r
  * \ingroup Semaphores\r
  */\r
-#define xSemaphoreGive( xSemaphore )                           xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
+#define xSemaphoreGive( xSemaphore )           xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
+#define xSemaphoreAltGive( xSemaphore )                xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
 \r
 /**\r
  * semphr. h\r
index 07bec78365af26bf0d31c5e3248c0bd8a3e8b419..2856a46ac503cf989e063d71c285c7504e64fe5d 100644 (file)
@@ -77,6 +77,11 @@ is being used. */
 /* Trap routine used by taskYIELD() to manually cause a context switch. */\r
 static void __interrupt __far prvYieldProcessor( void );\r
 \r
+/* The timer initialisation functions leave interrupts enabled,\r
+which is not what we want.  This ISR is installed temporarily in case\r
+the timer fires before we get a change to disable interrupts again. */\r
+static void __interrupt __far prvDummyISR( void );\r
+\r
 /*-----------------------------------------------------------*/\r
 /* See header file for description. */\r
 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
@@ -162,6 +167,15 @@ portBASE_TYPE xPortStartScheduler( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void __interrupt __far prvDummyISR( void )\r
+{\r
+       /* The timer initialisation functions leave interrupts enabled,\r
+       which is not what we want.  This ISR is installed temporarily in case\r
+       the timer fires before we get a change to disable interrupts again. */\r
+       outport( portEIO_REGISTER, portCLEAR_INTERRUPT );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 /* The ISR used depends on whether the preemptive or cooperative scheduler\r
 is being used. */\r
 #if( configUSE_PREEMPTION == 1 )\r
@@ -204,15 +218,23 @@ void vPortEndScheduler( void )
 static void prvSetupTimerInterrupt( void )\r
 {\r
 const unsigned portSHORT usTimerACompare = portTIMER_COMPARE, usTimerAMode = portENABLE_TIMER_AND_INTERRUPT;\r
+const unsigned portSHORT usT2_IRQ = 0x13;\r
+\r
+       /* Configure the timer, the dummy handler is used here as the init\r
+       function leaves interrupts enabled. */\r
+       t2_init( usTimerAMode, usTimerACompare, prvDummyISR );\r
+\r
+       /* Disable interrupts again before installing the real handlers. */\r
+       portDISABLE_INTERRUPTS();\r
 \r
        #if( configUSE_PREEMPTION == 1 )\r
                /* Tick service routine used by the scheduler when preemptive scheduling is\r
                being used. */\r
-               t2_init( usTimerAMode, usTimerACompare, prvPreemptiveTick );\r
+               setvect( usT2_IRQ, prvPreemptiveTick );\r
        #else\r
                /* Tick service routine used by the scheduler when cooperative scheduling is\r
                being used. */\r
-               t2_init( usTimerAMode, usTimerACompare, prvNonPreemptiveTick );\r
+               setvect( usT2_IRQ, prvNonPreemptiveTick );\r
        #endif\r
 }\r
 \r
index ba0e893838164e9e721f1ccb19b23c627e2ea63d..22f8d9a42c1c8ecd6afe36c9672211c95051a500 100644 (file)
@@ -77,7 +77,7 @@ typedef struct QueueDefinition
        xList xTasksWaitingToSend;                              /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */\r
        xList xTasksWaitingToReceive;                   /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */\r
 \r
-       unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */\r
+       volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */\r
        unsigned portBASE_TYPE uxLength;                /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */\r
        unsigned portBASE_TYPE uxItemSize;              /*< The size of each items that the queue will hold. */\r
 \r
@@ -107,6 +107,8 @@ signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * co
 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
 xQueueHandle xQueueCreateMutex( void );\r
 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );\r
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
 \r
 #if configUSE_CO_ROUTINES == 1\r
        signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
@@ -455,6 +457,202 @@ xTimeOutType xTimeOut;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+#if configUSE_ALTERNATIVE_API == 1\r
+\r
+       signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
+       {\r
+       signed portBASE_TYPE xReturn;\r
+       xTimeOutType xTimeOut;\r
+\r
+               /* The source code that implements the light weight (fast) API is much \r
+               simpler because it executes everything from within a critical section.  \r
+               This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
+               fully featured API as an alternative.  The fully featured API has more \r
+               complex code that takes longer to execute, but makes much less use of \r
+               critical sections.  Therefore the light weight API sacrifices interrupt \r
+               responsiveness to gain execution speed, whereas the fully featured API\r
+               sacrifices execution speed to ensure better interrupt responsiveness.  */\r
+\r
+               taskENTER_CRITICAL();\r
+               {\r
+                       /* Capture the current time status for future reference. */\r
+                       vTaskSetTimeOutState( &xTimeOut );\r
+\r
+                       /* If the queue is already full we may have to block. */\r
+                       do\r
+                       {\r
+                               if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )\r
+                               {\r
+                                       /* The queue is full - do we want to block or just leave without\r
+                                       posting? */\r
+                                       if( xTicksToWait > ( portTickType ) 0 )\r
+                                       {\r
+                                               /* We are going to place ourselves on the xTasksWaitingToSend \r
+                                               event list, and will get woken should the delay expire, or \r
+                                               space become available on the queue. */\r
+                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+                       \r
+                                               /* Force a context switch now as we are blocked.  We can do\r
+                                               this from within a critical section as the task we are\r
+                                               switching to has its own context.  When we return here (i.e.\r
+                                               we unblock) we will leave the critical section as normal. */\r
+                                               taskYIELD();\r
+                                       }\r
+                               }\r
+                                       \r
+                               if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+                               {\r
+                                       /* There is room in the queue, copy the data into the queue. */                 \r
+                                       prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
+                                       xReturn = pdPASS;\r
+\r
+                                       if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
+                                       {\r
+                                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                               {\r
+                                                       /* The task waiting has a higher priority. */\r
+                                                       taskYIELD();\r
+                                               }\r
+                                       }                       \r
+                               }\r
+                               else\r
+                               {\r
+                                       xReturn = errQUEUE_FULL;\r
+\r
+                                       if( xTicksToWait > 0 )\r
+                                       {                                       \r
+                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                                               {\r
+                                                       /* Another task must have accessed the queue between \r
+                                                       this task unblocking and actually executing. */\r
+                                                       xReturn = queueERRONEOUS_UNBLOCK;\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               \r
+                                       }\r
+                               }\r
+                       }\r
+                       while( xReturn == queueERRONEOUS_UNBLOCK );\r
+               }\r
+               taskEXIT_CRITICAL();\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif /* configUSE_ALTERNATIVE_API */\r
+/*-----------------------------------------------------------*/\r
+\r
+#if configUSE_ALTERNATIVE_API == 1\r
+\r
+       signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
+       {\r
+       signed portBASE_TYPE xReturn = pdTRUE;\r
+       xTimeOutType xTimeOut;\r
+       signed portCHAR *pcOriginalReadPosition;\r
+\r
+               /* The source code that implements the light weight (fast) API is much \r
+               simpler because it executes everything from within a critical section.  \r
+               This is the approach taken by many other RTOSes, but FreeRTOS.org has the \r
+               fully featured API as an alternative.  The fully featured API has more \r
+               complex code that takes longer to execute, but makes much less use of \r
+               critical sections.  Therefore the light weight API sacrifices interrupt \r
+               responsiveness to gain execution speed, whereas the fully featured API\r
+               sacrifices execution speed to ensure better interrupt responsiveness.  */\r
+\r
+               taskENTER_CRITICAL();\r
+               {\r
+                       /* Capture the current time status for future reference. */\r
+                       vTaskSetTimeOutState( &xTimeOut );\r
+\r
+                       do\r
+                       {\r
+                               /* If there are no messages in the queue we may have to block. */\r
+                               if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
+                               {\r
+                                       /* There are no messages in the queue, do we want to block or just\r
+                                       leave with nothing? */                  \r
+                                       if( xTicksToWait > ( portTickType ) 0 )\r
+                                       {\r
+                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               {\r
+                                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                                       {\r
+                                                               vTaskPriorityInherit( ( void * const ) pxQueue->pxMutexHolder );\r
+                                                       }\r
+                                               }\r
+                                               #endif\r
+                                               \r
+                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                                               taskYIELD();\r
+                                       }\r
+                               }\r
+                       \r
+                               if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+                               {\r
+                                       /* Remember our read position in case we are just peeking. */\r
+                                       pcOriginalReadPosition = pxQueue->pcReadFrom;\r
+\r
+                                       prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+\r
+                                       if( xJustPeeking == pdFALSE )\r
+                                       {\r
+                                               /* We are actually removing data. */\r
+                                               --( pxQueue->uxMessagesWaiting );\r
+                                                       \r
+                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               {\r
+                                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                                       {\r
+                                                               /* Record the information required to implement\r
+                                                               priority inheritance should it become necessary. */\r
+                                                               pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();\r
+                                                       }\r
+                                               }\r
+                                               #endif\r
+\r
+                                               if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
+                                               {\r
+                                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+                                                       {\r
+                                                               /* The task waiting has a higher priority. */\r
+                                                               taskYIELD();\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               /* We are not removing the data, so reset our read\r
+                                               pointer. */\r
+                                               pxQueue->pcReadFrom = pcOriginalReadPosition;\r
+                                       }\r
+                                       \r
+                                       xReturn = pdPASS;                                       \r
+                               }\r
+                               else\r
+                               {\r
+                                       xReturn = errQUEUE_EMPTY;\r
+\r
+                                       if( xTicksToWait > 0 )\r
+                                       {\r
+                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                                               {\r
+                                                       xReturn = queueERRONEOUS_UNBLOCK;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                       } while( xReturn == queueERRONEOUS_UNBLOCK );\r
+               }\r
+               taskEXIT_CRITICAL();\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif /* configUSE_ALTERNATIVE_API */\r
+/*-----------------------------------------------------------*/\r
+\r
 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition )\r
 {\r
        /* Similar to xQueueGenericSend, except we don't block if there is no room\r