]> git.sur5r.net Git - freertos/commitdiff
Added xQueueSendToBack, xQueueSendToFront, xQueuePeek and xSemaphoreCreateMutex ...
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 21 Aug 2007 16:54:48 +0000 (16:54 +0000)
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 21 Aug 2007 16:54:48 +0000 (16:54 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@103 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

18 files changed:
Demo/Common/Full/BlockQ.c
Demo/Common/Full/PollQ.c
Demo/Common/Full/dynamic.c
Demo/Common/Full/events.c
Demo/Common/Minimal/GenQTest.c [new file with mode: 0644]
Demo/Common/include/GenQTest.h [new file with mode: 0644]
Demo/PC/FreeRTOSConfig.h
Demo/PC/main.c
Demo/PC/rtosdemo.tgt
Demo/PC/rtosdemo.wpj
Demo/PC/serial/serial.c
Source/include/FreeRTOS.h
Source/include/queue.h
Source/include/semphr.h
Source/include/task.h
Source/portable/Paradigm/Tern_EE/large_untested/portasm.h
Source/queue.c
Source/tasks.c

index 6c96a79b022fcc19f0bfaaaa5539541a8a3cf859..e7688ae33540527277365d6e556421c6de6eb8fc 100644 (file)
@@ -89,7 +89,7 @@ Changes from V4.0.2
 #include "BlockQ.h"\r
 #include "print.h"\r
 \r
-#define blckqSTACK_SIZE                ( ( unsigned portSHORT ) 128 )\r
+#define blckqSTACK_SIZE                ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE )\r
 #define blckqNUM_TASK_SETS     ( 3 )\r
 \r
 /* Structure used to pass parameters to the blocking queue tasks. */\r
@@ -215,7 +215,7 @@ portSHORT sErrorEverOccurred = pdFALSE;
 \r
        for( ;; )\r
        {               \r
-               if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )\r
+               if( xQueueSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS )\r
                {\r
                        vPrintDisplayMessage( &pcTaskErrorMsg );\r
                        sErrorEverOccurred = pdTRUE;\r
index dd6ac8bdd86af39633dc931d2a708f5ff13e2236..cfd1cba37ba23ed842825966669402ef30dea532 100644 (file)
@@ -78,7 +78,7 @@ Changes from V2.0.0
 /* Demo program include files. */\r
 #include "PollQ.h"\r
 \r
-#define pollqSTACK_SIZE                ( ( unsigned portSHORT ) 128 )\r
+#define pollqSTACK_SIZE                ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE )\r
 \r
 /* The task that posts the incrementing number onto the queue. */\r
 static void vPolledQueueProducer( void *pvParameters );\r
@@ -125,7 +125,7 @@ portSHORT sError = pdFALSE;
                for( usLoop = 0; usLoop < usNumToProduce; ++usLoop )\r
                {\r
                        /* Send an incrementing number on the queue without blocking. */\r
-                       if( xQueueSend( *pxQueue, ( void * ) &usValue, ( portTickType ) 0 ) != pdPASS )\r
+                       if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( portTickType ) 0 ) != pdPASS )\r
                        {\r
                                /* We should never find the queue full - this is an error. */\r
                                vPrintDisplayMessage( &pcTaskErrorMsg );\r
index 128785d0d1179df419064b17b8d0e547419ba2a2..454e7524ac53dc705c9ad368611d4a8897449e9f 100644 (file)
@@ -146,7 +146,7 @@ static void prvChangePriorityHelperTask( void *pvParameters );
 \r
 \r
 /* Demo task specific constants. */\r
-#define priSTACK_SIZE                          ( ( unsigned portSHORT ) 128 )\r
+#define priSTACK_SIZE                          ( ( unsigned portSHORT ) configMINIMAL_STACK_SIZE )\r
 #define priSLEEP_TIME                          ( ( portTickType ) 50 )\r
 #define priLOOPS                                       ( 5 )\r
 #define priMAX_COUNT                           ( ( unsigned portLONG ) 0xff )\r
@@ -193,7 +193,7 @@ void vStartDynamicPriorityTasks( void )
        xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_SEND", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
        xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RECV", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
        xTaskCreate( prvChangePriorityWhenSuspendedTask, "1st_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL );\r
-       xTaskCreate( prvChangePriorityHelperTask, "2nt_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle );\r
+       xTaskCreate( prvChangePriorityHelperTask, "2nd_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
index 630c11076e5d1886a876f65cd626c36513c5a020..ab39bacfdad30f277b3c0e7319cd93edd3bb3e37 100644 (file)
@@ -68,7 +68,7 @@
 #include "print.h"\r
 \r
 /* Demo specific constants. */\r
-#define evtSTACK_SIZE          ( ( unsigned portBASE_TYPE ) 128 )\r
+#define evtSTACK_SIZE          ( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE )\r
 #define evtNUM_TASKS           ( 4 )\r
 #define evtQUEUE_LENGTH                ( ( unsigned portBASE_TYPE ) 3 )\r
 #define evtNO_DELAY                                            0\r
diff --git a/Demo/Common/Minimal/GenQTest.c b/Demo/Common/Minimal/GenQTest.c
new file mode 100644 (file)
index 0000000..275b814
--- /dev/null
@@ -0,0 +1,536 @@
+/*\r
+       FreeRTOS.org V4.4.0 - 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 for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+\r
+/* \r
+ * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - \r
+ * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and \r
+ * mutex behaviour. \r
+ *\r
+ * See the comments above the prvSendFrontAndBackTest() and \r
+ * prvLowPriorityMutexTask() prototypes below for more information.\r
+ */\r
+\r
+\r
+#include <stdlib.h>\r
+\r
+/* Scheduler include files. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* Demo program include files. */\r
+#include "GenQTest.h"\r
+\r
+#define genqQUEUE_LENGTH               ( 5 )\r
+#define genqNO_BLOCK                   ( 0 )\r
+\r
+#define genqMUTEX_LOW_PRIORITY         ( tskIDLE_PRIORITY )\r
+#define genqMUTEX_TEST_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
+#define genqMUTEX_MEDIUM_PRIORITY      ( tskIDLE_PRIORITY + 2 )\r
+#define genqMUTEX_HIGH_PRIORITY                ( tskIDLE_PRIORITY + 3 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack()\r
+ * macros by using both to fill a queue, then reading from the queue to\r
+ * check the resultant queue order is as expected.  Queue data is also\r
+ * peeked.\r
+ */\r
+static void prvSendFrontAndBackTest( void *pvParameters );\r
+\r
+/*\r
+ * The following three tasks are used to demonstrate the mutex behaviour.\r
+ * Each task is given a different priority to demonstrate the priority\r
+ * inheritance mechanism.\r
+ *\r
+ * The low priority task obtains a mutex.  After this a high priority task\r
+ * attempts to obtain the same mutex, causing its priority to be inherited\r
+ * by the low priority task.  The task with the inherited high priority then\r
+ * resumes a medium priority task to ensure it is not blocked by the medium\r
+ * priority task while it holds the inherited high priority.  Once the mutex\r
+ * is returned the task with the inherited priority returns to its original\r
+ * low priority, and is therefore immediately preempted by first the high\r
+ * priority task and then the medium prioroity task before it can continue.\r
+ */\r
+static void prvLowPriorityMutexTask( void *pvParameters );\r
+static void prvMediumPriorityMutexTask( void *pvParameters );\r
+static void prvHighPriorityMutexTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
+detected in any of the tasks. */\r
+static portBASE_TYPE xErrorDetected = pdFALSE;\r
+\r
+/* Counters that are incremented on each cycle of a test.  This is used to\r
+detect a stalled task - a test that is no longer running. */\r
+static volatile unsigned portLONG ulLoopCounter = 0;\r
+static volatile unsigned portLONG ulLoopCounter2 = 0;\r
+\r
+/* The variable that is guarded by the mutex in the mutex demo tasks. */\r
+static volatile unsigned portLONG ulGuardedVariable = 0;\r
+\r
+/* Handles used in the mutext test to suspend and resume the high and medium\r
+priority mutex test tasks. */\r
+static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+{\r
+xQueueHandle xQueue;\r
+xSemaphoreHandle xMutex;\r
+\r
+       /* Create the queue that we are going to use for the\r
+       prvSendFrontAndBackTest demo. */\r
+       xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );\r
+\r
+       /* 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, "GenQ", 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, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );\r
+       xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );\r
+       xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSendFrontAndBackTest( void *pvParameters )\r
+{\r
+unsigned portLONG ulData, ulData2;\r
+xQueueHandle xQueue;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       xQueue = ( xQueueHandle ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* The queue is empty, so sending an item to the back of the queue\r
+               should have the same efect as sending it to the front of the queue.\r
+\r
+               First send to the front and check everything is as expected. */\r
+               xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* The data we sent to the queue should equal the data we just received\r
+               from the queue. */\r
+               if( ulLoopCounter != ulData )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Then do the same, sending the data to the back, checking everything\r
+               is as expected. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* The data we sent to the queue should equal the data we just received\r
+               from the queue. */\r
+               if( ulLoopCounter != ulData )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+\r
+\r
+               /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */\r
+               for( ulData = 2; ulData < 5; ulData++ )\r
+               {\r
+                       xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               }\r
+\r
+               /* Now the order in the queue should be 2, 3, 4, with 2 being the first\r
+               thing to be read out.  Now add 1 then 0 to the front of the queue. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 3 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+               ulData = 1;\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               ulData = 0;\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+\r
+               /* Now the queue should be full, and when we read the data out we\r
+               should receive 0, 1, 2, 3, 4. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               /* Check the data we read out is in the expected order. */\r
+               for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )\r
+               {\r
+                       /* Try peeking the data first. */\r
+                       if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+                       \r
+\r
+                       /* Now try receiving the data for real.  The value should be the\r
+                       same.  Clobber the value first so we know we really received it. */\r
+                       ulData2 = ~ulData2;\r
+                       if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* The queue should now be empty again. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+\r
+               /* Our queue is empty once more, add 10, 11 to the back. */\r
+               ulData = 10;\r
+               if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+               ulData = 11;\r
+               if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 2 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now we should have 10, 11 in the queue.  Add 7, 8, 9 to the\r
+               front. */\r
+               for( ulData = 9; ulData >= 7; ulData-- )\r
+               {\r
+                       if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Now check that the queue is full, and that receiving data provides\r
+               the expected sequence of 7, 8, 9, 10, 11. */\r
+               if( uxQueueMessagesWaiting( xQueue ) != 5 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               /* Check the data we read out is in the expected order. */\r
+               for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ )\r
+               {\r
+                       if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+\r
+                       if( ulData != ulData2 )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               ulLoopCounter++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
+       \r
+               const portCHAR * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n";\r
+\r
+               /* Queue a message for printing to say the task has started. */\r
+               vPrintDisplayMessage( &pcTaskStartMsg );\r
+       #endif\r
+\r
+       for( ;; )\r
+       {\r
+               /* Take the mutex.  It should be available now. */\r
+               if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Set our guarded variable to a known start value. */\r
+               ulGuardedVariable = 0;\r
+\r
+               /* Our priority should be as per that assigned when the task was\r
+               created. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now unsuspend the high priority task.  This will attempt to take the\r
+               mutex, and block when it finds it cannot obtain it. */\r
+               vTaskResume( xHighPriorityMutexTask );\r
+\r
+               /* We should now have inherited the prioritoy of the high priority task,\r
+               as by now it will have attempted to get the mutex. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* We can attempt to set our priority to the test priority - between the\r
+               idle priority and the medium/high test priorities, but our actual\r
+               prioroity should remain at the high priority. */\r
+               vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Now unsuspend the medium priority task.  This should not run as our\r
+               inherited priority is above that of the medium priority task. */\r
+               vTaskResume( xMediumPriorityMutexTask );\r
+\r
+               /* If the did run then it will have incremented our guarded variable. */\r
+               if( ulGuardedVariable != 0 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we give back the semaphore our priority should be disinherited\r
+               back to the priority to which we attempted to set ourselves.  This means\r
+               that when the high priority task next blocks, the medium priority task\r
+               should execute and increment the guarded variable.   When we next run\r
+               both the high and medium priority tasks will have been suspended again. */\r
+               if( xSemaphoreGive( xMutex ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Check that the guarded variable did indeed increment... */\r
+               if( ulGuardedVariable != 1 )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* ... and that our priority has been disinherited to\r
+               genqMUTEX_TEST_PRIORITY. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* Set our priority back to our original priority ready for the next\r
+               loop around this test. */\r
+               vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );\r
+\r
+               /* Just to show we are still running. */\r
+               ulLoopCounter2++;\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif          \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMediumPriorityMutexTask( void *pvParameters )\r
+{\r
+       for( ;; )\r
+       {\r
+               /* The medium priority task starts by suspending itself.  The low\r
+               priority task will unsuspend this task when required. */\r
+               vTaskSuspend( NULL );\r
+\r
+               /* When this task unsuspends all it does is increment the guarded\r
+               variable, this is so the low priority task knows that it has\r
+               executed. */\r
+               ulGuardedVariable++;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHighPriorityMutexTask( void *pvParameters )\r
+{\r
+xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* The high priority task starts by suspending itself.  The low\r
+               priority task will unsuspend this task when required. */\r
+               vTaskSuspend( NULL );\r
+\r
+               /* When this task unsuspends all it does is attempt to obtain\r
+               the mutex.  It should find the mutex is not available so a\r
+               block time is specified. */\r
+               if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* When we eventually obtain the mutex we just give it back then\r
+               return to suspend ready for the next test. */\r
+               if( xSemaphoreGive( xMutex ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }               \r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is called to check that all the created tasks are still running. */\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void )\r
+{\r
+static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;\r
+\r
+       /* If the demo task is still running then we expect the loopcounters to\r
+       have incremented since this function was last called. */\r
+       if( ulLastLoopCounter == ulLoopCounter )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       if( ulLastLoopCounter2 == ulLoopCounter2 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       ulLastLoopCounter = ulLoopCounter;\r
+       ulLastLoopCounter2 = ulLoopCounter2;    \r
+\r
+       /* Errors detected in the task itself will have latched xErrorDetected\r
+       to true. */\r
+\r
+       return !xErrorDetected;\r
+}\r
+\r
+\r
diff --git a/Demo/Common/include/GenQTest.h b/Demo/Common/include/GenQTest.h
new file mode 100644 (file)
index 0000000..8adbb7b
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+       FreeRTOS.org V4.4.0 - 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 for an IEC 61508 compliant version along\r
+       with commercial development and support options.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef GEN_Q_TEST_H\r
+#define GEN_Q_TEST_H\r
+\r
+void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority );\r
+portBASE_TYPE xAreGenericQueueTasksStillRunning( void );\r
+\r
+#endif /* GEN_Q_TEST_H */\r
+\r
+\r
+\r
index 0920a60e673f59debf0c4acde4640f6d17982402..97eb232d3ee0168f4a08f20865fcb684bd1c43b7 100644 (file)
 #define configUSE_IDLE_HOOK                    1\r
 #define configUSE_TICK_HOOK                    1\r
 #define configTICK_RATE_HZ                     ( ( portTickType ) 1000 )\r
-#define configMINIMAL_STACK_SIZE       ( ( unsigned portSHORT ) 128 ) /* This can be made smaller if required. */\r
+#define configMINIMAL_STACK_SIZE       ( ( unsigned portSHORT ) 256 ) /* This can be made smaller if required. */\r
 #define configTOTAL_HEAP_SIZE          ( ( size_t ) ( 32 * 1024 ) ) \r
 #define configMAX_TASK_NAME_LEN                ( 16 )\r
 #define configUSE_TRACE_FACILITY    1\r
 #define configUSE_16_BIT_TICKS      1\r
 #define configIDLE_SHOULD_YIELD                1\r
 #define configUSE_CO_ROUTINES          1\r
+#define configUSE_MUTEXES                      1\r
 \r
 #define configMAX_PRIORITIES           ( ( unsigned portBASE_TYPE ) 10 )\r
 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
index 055095f1d4a569fe7204e2a650116082633cf831..6811bbb103cd2abf56da9a57e35aedc7783b7cc1 100644 (file)
@@ -119,6 +119,7 @@ Changes from V3.2.4
 #include "mevents.h"\r
 #include "crhook.h"\r
 #include "blocktim.h"\r
+#include "GenQTest.h"\r
 \r
 /* Priority definitions for the tasks in the demo application. */\r
 #define mainLED_TASK_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
@@ -128,6 +129,7 @@ Changes from V3.2.4
 #define mainQUEUE_BLOCK_PRIORITY       ( tskIDLE_PRIORITY + 3 )\r
 #define mainCOM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
 #define mainSEMAPHORE_TASK_PRIORITY    ( tskIDLE_PRIORITY + 1 )\r
+#define mainGENERIC_QUEUE_PRIORITY     ( tskIDLE_PRIORITY )\r
 \r
 #define mainPRINT_STACK_SIZE           ( ( unsigned portSHORT ) 512 )\r
 #define mainDEBUG_LOG_BUFFER_SIZE      ( ( unsigned portSHORT ) 20480 )\r
@@ -176,7 +178,7 @@ portSHORT main( void )
        vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
        vStartBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );\r
        vCreateBlockTimeTasks();\r
-       \r
+       vStartGenericQueueTasks( mainGENERIC_QUEUE_PRIORITY );\r
        vStartSemaphoreTasks( mainSEMAPHORE_TASK_PRIORITY );\r
        vStartDynamicPriorityTasks();\r
        vStartMultiEventTasks();\r
@@ -391,6 +393,12 @@ static portSHORT sErrorHasOccurred = pdFALSE;
                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( sErrorHasOccurred == pdFALSE )\r
        {\r
                vDisplayMessage( "OK " );\r
index 7b5f2d66ddc6f1114d3b00221d32064d0ad2c663..53595149daba68d3bca5209ab6c56e220e9bf2dc 100644 (file)
@@ -15,7 +15,7 @@ WString
 de6en\r
 1\r
 0\r
-0\r
+1\r
 4\r
 MCommand\r
 0\r
@@ -75,7 +75,7 @@ WVList
 0\r
 19\r
 WPickList\r
-50\r
+52\r
 20\r
 MItem\r
 3\r
@@ -97,11 +97,11 @@ WCC
 WString\r
 25\r
 d????Include directories:\r
-1\r
+0\r
 26\r
 WString\r
-97\r
-$(%watcom)\h;..\common\include;..\..\source\include;..\..\source\portable\owatcom\16bitdos\common\r
+99\r
+$(%watcom)\h;..\common\include;..\..\source\include;..\..\source\portable\owatcom\16bitdos\common;.\r
 0\r
 27\r
 MCState\r
@@ -113,7 +113,7 @@ WCC
 WString\r
 26\r
 ?????Force ANSI compliance\r
-1\r
+0\r
 1\r
 30\r
 MCState\r
@@ -125,7 +125,7 @@ WCC
 WString\r
 33\r
 ?????Disable stack depth checking\r
-1\r
+0\r
 1\r
 33\r
 MVState\r
@@ -137,11 +137,11 @@ WCC
 WString\r
 23\r
 ?????Macro definitions:\r
-1\r
+0\r
 36\r
 WString\r
-52\r
-OPEN_WATCOM_INDUSTRIAL_PC_PORT USE_STDIO DEBUG_BUILD\r
+40\r
+OPEN_WATCOM_INDUSTRIAL_PC_PORT USE_STDIO\r
 0\r
 37\r
 MCState\r
@@ -153,7 +153,7 @@ WCC
 WString\r
 34\r
 ?????Change char default to signed\r
-1\r
+0\r
 1\r
 40\r
 MRState\r
@@ -163,10 +163,10 @@ WString
 WCC\r
 42\r
 WString\r
-21\r
-?????Compiler default\r
-1\r
+29\r
+?????No debugging information\r
 0\r
+1\r
 43\r
 MRState\r
 44\r
@@ -175,9 +175,9 @@ WString
 WCC\r
 45\r
 WString\r
-21\r
-?????Compiler default\r
-1\r
+28\r
+?????Line number information\r
+0\r
 0\r
 46\r
 MRState\r
@@ -187,22 +187,22 @@ WString
 WCC\r
 48\r
 WString\r
-25\r
-?????Floating-point calls\r
-1\r
-1\r
+21\r
+?????Compiler default\r
+0\r
+0\r
 49\r
-MCState\r
+MRState\r
 50\r
 WString\r
 3\r
 WCC\r
 51\r
 WString\r
-31\r
-???e?SS not assumed equal to DS\r
-1\r
-1\r
+21\r
+?????Compiler default\r
+0\r
+0\r
 52\r
 MRState\r
 53\r
@@ -211,114 +211,114 @@ WString
 WCC\r
 54\r
 WString\r
-9\r
-??6??8086\r
-1\r
+25\r
+?????Floating-point calls\r
 0\r
+1\r
 55\r
-MRState\r
+MCState\r
 56\r
 WString\r
 3\r
 WCC\r
 57\r
 WString\r
-10\r
-??6??80186\r
-1\r
+31\r
+???e?SS not assumed equal to DS\r
+0\r
 1\r
 58\r
-MVState\r
+MRState\r
 59\r
 WString\r
 3\r
 WCC\r
 60\r
 WString\r
-25\r
-d????Include directories:\r
+9\r
+??6??8086\r
 0\r
-61\r
-WString\r
-99\r
-$(%watcom)\h;..\common\include;..\..\source\include;..\..\source\portable\owatcom\16bitdos\common;.\r
 0\r
+61\r
+MRState\r
 62\r
-MCState\r
-63\r
 WString\r
 3\r
 WCC\r
-64\r
+63\r
 WString\r
-26\r
-?????Force ANSI compliance\r
+10\r
+??6??80186\r
 0\r
 1\r
+64\r
+MVState\r
 65\r
-MCState\r
-66\r
 WString\r
 3\r
 WCC\r
+66\r
+WString\r
+25\r
+d????Include directories:\r
+1\r
 67\r
 WString\r
-33\r
-?????Disable stack depth checking\r
+97\r
+$(%watcom)\h;..\common\include;..\..\source\include;..\..\source\portable\owatcom\16bitdos\common\r
 0\r
-1\r
 68\r
-MVState\r
+MCState\r
 69\r
 WString\r
 3\r
 WCC\r
 70\r
 WString\r
-23\r
-?????Macro definitions:\r
-0\r
+26\r
+?????Force ANSI compliance\r
+1\r
+1\r
 71\r
-WString\r
-40\r
-OPEN_WATCOM_INDUSTRIAL_PC_PORT USE_STDIO\r
-0\r
+MVState\r
 72\r
-MCState\r
-73\r
 WString\r
 3\r
 WCC\r
+73\r
+WString\r
+23\r
+?????Macro definitions:\r
+1\r
 74\r
 WString\r
-34\r
-?????Change char default to signed\r
+52\r
+OPEN_WATCOM_INDUSTRIAL_PC_PORT USE_STDIO DEBUG_BUILD\r
 0\r
-1\r
 75\r
-MRState\r
+MCState\r
 76\r
 WString\r
 3\r
 WCC\r
 77\r
 WString\r
-29\r
-?????No debugging information\r
-0\r
+34\r
+?????Change char default to signed\r
+1\r
 1\r
 78\r
-MRState\r
+MCState\r
 79\r
 WString\r
 3\r
 WCC\r
 80\r
 WString\r
-28\r
-?????Line number information\r
-0\r
-0\r
+33\r
+?????Disable stack depth checking\r
+1\r
+1\r
 81\r
 MRState\r
 82\r
@@ -329,7 +329,7 @@ WCC
 WString\r
 21\r
 ?????Compiler default\r
-0\r
+1\r
 0\r
 84\r
 MRState\r
@@ -341,7 +341,7 @@ WCC
 WString\r
 21\r
 ?????Compiler default\r
-0\r
+1\r
 0\r
 87\r
 MRState\r
@@ -353,7 +353,7 @@ WCC
 WString\r
 25\r
 ?????Floating-point calls\r
-0\r
+1\r
 1\r
 90\r
 MCState\r
@@ -365,7 +365,7 @@ WCC
 WString\r
 31\r
 ???e?SS not assumed equal to DS\r
-0\r
+1\r
 1\r
 93\r
 MRState\r
@@ -377,7 +377,7 @@ WCC
 WString\r
 9\r
 ??6??8086\r
-0\r
+1\r
 0\r
 96\r
 MRState\r
@@ -389,7 +389,7 @@ WCC
 WString\r
 10\r
 ??6??80186\r
-0\r
+1\r
 1\r
 99\r
 WVList\r
@@ -760,8 +760,8 @@ WVList
 0\r
 180\r
 MItem\r
-15\r
-fileio\fileio.c\r
+28\r
+..\COMMON\MINIMAL\GenQTest.c\r
 181\r
 WString\r
 4\r
@@ -778,8 +778,8 @@ WVList
 0\r
 184\r
 MItem\r
-6\r
-main.c\r
+15\r
+fileio\fileio.c\r
 185\r
 WString\r
 4\r
@@ -796,8 +796,8 @@ WVList
 0\r
 188\r
 MItem\r
-17\r
-partest\partest.c\r
+6\r
+main.c\r
 189\r
 WString\r
 4\r
@@ -814,8 +814,8 @@ WVList
 0\r
 192\r
 MItem\r
-15\r
-serial\serial.c\r
+17\r
+partest\partest.c\r
 193\r
 WString\r
 4\r
@@ -832,26 +832,26 @@ WVList
 0\r
 196\r
 MItem\r
-3\r
-*.h\r
+15\r
+serial\serial.c\r
 197\r
 WString\r
-3\r
-NIL\r
+4\r
+COBJ\r
 198\r
 WVList\r
 0\r
 199\r
 WVList\r
 0\r
--1\r
+20\r
+1\r
 1\r
-0\r
 0\r
 200\r
 MItem\r
-31\r
-..\..\SOURCE\INCLUDE\croutine.h\r
+3\r
+*.h\r
 201\r
 WString\r
 3\r
@@ -862,14 +862,14 @@ WVList
 203\r
 WVList\r
 0\r
-196\r
-1\r
+-1\r
 1\r
 0\r
+0\r
 204\r
 MItem\r
-27\r
-..\..\source\include\list.h\r
+31\r
+..\..\SOURCE\INCLUDE\croutine.h\r
 205\r
 WString\r
 3\r
@@ -880,14 +880,14 @@ WVList
 207\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 208\r
 MItem\r
-31\r
-..\..\source\include\portable.h\r
+27\r
+..\..\source\include\list.h\r
 209\r
 WString\r
 3\r
@@ -898,14 +898,14 @@ WVList
 211\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 212\r
 MItem\r
 31\r
-..\..\source\include\projdefs.h\r
+..\..\source\include\portable.h\r
 213\r
 WString\r
 3\r
@@ -916,14 +916,14 @@ WVList
 215\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 216\r
 MItem\r
-28\r
-..\..\source\include\queue.h\r
+31\r
+..\..\source\include\projdefs.h\r
 217\r
 WString\r
 3\r
@@ -934,14 +934,14 @@ WVList
 219\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 220\r
 MItem\r
-29\r
-..\..\source\include\semphr.h\r
+28\r
+..\..\source\include\queue.h\r
 221\r
 WString\r
 3\r
@@ -952,14 +952,14 @@ WVList
 223\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 224\r
 MItem\r
-27\r
-..\..\source\include\task.h\r
+29\r
+..\..\source\include\semphr.h\r
 225\r
 WString\r
 3\r
@@ -970,14 +970,14 @@ WVList
 227\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 228\r
 MItem\r
-55\r
-..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
+27\r
+..\..\source\include\task.h\r
 229\r
 WString\r
 3\r
@@ -988,14 +988,14 @@ WVList
 231\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 232\r
 MItem\r
-53\r
-..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
+55\r
+..\..\source\portable\owatcom\16bitdos\common\portasm.h\r
 233\r
 WString\r
 3\r
@@ -1006,14 +1006,14 @@ WVList
 235\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 236\r
 MItem\r
-26\r
-..\common\include\blockq.h\r
+53\r
+..\..\source\portable\owatcom\16bitdos\pc\portmacro.h\r
 237\r
 WString\r
 3\r
@@ -1024,14 +1024,14 @@ WVList
 239\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 240\r
 MItem\r
-28\r
-..\COMMON\INCLUDE\blocktim.h\r
+26\r
+..\common\include\blockq.h\r
 241\r
 WString\r
 3\r
@@ -1042,14 +1042,14 @@ WVList
 243\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 244\r
 MItem\r
-27\r
-..\common\include\comtest.h\r
+28\r
+..\COMMON\INCLUDE\blocktim.h\r
 245\r
 WString\r
 3\r
@@ -1060,14 +1060,14 @@ WVList
 247\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 248\r
 MItem\r
-26\r
-..\COMMON\INCLUDE\crhook.h\r
+27\r
+..\common\include\comtest.h\r
 249\r
 WString\r
 3\r
@@ -1078,14 +1078,14 @@ WVList
 251\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 252\r
 MItem\r
-25\r
-..\common\include\death.h\r
+26\r
+..\COMMON\INCLUDE\crhook.h\r
 253\r
 WString\r
 3\r
@@ -1096,14 +1096,14 @@ WVList
 255\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 256\r
 MItem\r
-27\r
-..\COMMON\INCLUDE\dynamic.h\r
+25\r
+..\common\include\death.h\r
 257\r
 WString\r
 3\r
@@ -1114,14 +1114,14 @@ WVList
 259\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 260\r
 MItem\r
-26\r
-..\common\include\fileio.h\r
+27\r
+..\COMMON\INCLUDE\dynamic.h\r
 261\r
 WString\r
 3\r
@@ -1132,14 +1132,14 @@ WVList
 263\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 264\r
 MItem\r
-25\r
-..\common\include\flash.h\r
+26\r
+..\common\include\fileio.h\r
 265\r
 WString\r
 3\r
@@ -1150,14 +1150,14 @@ WVList
 267\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 268\r
 MItem\r
-24\r
-..\common\include\flop.h\r
+25\r
+..\common\include\flash.h\r
 269\r
 WString\r
 3\r
@@ -1168,14 +1168,14 @@ WVList
 271\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 272\r
 MItem\r
-27\r
-..\common\include\partest.h\r
+24\r
+..\common\include\flop.h\r
 273\r
 WString\r
 3\r
@@ -1186,14 +1186,14 @@ WVList
 275\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 276\r
 MItem\r
-25\r
-..\common\include\pollq.h\r
+28\r
+..\COMMON\INCLUDE\GenQTest.h\r
 277\r
 WString\r
 3\r
@@ -1204,14 +1204,14 @@ WVList
 279\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 280\r
 MItem\r
-25\r
-..\common\include\print.h\r
+27\r
+..\common\include\partest.h\r
 281\r
 WString\r
 3\r
@@ -1222,14 +1222,14 @@ WVList
 283\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 284\r
 MItem\r
-27\r
-..\common\include\semtest.h\r
+25\r
+..\common\include\pollq.h\r
 285\r
 WString\r
 3\r
@@ -1240,14 +1240,14 @@ WVList
 287\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 288\r
 MItem\r
-26\r
-..\common\include\serial.h\r
+25\r
+..\common\include\print.h\r
 289\r
 WString\r
 3\r
@@ -1258,14 +1258,14 @@ WVList
 291\r
 WVList\r
 0\r
-196\r
+200\r
 1\r
 1\r
 0\r
 292\r
 MItem\r
-16\r
-FreeRTOSConfig.h\r
+27\r
+..\common\include\semtest.h\r
 293\r
 WString\r
 3\r
@@ -1276,7 +1276,43 @@ WVList
 295\r
 WVList\r
 0\r
-196\r
+200\r
+1\r
+1\r
+0\r
+296\r
+MItem\r
+26\r
+..\common\include\serial.h\r
+297\r
+WString\r
+3\r
+NIL\r
+298\r
+WVList\r
+0\r
+299\r
+WVList\r
+0\r
+200\r
+1\r
+1\r
+0\r
+300\r
+MItem\r
+16\r
+FreeRTOSConfig.h\r
+301\r
+WString\r
+3\r
+NIL\r
+302\r
+WVList\r
+0\r
+303\r
+WVList\r
+0\r
+200\r
 1\r
 1\r
 0\r
index 1b02cfb2fc52011dda8458414ddbce65738d477a..25dbb7d795048b7f73e032f0d5e2032774aa3dd4 100644 (file)
@@ -31,7 +31,7 @@ WRect
 0\r
 0\r
 7168\r
-7168\r
+8523\r
 0\r
 0\r
 9\r
@@ -39,5 +39,5 @@ WFileName
 12\r
 rtosdemo.tgt\r
 0\r
-25\r
+26\r
 7\r
index 566530b42ac890c68535ccf2f4d3bc8ddd1228d6..b8625d7249a39cdffc336ff1f5ee946e555aea15 100644 (file)
@@ -500,6 +500,7 @@ static portSHORT sComPortISR( const xComPort * const pxPort )
 portSHORT sInterruptID;\r
 portCHAR cIn, cOut;\r
 portBASE_TYPE xTaskWokenByPost = pdFALSE, xAnotherTaskWokenByPost = pdFALSE, xTaskWokenByTx = pdFALSE;\r
+extern void vComTestUnsuspendTask( void );\r
 \r
        portOUTPUT_BYTE( pxPort->us8259InterruptMaskReg, ( portINPUT_BYTE( pxPort->us8259InterruptMaskReg) | ~pxPort->ucInterruptEnableMast ) );\r
 \r
index 11ca53f624ae23a757f149bca603786e2c9d1501..3c02e6c6f5195f467c58c429d4a467502559c5e5 100644 (file)
 \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
+       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
+       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 for an IEC 61508 compliant version along\r
@@ -37,8 +37,8 @@
 #define INC_FREERTOS_H\r
 \r
 \r
-/* \r
- * Include the generic headers required for the FreeRTOS port being used. \r
+/*\r
+ * Include the generic headers required for the FreeRTOS port being used.\r
  */\r
 #include <stddef.h>\r
 \r
@@ -58,7 +58,7 @@
 \r
 \r
 /*\r
- * Check all the required application specific macros have been defined. \r
+ * Check all the required application specific macros have been defined.\r
  * These macros are application specific and (as downloaded) are defined\r
  * within FreeRTOSConfig.h.\r
  */\r
        #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
+#if ( configUSE_MUTEXES == 1 )\r
+       /* xTaskGetCurrentTaskHandle is used by the priority inheritance mechanism\r
+       within the mutex implementation so must be available if mutexes are used. */\r
+       #undef INCLUDE_xTaskGetCurrentTaskHandle\r
+       #define INCLUDE_xTaskGetCurrentTaskHandle 1\r
+#else\r
+       #ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
+               #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
+       #endif\r
 #endif\r
+\r
+#endif /* INC_FREERTOS_H */\r
index 6ded9787125e40e57d1075b1f784e16b9a93140a..c9d4489896cdfdbfa9cd20c32bfc49a5ad9a74e9 100644 (file)
 \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
+       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
+       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 for an IEC 61508 compliant version along\r
 \r
 typedef void * xQueueHandle;\r
 \r
+/* For internal use only. */\r
+#define        queueSEND_TO_BACK       ( 0 )\r
+#define        queueSEND_TO_FRONT      ( 1 )\r
+\r
+\r
 /**\r
  * queue. h\r
  * <pre>\r
- xQueueHandle xQueueCreate( \r
-                              unsigned portBASE_TYPE uxQueueLength, \r
-                              unsigned portBASE_TYPE uxItemSize \r
+ xQueueHandle xQueueCreate(\r
+                              unsigned portBASE_TYPE uxQueueLength,\r
+                              unsigned portBASE_TYPE uxItemSize\r
                           );\r
  * </pre>\r
  *\r
@@ -52,15 +57,15 @@ typedef void * xQueueHandle;
  *\r
  * @param uxQueueLength The maximum number of items that the queue can contain.\r
  *\r
- * @param uxItemSize The number of bytes each item in the queue will require.  \r
+ * @param uxItemSize The number of bytes each item in the queue will require.\r
  * Items are queued by copy, not by reference, so this is the number of bytes\r
  * that will be copied for each posted item.  Each item on the queue must be\r
  * the same size.\r
  *\r
- * @return If the queue is successfully create then a handle to the newly \r
+ * @return If the queue is successfully create then a handle to the newly\r
  * created queue is returned.  If the queue cannot be created then 0 is\r
  * returned.\r
- * \r
+ *\r
  * Example usage:\r
    <pre>\r
  struct AMessage\r
@@ -99,20 +104,273 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
 /**\r
  * queue. h\r
  * <pre>\r
- portBASE_TYPE xQueueSend( \r
-                             xQueueHandle xQueue, \r
-                             const void * pvItemToQueue, \r
-                             portTickType xTicksToWait \r
+ portBASE_TYPE xQueueSendToToFront(\r
+                                   xQueueHandle xQueue,\r
+                                   const void * pvItemToQueue,\r
+                                   portTickType xTicksToWait\r
+                               );\r
+ * </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSend().\r
+ *\r
+ * Post an item to the front of a queue.  The item is queued by copy, not by\r
+ * reference.  This function must not be called from an interrupt service\r
+ * routine.  See xQueueSendFromISR () for an alternative which may be used\r
+ * in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full.  The call will return immediately if this is set to 0.  The\r
+ * time is defined in tick periods so the constant portTICK_RATE_MS\r
+ * should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+ struct AMessage\r
+ {\r
+    portCHAR ucMessageID;\r
+    portCHAR ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned portLONG ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+    // Create a queue capable of containing 10 unsigned long values.\r
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
+\r
+    // Create a queue capable of containing 10 pointers to AMessage structures.\r
+    // These should be passed by pointer as they contain a lot of data.\r
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+    // ...\r
+\r
+    if( xQueue1 != 0 )\r
+    {\r
+        // Send an unsigned long.  Wait for 10 ticks for space to become\r
+        // available if necessary.\r
+        if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+        {\r
+            // Failed to post the message, even after 10 ticks.\r
+        }\r
+    }\r
+\r
+    if( xQueue2 != 0 )\r
+    {\r
+        // Send a pointer to a struct AMessage object.  Don't block if the\r
+        // queue is already full.\r
+        pxMessage = & xMessage;\r
+        xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+    }\r
+\r
+       // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_FRONT )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToBack(\r
+                                   xQueueHandle xQueue,\r
+                                   const void * pvItemToQueue,\r
+                                   portTickType xTicksToWait\r
+                               );\r
+ * </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSend().\r
+ *\r
+ * Post an item to the back of a queue.  The item is queued by copy, not by\r
+ * reference.  This function must not be called from an interrupt service\r
+ * routine.  See xQueueSendFromISR () for an alternative which may be used\r
+ * in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full.  The call will return immediately if this is set to 0.  The\r
+ * time is defined in tick periods so the constant portTICK_RATE_MS\r
+ * should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+ struct AMessage\r
+ {\r
+    portCHAR ucMessageID;\r
+    portCHAR ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned portLONG ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+    // Create a queue capable of containing 10 unsigned long values.\r
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
+\r
+    // Create a queue capable of containing 10 pointers to AMessage structures.\r
+    // These should be passed by pointer as they contain a lot of data.\r
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+    // ...\r
+\r
+    if( xQueue1 != 0 )\r
+    {\r
+        // Send an unsigned long.  Wait for 10 ticks for space to become\r
+        // available if necessary.\r
+        if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+        {\r
+            // Failed to post the message, even after 10 ticks.\r
+        }\r
+    }\r
+\r
+    if( xQueue2 != 0 )\r
+    {\r
+        // Send a pointer to a struct AMessage object.  Don't block if the\r
+        // queue is already full.\r
+        pxMessage = & xMessage;\r
+        xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+    }\r
+\r
+       // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSend(\r
+                              xQueueHandle xQueue,\r
+                              const void * pvItemToQueue,\r
+                              portTickType xTicksToWait\r
                          );\r
  * </pre>\r
  *\r
+ * This is a macro that calls xQueueGenericSend().  It is included for\r
+ * backward compatibility with versions of FreeRTOS.org that did not\r
+ * include the xQueueSendToFront() and xQueueSendToBack() macros.  It is\r
+ * equivalent to xQueueSendToBack().\r
+ *\r
+ * Post an item on a queue.  The item is queued by copy, not by reference.\r
+ * This function must not be called from an interrupt service routine.\r
+ * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for space to become available on the queue, should it already\r
+ * be full.  The call will return immediately if this is set to 0.  The\r
+ * time is defined in tick periods so the constant portTICK_RATE_MS\r
+ * should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+ struct AMessage\r
+ {\r
+    portCHAR ucMessageID;\r
+    portCHAR ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ unsigned portLONG ulVar = 10UL;\r
+\r
+ void vATask( void *pvParameters )\r
+ {\r
+ xQueueHandle xQueue1, xQueue2;\r
+ struct AMessage *pxMessage;\r
+\r
+    // Create a queue capable of containing 10 unsigned long values.\r
+    xQueue1 = xQueueCreate( 10, sizeof( unsigned portLONG ) );\r
+\r
+    // Create a queue capable of containing 10 pointers to AMessage structures.\r
+    // These should be passed by pointer as they contain a lot of data.\r
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+    // ...\r
+\r
+    if( xQueue1 != 0 )\r
+    {\r
+        // Send an unsigned long.  Wait for 10 ticks for space to become\r
+        // available if necessary.\r
+        if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+        {\r
+            // Failed to post the message, even after 10 ticks.\r
+        }\r
+    }\r
+\r
+    if( xQueue2 != 0 )\r
+    {\r
+        // Send a pointer to a struct AMessage object.  Don't block if the\r
+        // queue is already full.\r
+        pxMessage = & xMessage;\r
+        xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+    }\r
+\r
+       // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, queueSEND_TO_BACK )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueGenericSend(\r
+                                                                       xQueueHandle xQueue,\r
+                                                                       const void * pvItemToQueue,\r
+                                                                       portTickType xTicksToWait\r
+                                                                       portBASE_TYPE xCopyPosition\r
+                                                               );\r
+ * </pre>\r
+ *\r
+ * It is preferred that the macros xQueueSend(), xQueueSendToFront() and\r
+ * xQueueSendToBack() are used in place of calling this function directly.\r
+ *\r
  * Post an item on a queue.  The item is queued by copy, not by reference.\r
  * This function must not be called from an interrupt service routine.\r
  * See xQueueSendFromISR () for an alternative which may be used in an ISR.\r
  *\r
  * @param xQueue The handle to the queue on which the item is to be posted.\r
- * \r
- * @param pvItemToQueue A pointer to the item that is to be placed on the \r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
  * queue.  The size of the items the queue will hold was defined when the\r
  * queue was created, so this many bytes will be copied from pvItemToQueue\r
  * into the queue storage area.\r
@@ -120,9 +378,13 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
  * @param xTicksToWait The maximum amount of time the task should block\r
  * waiting for space to become available on the queue, should it already\r
  * be full.  The call will return immediately if this is set to 0.  The\r
- * time is defined in tick periods so the constant portTICK_RATE_MS \r
+ * time is defined in tick periods so the constant portTICK_RATE_MS\r
  * should be used to convert to real time if this is required.\r
  *\r
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
+ * at the front of the queue (for high priority messages).\r
+ *\r
  * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL.\r
  *\r
  * Example usage:\r
@@ -145,46 +407,234 @@ xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBA
 \r
     // Create a queue capable of containing 10 pointers to AMessage structures.\r
     // These should be passed by pointer as they contain a lot of data.\r
-    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+\r
+    // ...\r
+\r
+    if( xQueue1 != 0 )\r
+    {\r
+        // Send an unsigned long.  Wait for 10 ticks for space to become\r
+        // available if necessary.\r
+        if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )\r
+        {\r
+            // Failed to post the message, even after 10 ticks.\r
+        }\r
+    }\r
+\r
+    if( xQueue2 != 0 )\r
+    {\r
+        // Send a pointer to a struct AMessage object.  Don't block if the\r
+        // queue is already full.\r
+        pxMessage = & xMessage;\r
+        xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );\r
+    }\r
+\r
+       // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueSend xQueueSend\r
+ * \ingroup QueueManagement\r
+ */\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portTickType xCopyPosition );\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueuePeek(\r
+                             xQueueHandle xQueue,\r
+                             void *pvBuffer,\r
+                             portTickType xTicksToWait\r
+                         );</pre>\r
+ *\r
+ * This is a macro that calls the xQueueGenericReceive() function.\r
+ *\r
+ * Receive an item from a queue without removing the item from the queue.\r
+ * The item is received by copy so a buffer of adequate size must be\r
+ * provided.  The number of bytes copied into the buffer was defined when\r
+ * the queue was created.\r
+ *\r
+ * Successfully received items remain on the queue so will be returned again\r
+ * by the next call, or a call to xQueueReceive().\r
+ *\r
+ * This macro must not be used in an interrupt service routine.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for an item to receive should the queue be empty at the time\r
+ * of the call.    The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+ struct AMessage\r
+ {\r
+    portCHAR ucMessageID;\r
+    portCHAR ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Task to create a queue and post a value.\r
+ void vATask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxMessage;\r
+\r
+    // Create a queue capable of containing 10 pointers to AMessage structures.\r
+    // These should be passed by pointer as they contain a lot of data.\r
+    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+    if( xQueue == 0 )\r
+    {\r
+        // Failed to create the queue.\r
+    }\r
+\r
+    // ...\r
+\r
+    // Send a pointer to a struct AMessage object.  Don't block if the\r
+    // queue is already full.\r
+    pxMessage = & xMessage;\r
+    xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+\r
+       // ... Rest of task code.\r
+ }\r
+\r
+ // Task to peek the data from the queue.\r
+ void vADifferentTask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxRxedMessage;\r
+\r
+    if( xQueue != 0 )\r
+    {\r
+        // Peek a message on the created queue.  Block for 10 ticks if a\r
+        // message is not immediately available.\r
+        if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+        {\r
+            // pcRxedMessage now points to the struct AMessage variable posted\r
+            // by vATask, but the item still remains on the queue.\r
+        }\r
+    }\r
+\r
+       // ... Rest of task code.\r
+ }\r
+ </pre>\r
+ * \defgroup xQueueReceive xQueueReceive\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdTRUE )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueReceive(\r
+                                 xQueueHandle xQueue,\r
+                                 void *pvBuffer,\r
+                                 portTickType xTicksToWait\r
+                            );</pre>\r
+ *\r
+ * This is a macro that calls the xQueueGenericReceive() function.\r
+ *\r
+ * Receive an item from a queue.  The item is received by copy so a buffer of\r
+ * adequate size must be provided.  The number of bytes copied into the buffer\r
+ * was defined when the queue was created.\r
+ *\r
+ * Successfully received items are removed from the queue.\r
+ *\r
+ * This function must not be used in an interrupt service routine.  See\r
+ * xQueueReceiveFromISR for an alternative that can.\r
+ *\r
+ * @param pxQueue The handle to the queue from which the item is to be\r
+ * received.\r
+ *\r
+ * @param pvBuffer Pointer to the buffer into which the received item will\r
+ * be copied.\r
+ *\r
+ * @param xTicksToWait The maximum amount of time the task should block\r
+ * waiting for an item to receive should the queue be empty at the time\r
+ * of the call.    The time is defined in tick periods so the constant\r
+ * portTICK_RATE_MS should be used to convert to real time if this is required.\r
+ *\r
+ * @return pdTRUE if an item was successfully received from the queue,\r
+ * otherwise pdFALSE.\r
+ *\r
+ * Example usage:\r
+   <pre>\r
+ struct AMessage\r
+ {\r
+    portCHAR ucMessageID;\r
+    portCHAR ucData[ 20 ];\r
+ } xMessage;\r
+\r
+ xQueueHandle xQueue;\r
+\r
+ // Task to create a queue and post a value.\r
+ void vATask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxMessage;\r
+\r
+    // Create a queue capable of containing 10 pointers to AMessage structures.\r
+    // These should be passed by pointer as they contain a lot of data.\r
+    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );\r
+    if( xQueue == 0 )\r
+    {\r
+        // Failed to create the queue.\r
+    }\r
 \r
     // ...\r
 \r
-    if( xQueue1 != 0 )\r
+    // Send a pointer to a struct AMessage object.  Don't block if the\r
+    // queue is already full.\r
+    pxMessage = & xMessage;\r
+    xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );\r
+\r
+       // ... Rest of task code.\r
+ }\r
+\r
+ // Task to receive from the queue.\r
+ void vADifferentTask( void *pvParameters )\r
+ {\r
+ struct AMessage *pxRxedMessage;\r
+\r
+    if( xQueue != 0 )\r
     {\r
-        // Send an unsigned long.  Wait for 10 ticks for space to become \r
-        // available if necessary.\r
-        if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )\r
+        // Receive a message on the created queue.  Block for 10 ticks if a\r
+        // message is not immediately available.\r
+        if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
         {\r
-            // Failed to post the message, even after 10 ticks.\r
+            // pcRxedMessage now points to the struct AMessage variable posted\r
+            // by vATask.\r
         }\r
     }\r
 \r
-    if( xQueue2 != 0 )\r
-    {\r
-        // Send a pointer to a struct AMessage object.  Don't block if the\r
-        // queue is already full.\r
-        pxMessage = & xMessage;\r
-        xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );\r
-    }\r
-\r
        // ... Rest of task code.\r
  }\r
  </pre>\r
- * \defgroup xQueueSend xQueueSend\r
+ * \defgroup xQueueReceive xQueueReceive\r
  * \ingroup QueueManagement\r
  */\r
-signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait );\r
+#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( xQueue, pvBuffer, xTicksToWait, pdFALSE )\r
+\r
 \r
 /**\r
  * queue. h\r
  * <pre>\r
- portBASE_TYPE xQueueReceive( \r
-                                xQueueHandle xQueue, \r
-                                void *pvBuffer, \r
-                                portTickType xTicksToWait \r
-                            );</pre>\r
+ portBASE_TYPE xQueueGenericReceive(\r
+                                       xQueueHandle xQueue,\r
+                                       void *pvBuffer,\r
+                                       portTickType xTicksToWait\r
+                                       portBASE_TYPE xJustPeek\r
+                                    );</pre>\r
+ *\r
+ * It is preferred that the macro xQueueReceive() be used rather than calling\r
+ * this function directly.\r
  *\r
- * Receive an item from a queue.  The item is received by copy so a buffer of \r
+ * Receive an item from a queue.  The item is received by copy so a buffer of\r
  * adequate size must be provided.  The number of bytes copied into the buffer\r
  * was defined when the queue was created.\r
  *\r
@@ -196,12 +646,17 @@ signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue
  *\r
  * @param pvBuffer Pointer to the buffer into which the received item will\r
  * be copied.\r
- * \r
+ *\r
  * @param xTicksToWait The maximum amount of time the task should block\r
  * waiting for an item to receive should the queue be empty at the time\r
- * of the call.    The time is defined in tick periods so the constant \r
+ * of the call.    The time is defined in tick periods so the constant\r
  * portTICK_RATE_MS should be used to convert to real time if this is required.\r
  *\r
+ * @param xJustPeek When set to true, the item received from the queue is not\r
+ * actually removed from the queue - meaning a subsequent call to\r
+ * xQueueReceive() will return the same item.  When set to false, the item\r
+ * being received from the queue is also removed from the queue.\r
+ *\r
  * @return pdTRUE if an item was successfully received from the queue,\r
  * otherwise pdFALSE.\r
  *\r
@@ -214,7 +669,7 @@ signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue
  } xMessage;\r
 \r
  xQueueHandle xQueue;\r
\r
+\r
  // Task to create a queue and post a value.\r
  void vATask( void *pvParameters )\r
  {\r
@@ -247,7 +702,7 @@ signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue
     {\r
         // Receive a message on the created queue.  Block for 10 ticks if a\r
         // message is not immediately available.\r
-        if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
+        if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )\r
         {\r
             // pcRxedMessage now points to the struct AMessage variable posted\r
             // by vATask.\r
@@ -260,7 +715,7 @@ signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue
  * \defgroup xQueueReceive xQueueReceive\r
  * \ingroup QueueManagement\r
  */\r
-signed portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait );\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek );\r
 \r
 /**\r
  * queue. h\r
@@ -269,7 +724,7 @@ signed portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTic
  * Return the number of messages stored in a queue.\r
  *\r
  * @param xQueue A handle to the queue being queried.\r
- * \r
+ *\r
  * @return The number of messages available in the queue.\r
  *\r
  * \page uxQueueMessagesWaiting uxQueueMessagesWaiting\r
@@ -283,7 +738,7 @@ unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue );
  *\r
  * Delete a queue - freeing all the memory allocated for storing of items\r
  * placed on the queue.\r
- * \r
+ *\r
  * @param xQueue A handle to the queue to be deleted.\r
  *\r
  * \page vQueueDelete vQueueDelete\r
@@ -294,13 +749,254 @@ void vQueueDelete( xQueueHandle xQueue );
 /**\r
  * queue. h\r
  * <pre>\r
- portBASE_TYPE xQueueSendFromISR( \r
-                                    xQueueHandle pxQueue, \r
-                                    const void *pvItemToQueue, \r
-                                    portBASE_TYPE xTaskPreviouslyWoken \r
+ portBASE_TYPE xQueueSendToFrontFromISR(\r
+                                         xQueueHandle pxQueue,\r
+                                         const void *pvItemToQueue,\r
+                                         portBASE_TYPE xTaskPreviouslyWoken\r
+                                      );\r
+ </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSendFromISR().\r
+ *\r
+ * Post an item to the front of a queue.  It is safe to use this macro from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR.  In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param cTaskPreviouslyWoken This is included so an ISR can post onto\r
+ * the same queue multiple times from a single interrupt.  The first call\r
+ * should always pass in pdFALSE.  Subsequent calls should pass in\r
+ * the value returned from the previous call.  See the file serial .c in the\r
+ * PC port for a good example of this mechanism.\r
+ *\r
+ * @return pdTRUE if a task was woken by posting onto the queue.  This is\r
+ * used by the ISR to determine if a context switch may be required following\r
+ * the ISR.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+   <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ portCHAR cIn;\r
+ portBASE_TYPE xTaskWokenByPost;\r
+\r
+    // We have not woken a task at the start of the ISR.\r
+    cTaskWokenByPost = pdFALSE;\r
+\r
+    // Loop until the buffer is empty.\r
+    do\r
+    {\r
+        // Obtain a byte from the buffer.\r
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );                                           \r
+\r
+        // Post the byte.  The first time round the loop cTaskWokenByPost\r
+        // will be pdFALSE.  If the queue send causes a task to wake we do\r
+        // not want the task to run until we have finished the ISR, so\r
+        // xQueueSendFromISR does not cause a context switch.  Also we\r
+        // don't want subsequent posts to wake any other tasks, so we store\r
+        // the return value back into cTaskWokenByPost so xQueueSendFromISR\r
+        // knows not to wake any task the next iteration of the loop.\r
+        xTaskWokenByPost = xQueueSendToFrontFromISR( xRxQueue, &cIn, cTaskWokenByPost );\r
+\r
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+    // Now the buffer is empty we can switch context if necessary.\r
+    if( cTaskWokenByPost )\r
+    {\r
+        taskYIELD ();\r
+    }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToFromFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_FRONT )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendToBackFromISR(\r
+                                         xQueueHandle pxQueue,\r
+                                         const void *pvItemToQueue,\r
+                                         portBASE_TYPE xTaskPreviouslyWoken\r
+                                      );\r
+ </pre>\r
+ *\r
+ * This is a macro that calls xQueueGenericSendFromISR().\r
+ *\r
+ * Post an item to the back of a queue.  It is safe to use this macro from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR.  In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param cTaskPreviouslyWoken This is included so an ISR can post onto\r
+ * the same queue multiple times from a single interrupt.  The first call\r
+ * should always pass in pdFALSE.  Subsequent calls should pass in\r
+ * the value returned from the previous call.  See the file serial .c in the\r
+ * PC port for a good example of this mechanism.\r
+ *\r
+ * @return pdTRUE if a task was woken by posting onto the queue.  This is\r
+ * used by the ISR to determine if a context switch may be required following\r
+ * the ISR.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+   <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ portCHAR cIn;\r
+ portBASE_TYPE xTaskWokenByPost;\r
+\r
+    // We have not woken a task at the start of the ISR.\r
+    cTaskWokenByPost = pdFALSE;\r
+\r
+    // Loop until the buffer is empty.\r
+    do\r
+    {\r
+        // Obtain a byte from the buffer.\r
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );                                           \r
+\r
+        // Post the byte.  The first time round the loop cTaskWokenByPost\r
+        // will be pdFALSE.  If the queue send causes a task to wake we do\r
+        // not want the task to run until we have finished the ISR, so\r
+        // xQueueSendFromISR does not cause a context switch.  Also we\r
+        // don't want subsequent posts to wake any other tasks, so we store\r
+        // the return value back into cTaskWokenByPost so xQueueSendFromISR\r
+        // knows not to wake any task the next iteration of the loop.\r
+        xTaskWokenByPost = xQueueSendToBackFromISR( xRxQueue, &cIn, cTaskWokenByPost );\r
+\r
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+    // Now the buffer is empty we can switch context if necessary.\r
+    if( cTaskWokenByPost )\r
+    {\r
+        taskYIELD ();\r
+    }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendToBackFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_BACK )\r
+\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueSendFromISR(\r
+                                     xQueueHandle pxQueue,\r
+                                     const void *pvItemToQueue,\r
+                                     portBASE_TYPE xTaskPreviouslyWoken\r
                                 );\r
  </pre>\r
  *\r
+ * This is a macro that calls xQueueGenericSendFromISR().  It is included\r
+ * for backward compatibility with versions of FreeRTOS.org that did not\r
+ * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR()\r
+ * macros.\r
+ *\r
+ * Post an item to the back of a queue.  It is safe to use this function from\r
+ * within an interrupt service routine.\r
+ *\r
+ * Items are queued by copy not reference so it is preferable to only\r
+ * queue small items, especially when called from an ISR.  In most cases\r
+ * it would be preferable to store a pointer to the item being queued.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue.  The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param cTaskPreviouslyWoken This is included so an ISR can post onto\r
+ * the same queue multiple times from a single interrupt.  The first call\r
+ * should always pass in pdFALSE.  Subsequent calls should pass in\r
+ * the value returned from the previous call.  See the file serial .c in the\r
+ * PC port for a good example of this mechanism.\r
+ *\r
+ * @return pdTRUE if a task was woken by posting onto the queue.  This is\r
+ * used by the ISR to determine if a context switch may be required following\r
+ * the ISR.\r
+ *\r
+ * Example usage for buffered IO (where the ISR can obtain more than one value\r
+ * per call):\r
+   <pre>\r
+ void vBufferISR( void )\r
+ {\r
+ portCHAR cIn;\r
+ portBASE_TYPE xTaskWokenByPost;\r
+\r
+    // We have not woken a task at the start of the ISR.\r
+    cTaskWokenByPost = pdFALSE;\r
+\r
+    // Loop until the buffer is empty.\r
+    do\r
+    {\r
+        // Obtain a byte from the buffer.\r
+        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );                                           \r
+\r
+        // Post the byte.  The first time round the loop cTaskWokenByPost\r
+        // will be pdFALSE.  If the queue send causes a task to wake we do\r
+        // not want the task to run until we have finished the ISR, so\r
+        // xQueueSendFromISR does not cause a context switch.  Also we\r
+        // don't want subsequent posts to wake any other tasks, so we store\r
+        // the return value back into cTaskWokenByPost so xQueueSendFromISR\r
+        // knows not to wake any task the next iteration of the loop.\r
+        xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost );\r
+\r
+    } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
+\r
+    // Now the buffer is empty we can switch context if necessary.\r
+    if( cTaskWokenByPost )\r
+    {\r
+        taskYIELD ();\r
+    }\r
+ }\r
+ </pre>\r
+ *\r
+ * \defgroup xQueueSendFromISR xQueueSendFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken ) xQueueGenericSendFromISR( pxQueue, pvItemToQueue, xTaskPreviouslyWoken, queueSEND_TO_BACK )\r
+\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueGenericSendFromISR(\r
+                                           xQueueHandle pxQueue,\r
+                                           const void *pvItemToQueue,\r
+                                           portBASE_TYPE xTaskPreviouslyWoken\r
+                                                                                  portBASE_TYPE xCopyPosition\r
+                                       );\r
+ </pre>\r
+ *\r
+ * It is preferred that the macros xQueueSendFromISR(),\r
+ * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place\r
+ * of calling this function directly.\r
+ *\r
  * Post an item on a queue.  It is safe to use this function from within an\r
  * interrupt service routine.\r
  *\r
@@ -309,8 +1005,8 @@ void vQueueDelete( xQueueHandle xQueue );
  * it would be preferable to store a pointer to the item being queued.\r
  *\r
  * @param xQueue The handle to the queue on which the item is to be posted.\r
- * \r
- * @param pvItemToQueue A pointer to the item that is to be placed on the \r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
  * queue.  The size of the items the queue will hold was defined when the\r
  * queue was created, so this many bytes will be copied from pvItemToQueue\r
  * into the queue storage area.\r
@@ -321,7 +1017,11 @@ void vQueueDelete( xQueueHandle xQueue );
  * the value returned from the previous call.  See the file serial .c in the\r
  * PC port for a good example of this mechanism.\r
  *\r
- * @return pdTRUE if a task was woken by posting onto the queue.  This is \r
+ * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the\r
+ * item at the back of the queue, or queueSEND_TO_FRONT to place the item\r
+ * at the front of the queue (for high priority messages).\r
+ *\r
+ * @return pdTRUE if a task was woken by posting onto the queue.  This is\r
  * used by the ISR to determine if a context switch may be required following\r
  * the ISR.\r
  *\r
@@ -345,11 +1045,11 @@ void vQueueDelete( xQueueHandle xQueue );
         // Post the byte.  The first time round the loop cTaskWokenByPost\r
         // will be pdFALSE.  If the queue send causes a task to wake we do\r
         // not want the task to run until we have finished the ISR, so\r
-        // xQueueSendFromISR does not cause a context switch.  Also we \r
+        // xQueueSendFromISR does not cause a context switch.  Also we\r
         // don't want subsequent posts to wake any other tasks, so we store\r
         // the return value back into cTaskWokenByPost so xQueueSendFromISR\r
         // knows not to wake any task the next iteration of the loop.\r
-        xTaskWokenByPost = xQueueSendFromISR( xRxQueue, &cIn, cTaskWokenByPost );\r
+        xTaskWokenByPost = xQueueGenericSendFromISR( xRxQueue, &cIn, cTaskWokenByPost, queueSEND_TO_BACK );\r
 \r
     } while( portINPUT_BYTE( BUFFER_COUNT ) );\r
 \r
@@ -364,16 +1064,16 @@ void vQueueDelete( xQueueHandle xQueue );
  * \defgroup xQueueSendFromISR xQueueSendFromISR\r
  * \ingroup QueueManagement\r
  */\r
-signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken );\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition );\r
 \r
 /**\r
  * queue. h\r
  * <pre>\r
- portBASE_TYPE xQueueReceiveFromISR( \r
-                                       xQueueHandle pxQueue, \r
-                                       void *pvBuffer, \r
-                                       portBASE_TYPE *pxTaskWoken \r
-                                   ); \r
+ portBASE_TYPE xQueueReceiveFromISR(\r
+                                       xQueueHandle pxQueue,\r
+                                       void *pvBuffer,\r
+                                       portBASE_TYPE *pxTaskWoken\r
+                                   );\r
  * </pre>\r
  *\r
  * Receive an item from a queue.  It is safe to use this function from within an\r
@@ -384,7 +1084,7 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
  *\r
  * @param pvBuffer Pointer to the buffer into which the received item will\r
  * be copied.\r
- * \r
+ *\r
  * @param pxTaskWoken A task may be blocked waiting for space to become\r
  * available on the queue.  If xQueueReceiveFromISR causes such a task to\r
  * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will\r
@@ -395,9 +1095,9 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
  *\r
  * Example usage:\r
    <pre>\r
\r
+\r
  xQueueHandle xQueue;\r
\r
+\r
  // Function to create a queue and post some values.\r
  void vAFunction( void *pvParameters )\r
  {\r
@@ -427,7 +1127,7 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
     xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );\r
  }\r
 \r
- // ISR that outputs all the characters received on the queue. \r
+ // ISR that outputs all the characters received on the queue.\r
  void vISR_Routine( void )\r
  {\r
  portBASE_TYPE xTaskWokenByReceive = pdFALSE;\r
@@ -438,7 +1138,7 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
         // A character was received.  Output the character now.\r
         vOutputCharacter( cRxedChar );\r
 \r
-        // If removing the character from the queue woke the task that was \r
+        // If removing the character from the queue woke the task that was\r
         // posting onto the queue cTaskWokenByReceive will have been set to\r
         // pdTRUE.  No matter how many times this loop iterates only one\r
         // task will be woken.\r
@@ -453,13 +1153,13 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
  * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR\r
  * \ingroup QueueManagement\r
  */\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
 \r
 \r
-/* \r
- * The functions defined above are for passing data to and from tasks.  The \r
- * functions below are the equivalents for passing data to and from \r
- * co-rtoutines.\r
+/*\r
+ * The functions defined above are for passing data to and from tasks.  The\r
+ * functions below are the equivalents for passing data to and from\r
+ * co-routines.\r
  *\r
  * These functions are called from the co-routine macro implementation and\r
  * should not be called directly from application code.  Instead use the macro\r
@@ -470,5 +1170,11 @@ signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffe
 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );\r
 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
 \r
-#endif\r
+/*\r
+ * For internal use only.  Use xSemaphoreCreateMutex() instead of calling\r
+ * this function directly.\r
+ */\r
+xQueueHandle xQueueCreateMutex( void );\r
+\r
+#endif /* QUEUE_H */\r
 \r
index 266ad1ae9dc7c6a51b28e3b553c630b30780142a..18bbb444d8511907e8193b15bce3557a4e6884ff 100644 (file)
@@ -54,6 +54,13 @@ typedef xQueueHandle xSemaphoreHandle;
  * as we don't want to actually store any data - we just want to know if the\r
  * queue is empty or full.\r
  *\r
+ * This type of semaphore can be used for pure synchronisation between tasks or\r
+ * between an interrupt and a task.  The semaphore need not be given back once\r
+ * obtained, so one task/interrupt can continuously 'give' the semaphore while\r
+ * another continuously 'takes' the semaphore.  For this reason this type of\r
+ * semaphore does not use a priority inheritance mechanism.  For an alternative\r
+ * that does use priority inheritance see xSemaphoreCreateMutex().\r
+ *\r
  * @param xSemaphore Handle to the created semaphore.  Should be of type xSemaphoreHandle.\r
  *\r
  * Example usage:\r
@@ -205,7 +212,7 @@ typedef xQueueHandle xSemaphoreHandle;
  * \defgroup xSemaphoreGive xSemaphoreGive\r
  * \ingroup Semaphores\r
  */\r
-#define xSemaphoreGive( xSemaphore )                           xQueueSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME )\r
+#define xSemaphoreGive( xSemaphore )                           xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )\r
 \r
 /**\r
  * semphr. h\r
@@ -218,6 +225,9 @@ typedef xQueueHandle xSemaphoreHandle;
  * <i>Macro</i> to  release a semaphore.  The semaphore must of been created using \r
  * vSemaphoreCreateBinary (), and obtained using xSemaphoreTake ().\r
  *\r
+ * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())\r
+ * must not be used with this macro.\r
+ *\r
  * This macro can be used from an ISR.\r
  *\r
  * @param xSemaphore A handle to the semaphore being released.  This is the\r
@@ -285,8 +295,52 @@ typedef xQueueHandle xSemaphoreHandle;
  * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR\r
  * \ingroup Semaphores\r
  */\r
-#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )                      xQueueSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken )\r
+#define xSemaphoreGiveFromISR( xSemaphore, xTaskPreviouslyWoken )                      xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, xTaskPreviouslyWoken, queueSEND_TO_BACK )\r
+\r
+/**\r
+ * semphr. h\r
+ * <pre>xSemaphoreCreateMutex( xSemaphoreHandle xSemaphore )</pre>\r
+ *\r
+ * <i>Macro</i> that implements a mutex semaphore by using the existing queue \r
+ * mechanism.\r
+ *\r
+ * This type of semaphore uses a priority inheritance mechanism so a task \r
+ * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the \r
+ * semaphore it is no longer required.  \r
+ *\r
+ * Mutex type semaphores cannot be used from within interrupt service routines.  \r
+ *\r
+ * See xSemaphoreCreateBinary() for an alternative implemnetation that can be \r
+ * used for pure synchronisation (where one task or interrupt always 'gives' the \r
+ * semaphore and another always 'takes' the semaphore) and from within interrupt \r
+ * service routines.\r
+ *\r
+ * @param xSemaphore Handle to the created mutex semaphore.  Should be of type \r
+ *             xSemaphoreHandle.\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+ xSemaphoreHandle xSemaphore;\r
+\r
+ void vATask( void * pvParameters )\r
+ {\r
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().\r
+    // This is a macro so pass the variable in directly.\r
+    vSemaphoreCreateMutex( xSemaphore );\r
+\r
+    if( xSemaphore != NULL )\r
+    {\r
+        // The semaphore was created successfully.\r
+        // The semaphore can now be used.  \r
+    }\r
+ }\r
+ </pre>\r
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex\r
+ * \ingroup Semaphores\r
+ */\r
+#define xSemaphoreCreateMutex() xQueueCreateMutex()\r
+\r
 \r
+#endif /* SEMAPHORE_H */\r
 \r
-#endif\r
 \r
index 7a4d1095b3a51dec7de10548cdefa01611df59f0..6535fc8b36c1b13e337fffda73d71579fb79fd94 100644 (file)
@@ -364,7 +364,7 @@ void vTaskDelay( portTickType xTicksToDelay );
  * \defgroup vTaskDelayUntil vTaskDelayUntil\r
  * \ingroup TaskCtrl\r
  */\r
-void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );\r
+void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement );\r
 \r
 /**\r
  * task. h\r
@@ -894,7 +894,7 @@ inline void vTaskIncrementTick( void );
  * portTICK_RATE_MS can be used to convert kernel ticks into a real time\r
  * period.\r
  */\r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait );\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait );\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN\r
@@ -911,7 +911,7 @@ void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait );
  * @return pdTRUE if the task being removed has a higher priority than the task\r
  * making the call, otherwise pdFALSE.\r
  */\r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList *pxEventList );\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList );\r
 \r
 /*\r
  * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE.  IT IS AN\r
@@ -944,13 +944,13 @@ xTaskHandle xTaskGetCurrentTaskHandle( void );
 /*\r
  * Capture the current time status for future reference.\r
  */\r
-void vTaskSetTimeOutState( xTimeOutType *pxTimeOut );\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut );\r
 \r
 /*\r
  * Compare the time status now with that previously captured to see if the\r
  * timeout has expired.\r
  */\r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType * const pxTicksToWait );\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait );\r
 \r
 /*\r
  * Shortcut used by the queue implementation to prevent unnecessary call to\r
@@ -964,6 +964,18 @@ void vTaskMissedYield( void );
  */\r
 portBASE_TYPE xTaskGetSchedulerState( void );\r
 \r
+/*\r
+ * Raises the priority of the mutex holder to that of the calling task should\r
+ * the mutex holder have a priority less than the calling task.\r
+ */\r
+void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder );\r
+\r
+/*\r
+ * Set the priority of a task back to its proper priority in the case that it\r
+ * inherited a higher priority while it was holding a semaphore.\r
+ */\r
+void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder );\r
+\r
 #endif /* TASK_H */\r
 \r
 \r
index 51e80a3e7932bb511569137b7de3fb10352cbcb7..1fbcc85b46226fb7c1eced837bf2d4fdf6b5c1ea 100644 (file)
@@ -51,18 +51,18 @@ void portSWITCH_CONTEXT( void );
  */\r
 void portFIRST_CONTEXT( void );\r
 \r
-#define portSWITCH_CONTEXT()                                                                                   \r
-//                                                     asm { mov       ax, seg pxCurrentTCB            }\r
-//                                                     asm { mov       ds, ax                                          }\r
-//                                                     asm { les       bx, pxCurrentTCB                        }       /* Save the stack pointer into the TCB. */\r
-//                                                     asm { mov       es:0x2[ bx ], ss                        }\r
-//                                                     asm { mov       es:[ bx ], sp                           }\r
-//                                                     asm { call  far ptr vTaskSwitchContext  }       /* Perform the switch. */\r
-//                                                     asm { mov       ax, seg pxCurrentTCB            }       /* Restore the stack pointer from the TCB. */\r
-//                                                     asm { mov       ds, ax                                          }\r
-//                                                     asm { les       bx, dword ptr pxCurrentTCB      }\r
-//                                                     asm { mov       ss, es:[ bx + 2 ]                       }       \r
-//                                                     asm { mov       sp, es:[ bx ]                           }\r
+#define portSWITCH_CONTEXT()                                                                            \\r
+                                               asm { mov       ax, seg pxCurrentTCB            } \\r
+                                                       asm { mov       ds, ax                                          }  \\r
+                                                       asm { les       bx, pxCurrentTCB                        }       /* Save the stack pointer into the TCB. */    \\r
+                                                       asm { mov       es:0x2[ bx ], ss                        }   \\r
+                                                       asm { mov       es:[ bx ], sp                           }   \\r
+                                                       asm { call  far ptr vTaskSwitchContext  }       /* Perform the switch. */   \\r
+                                                       asm { mov       ax, seg pxCurrentTCB            }       /* Restore the stack pointer from the TCB. */  \\r
+                                                       asm { mov       ds, ax                                          }   \\r
+                                                       asm { les       bx, dword ptr pxCurrentTCB      }   \\r
+                                                       asm { mov       ss, es:[ bx + 2 ]                       }      \\r
+                                                       asm { mov       sp, es:[ bx ]                           }\r
 \r
 #define portFIRST_CONTEXT()                                                                                            \\r
                                                        asm { mov       ax, seg pxCurrentTCB            }       \\r
@@ -70,7 +70,7 @@ void portFIRST_CONTEXT( void );
                                                        asm { les       bx, dword ptr pxCurrentTCB      }       \\r
                                                        asm { mov       ss, es:[ bx + 2 ]                       }       \\r
                                                        asm { mov       sp, es:[ bx ]                           }       \\r
-                                                       asm { pop       bx                                                      }       \\r
+                                                       asm { pop       bp                                                      }       \\r
                                                        asm { pop       di                                                      }       \\r
                                                        asm { pop       si                                                      }       \\r
                                                        asm { pop       ds                                                      }       \\r
index 58d8ccde8777131af4a3b4c97940eedcf143a806..0431715dfdcb736b8149bced80d44bc99ee4f400 100644 (file)
@@ -70,9 +70,9 @@ Changes from V4.1.2:
 \r
 Changes from V4.1.3:\r
 \r
-       + Modified xQueueSend() and xQueueReceive() to handle the (very unlikely) \r
-       case whereby a task unblocking due to a temporal event can remove/send an \r
-       item from/to a queue when a higher priority task is     still blocked on the \r
+       + Modified xQueueSend() and xQueueReceive() to handle the (very unlikely)\r
+       case whereby a task unblocking due to a temporal event can remove/send an\r
+       item from/to a queue when a higher priority task is     still blocked on the\r
        queue.  This modification is a result of the SafeRTOS testing.\r
 */\r
 \r
@@ -90,6 +90,15 @@ Changes from V4.1.3:
 #define queueUNLOCKED  ( ( signed portBASE_TYPE ) -1 )\r
 #define queueERRONEOUS_UNBLOCK                                 ( -1 )\r
 \r
+/* For internal use only. */\r
+#define        queueSEND_TO_BACK       ( 0 )\r
+#define        queueSEND_TO_FRONT      ( 1 )\r
+\r
+/* Effectively make a union out of the xQUEUE structure. */\r
+#define pxMutexHolder                          pcTail\r
+#define uxQueueType                                    pcHead\r
+#define queueQUEUE_IS_MUTEX                    NULL\r
+\r
 /*\r
  * Definition of the queue used by the scheduler.\r
  * Items are queued by copy, not reference.\r
@@ -109,8 +118,8 @@ typedef struct QueueDefinition
        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
-       signed portBASE_TYPE xRxLock;                           /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */\r
-       signed portBASE_TYPE xTxLock;                           /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */\r
+       signed portBASE_TYPE xRxLock;                   /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */\r
+       signed portBASE_TYPE xTxLock;                   /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */\r
 } xQUEUE;\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -127,12 +136,13 @@ typedef xQUEUE * xQueueHandle;
  * functions are documented in the API header file.\r
  */\r
 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );\r
-signed portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait );\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
 unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle pxQueue );\r
 void vQueueDelete( xQueueHandle xQueue );\r
-signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken );\r
-signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition );\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
+xQueueHandle xQueueCreateMutex( void );\r
 \r
 #if configUSE_CO_ROUTINES == 1\r
        signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
@@ -166,20 +176,15 @@ static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue );
 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue );\r
 \r
 /*\r
- * Macro that copies an item into the queue.  This is done by copying the item\r
- * byte for byte, not by reference.  Updates the queue state to ensure it's\r
- * integrity after the copy.\r
+ * Copies an item into the queue, either at the front of the queue or the\r
+ * back of the queue.\r
  */\r
-#define prvCopyQueueData( pxQueue, pvItemToQueue )                                                                                             \\r
-{                                                                                                                                                                                              \\r
-       memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );       \\r
-       ++( pxQueue->uxMessagesWaiting );                                                                                                                       \\r
-       pxQueue->pcWriteTo += pxQueue->uxItemSize;                                                                                                      \\r
-       if( pxQueue->pcWriteTo >= pxQueue->pcTail )                                                                                                     \\r
-       {                                                                                                                                                                                       \\r
-               pxQueue->pcWriteTo = pxQueue->pcHead;                                                                                                   \\r
-       }                                                                                                                                                                                       \\r
-}\r
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition );\r
+\r
+/*\r
+ * Copies an item out of a queue.\r
+ */\r
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer );\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -248,7 +253,49 @@ size_t xQueueSizeInBytes;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
+#if ( configUSE_MUTEXES == 1 )\r
+\r
+       xQueueHandle xQueueCreateMutex( void )\r
+       {\r
+       xQUEUE *pxNewQueue;\r
+       \r
+               /* Allocate the new queue structure. */\r
+               pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
+               if( pxNewQueue != NULL )\r
+               {\r
+                       /* Information required for priority inheritance. */\r
+                       pxNewQueue->pxMutexHolder = NULL;\r
+                       pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
+       \r
+                       /* Queues used as a mutex no data is actually copied into or out\r
+                       of the queue. */\r
+                       pxNewQueue->pcWriteTo = NULL;\r
+                       pxNewQueue->pcReadFrom = NULL;\r
+                       \r
+                       /* Each mutex has a length of 1 (like a binary semaphore) and\r
+                       an item size of 0 as nothing is actually copied into or out\r
+                       of the mutex. */\r
+                       pxNewQueue->uxMessagesWaiting = 0;\r
+                       pxNewQueue->uxLength = 1;\r
+                       pxNewQueue->uxItemSize = 0;\r
+                       pxNewQueue->xRxLock = queueUNLOCKED;\r
+                       pxNewQueue->xTxLock = queueUNLOCKED;\r
+       \r
+                       /* Ensure the event queues start with the correct state. */\r
+                       vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
+                       vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
+\r
+                       /* Start with the semaphore in the expected state. */\r
+                       xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );\r
+               }\r
+       \r
+               return pxNewQueue;\r
+       }\r
+\r
+#endif /* configUSE_MUTEXES */\r
+/*-----------------------------------------------------------*/\r
+\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
 {\r
 signed portBASE_TYPE xReturn = pdPASS;\r
 xTimeOutType xTimeOut;\r
@@ -285,15 +332,15 @@ xTimeOutType xTimeOut;
        queue being modified here.  Places where the event list is modified\r
        include:\r
 \r
-               + xQueueSendFromISR().  This checks the lock on the queue to see if\r
-                 it has access.  If the queue is locked then the Tx lock count is\r
+               + xQueueGenericSendFromISR().  This checks the lock on the queue to see\r
+                 if it has access.  If the queue is locked then the Tx lock count is\r
                  incremented to signify that a task waiting for data can be made ready\r
                  once the queue lock is removed.  If the queue is not locked then\r
                  a task can be moved from the event list, but will not be removed\r
                  from the delayed list or placed in the ready list until the scheduler\r
                  is unlocked.\r
 \r
-               + xQueueReceiveFromISR().  As per xQueueSendFromISR().\r
+               + xQueueReceiveFromISR().  As per xQueueGenericSendFromISR().\r
        */\r
                \r
        /* If the queue is already full we may have to block. */\r
@@ -390,7 +437,7 @@ xTimeOutType xTimeOut;
                                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                                {\r
                                        /* There is room in the queue, copy the data into the queue. */                 \r
-                                       prvCopyQueueData( pxQueue, pvItemToQueue );             \r
+                                       prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
                                        xReturn = pdPASS;\r
                \r
                                        /* Update the TxLock count so prvUnlockQueue knows to check for\r
@@ -425,16 +472,16 @@ xTimeOutType xTimeOut;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken )\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE xTaskPreviouslyWoken, portBASE_TYPE xCopyPosition )\r
 {\r
-       /* Similar to xQueueSend, except we don't block if there is no room in the\r
-       queue.  Also we don't directly wake a task that was blocked on a queue\r
-       read, instead we return a flag to say whether a context switch is required\r
-       or not (i.e. has a task with a higher priority than us been woken by this\r
-       post). */\r
+       /* Similar to xQueueGenericSend, except we don't block if there is no room\r
+       in the queue.  Also we don't directly wake a task that was blocked on a\r
+       queue read, instead we return a flag to say whether a context switch is\r
+       required or not (i.e. has a task with a higher priority than us been woken\r
+       by this post). */\r
        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
        {\r
-               prvCopyQueueData( pxQueue, pvItemToQueue );\r
+               prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
 \r
                /* If the queue is locked we do not alter the event list.  This will\r
                be done when the queue is unlocked later. */\r
@@ -467,13 +514,14 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
 {\r
 signed portBASE_TYPE xReturn = pdTRUE;\r
 xTimeOutType xTimeOut;\r
+signed portCHAR *pcOriginalReadPosition;\r
 \r
-       /* This function is very similar to xQueueSend().  See comments within\r
-       xQueueSend() for a more detailed explanation.\r
+       /* This function is very similar to xQueueGenericSend().  See comments\r
+       within xQueueGenericSend() for a more detailed explanation.\r
 \r
        Make sure other tasks do not access the queue. */\r
        vTaskSuspendAll();\r
@@ -493,6 +541,17 @@ xTimeOutType xTimeOut;
                        leave with nothing? */                  \r
                        if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                       {\r
+                                               portENTER_CRITICAL();\r
+                                                       vTaskPriorityInherit( ( xTaskHandle * const ) pxQueue->pxMutexHolder );\r
+                                               portEXIT_CRITICAL();\r
+                                       }\r
+                               }\r
+                               #endif\r
+                               \r
                                vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
                                taskENTER_CRITICAL();\r
                                {\r
@@ -522,18 +581,39 @@ xTimeOutType xTimeOut;
                        {\r
                                if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
                                {\r
-                                       pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
-                                       if( pxQueue->pcReadFrom >= pxQueue->pcTail )\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
-                                               pxQueue->pcReadFrom = pxQueue->pcHead;\r
+                                               /* We are actually removing data. */\r
+                                               --( pxQueue->uxMessagesWaiting );\r
+                                                       \r
+                                               /* Increment the lock count so prvUnlockQueue knows to check for\r
+                                               tasks waiting for space to become available on the queue. */\r
+                                               ++( pxQueue->xRxLock );\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
-                                       --( pxQueue->uxMessagesWaiting );\r
-                                       memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
-               \r
-                                       /* Increment the lock count so prvUnlockQueue knows to check for\r
-                                       tasks waiting for space to become available on the queue. */\r
-                                       ++( pxQueue->xRxLock );\r
-                                       xReturn = pdPASS;\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
@@ -563,21 +643,15 @@ xTimeOutType xTimeOut;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken )\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )\r
 {\r
 signed portBASE_TYPE xReturn;\r
 \r
        /* We cannot block from an ISR, so check there is data available. */\r
        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
        {\r
-               /* Copy the data from the queue. */\r
-               pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
-               if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
-               {\r
-                       pxQueue->pcReadFrom = pxQueue->pcHead;\r
-               }\r
+               prvCopyDataFromQueue( pxQueue, pvBuffer );\r
                --( pxQueue->uxMessagesWaiting );\r
-               memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
 \r
                /* If the queue is locked we will not modify the event list.  Instead\r
                we update the lock count so the task that unlocks the queue will know\r
@@ -636,6 +710,57 @@ void vQueueDelete( xQueueHandle pxQueue )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
+{\r
+       if( pxQueue->uxItemSize == 0 )\r
+       {\r
+               #if ( configUSE_MUTEXES == 1 )\r
+               {\r
+                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                       {\r
+                               /* The mutex is no longer being held. */\r
+                               vTaskPriorityDisinherit( ( xTaskHandle * const ) pxQueue->pxMutexHolder );\r
+                       }\r
+               }\r
+               #endif\r
+       }\r
+       else if( xPosition == queueSEND_TO_BACK )\r
+       {\r
+               memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
+               pxQueue->pcWriteTo += pxQueue->uxItemSize;\r
+               if( pxQueue->pcWriteTo >= pxQueue->pcTail )\r
+               {\r
+                       pxQueue->pcWriteTo = pxQueue->pcHead;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );\r
+               pxQueue->pcReadFrom -= pxQueue->uxItemSize;\r
+               if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
+               {\r
+                       pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
+               }               \r
+       }\r
+\r
+       ++( pxQueue->uxMessagesWaiting );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )\r
+{\r
+       if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )\r
+       {\r
+               pxQueue->pcReadFrom += pxQueue->uxItemSize;\r
+               if( pxQueue->pcReadFrom >= pxQueue->pcTail )\r
+               {\r
+                       pxQueue->pcReadFrom = pxQueue->pcHead;\r
+               }\r
+               memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
+       }       \r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 static void prvUnlockQueue( xQueueHandle pxQueue )\r
 {\r
        /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */\r
@@ -722,7 +847,7 @@ signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQue
 signed portBASE_TYPE xReturn;\r
                \r
        /* If the queue is already full we may have to block.  A critical section\r
-       is required to prevent an interrupt removing something from the queue \r
+       is required to prevent an interrupt removing something from the queue\r
        between the check to see if the queue is full and blocking on the queue. */\r
        portDISABLE_INTERRUPTS();\r
        {\r
@@ -754,19 +879,19 @@ signed portBASE_TYPE xReturn;
                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                {\r
                        /* There is room in the queue, copy the data into the queue. */                 \r
-                       prvCopyQueueData( pxQueue, pvItemToQueue );             \r
+                       prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
                        xReturn = pdPASS;\r
 \r
                        /* Were any co-routines waiting for data to become available? */\r
                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
                        {\r
-                               /* In this instance the co-routine could be placed directly \r
-                               into the ready list as we are within a critical section.  \r
-                               Instead the same pending ready list mechansim is used as if\r
+                               /* In this instance the co-routine could be placed directly\r
+                               into the ready list as we are within a critical section.\r
+                               Instead the same pending ready list mechanism is used as if\r
                                the event were caused from within an interrupt. */\r
                                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
                                {\r
-                                       /* The co-routine waiting has a higher priority so record \r
+                                       /* The co-routine waiting has a higher priority so record\r
                                        that a yield might be appropriate. */\r
                                        xReturn = errQUEUE_YIELD;\r
                                }\r
@@ -790,7 +915,7 @@ signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, port
 signed portBASE_TYPE xReturn;\r
 \r
        /* If the queue is already empty we may have to block.  A critical section\r
-       is required to prevent an interrupt adding something to the queue \r
+       is required to prevent an interrupt adding something to the queue\r
        between the check to see if the queue is empty and blocking on the queue. */\r
        portDISABLE_INTERRUPTS();\r
        {\r
@@ -835,9 +960,9 @@ signed portBASE_TYPE xReturn;
                        /* Were any co-routines waiting for space to become available? */\r
                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
                        {\r
-                               /* In this instance the co-routine could be placed directly \r
-                               into the ready list as we are within a critical section.  \r
-                               Instead the same pending ready list mechansim is used as if\r
+                               /* In this instance the co-routine could be placed directly\r
+                               into the ready list as we are within a critical section.\r
+                               Instead the same pending ready list mechanism is used as if\r
                                the event were caused from within an interrupt. */\r
                                if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
                                {\r
@@ -866,9 +991,9 @@ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvIt
        exit without doing anything. */\r
        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
        {\r
-               prvCopyQueueData( pxQueue, pvItemToQueue );\r
+               prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
 \r
-               /* We only want to wake one co-routine per ISR, so check that a \r
+               /* We only want to wake one co-routine per ISR, so check that a\r
                co-routine has not already been woken. */\r
                if( !xCoRoutinePreviouslyWoken )                \r
                {\r
index e572f5c09e21a09d21ba6699e14040b8f92b59ef..7ed5637a1a934d3262b75f59480a601066b0e190 100644 (file)
@@ -229,10 +229,6 @@ Changes since V4.3.1:
        #define configMAX_TASK_NAME_LEN 16\r
 #endif\r
 \r
-#ifndef INCLUDE_xTaskGetCurrentTaskHandle\r
-       #define INCLUDE_xTaskGetCurrentTaskHandle 0\r
-#endif\r
-\r
 #ifndef configIDLE_SHOULD_YIELD\r
        #define configIDLE_SHOULD_YIELD         1\r
 #endif\r
@@ -261,9 +257,16 @@ typedef struct tskTaskControlBlock
        xListItem                               xEventListItem;         /*< List item used to place the TCB in event lists. */\r
        unsigned portBASE_TYPE  uxPriority;                     /*< The priority of the task where 0 is the lowest priority. */\r
        portSTACK_TYPE                  *pxStack;                       /*< Points to the start of the stack. */\r
-       unsigned portBASE_TYPE  uxTCBNumber;            /*< This is used for tracing the scheduler and making debugging easier only. */\r
        signed portCHAR                 pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created.  Facilitates debugging only. */\r
-       unsigned portSHORT              usStackDepth;           /*< Total depth of the stack (when empty).  This is defined as the number of variables the stack can hold, not the number of bytes. */\r
+\r
+       #if ( configUSE_TRACE_FACILITY == 1 )\r
+               unsigned portBASE_TYPE  uxTCBNumber;            /*< This is used for tracing the scheduler and making debugging easier only. */\r
+       #endif  \r
+               \r
+       #if ( configUSE_MUTEXES == 1 )\r
+               unsigned portBASE_TYPE uxBasePriority;\r
+       #endif\r
+               \r
 } tskTCB;\r
 \r
 /*lint -e956 */\r
@@ -429,7 +432,7 @@ register tskTCB *pxTCB;                                                                                                                                                                                             \
  * Utility to ready a TCB for a given task.  Mainly just copies the parameters\r
  * into the TCB structure.\r
  */\r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority );\r
 \r
 /*\r
  * Utility to ready all the lists used by the scheduler.  This is called\r
@@ -485,7 +488,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus );\r
 \r
 #endif\r
 \r
@@ -496,7 +499,7 @@ static tskTCB *prvAllocateTCBAndStack( unsigned portSHORT usStackDepth );
  */\r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte );\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte );\r
 \r
 #endif\r
 \r
@@ -524,7 +527,9 @@ signed portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode, const signed portCHAR
 {\r
 signed portBASE_TYPE xReturn;\r
 tskTCB * pxNewTCB;\r
-static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+       static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberate - this is guarded before use. */\r
+#endif\r
 \r
        /* Allocate the memory required by the TCB and stack for the new task.\r
        checking that the allocation was successful. */\r
@@ -535,7 +540,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                portSTACK_TYPE *pxTopOfStack;\r
 \r
                /* Setup the newly allocated TCB with the initial state of the task. */\r
-               prvInitialiseTCBVariables( pxNewTCB, usStackDepth, pcName, uxPriority );\r
+               prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority );\r
 \r
                /* Calculate the top of stack address.  This depends on whether the\r
                stack grows from high memory to low (as per the 80x86) or visa versa.\r
@@ -543,7 +548,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                required by the port. */\r
                #if portSTACK_GROWTH < 0\r
                {\r
-                       pxTopOfStack = pxNewTCB->pxStack + ( pxNewTCB->usStackDepth - 1 );\r
+                       pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 );\r
                }\r
                #else\r
                {\r
@@ -593,9 +598,13 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                uxTopUsedPriority = pxNewTCB->uxPriority;\r
                        }\r
 \r
-                       /* Add a counter into the TCB for tracing only. */\r
-                       pxNewTCB->uxTCBNumber = uxTaskNumber;\r
-                       uxTaskNumber++;\r
+                       #if ( configUSE_TRACE_FACILITY == 1 )\r
+                       {\r
+                               /* Add a counter into the TCB for tracing only. */\r
+                               pxNewTCB->uxTCBNumber = uxTaskNumber;\r
+                               uxTaskNumber++;\r
+                       }\r
+                       #endif\r
 \r
                        prvAddTaskToReadyQueue( pxNewTCB );\r
 \r
@@ -695,7 +704,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
 \r
 #if ( INCLUDE_vTaskDelayUntil == 1 )\r
 \r
-       void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement )\r
+       void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
        {\r
        portTickType xTimeToWake;\r
        portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE;\r
@@ -867,13 +876,22 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        /* If null is passed in here then we are changing the\r
                        priority of the calling function. */\r
                        pxTCB = prvGetTCBFromHandle( pxTask );\r
-                       uxCurrentPriority = pxTCB->uxPriority;\r
+                       \r
+                       #if ( configUSE_MUTEXES == 1 )\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxBasePriority;\r
+                       }\r
+                       #else\r
+                       {\r
+                               uxCurrentPriority = pxTCB->uxPriority;\r
+                       }\r
+                       #endif\r
 \r
                        if( uxCurrentPriority != uxNewPriority )\r
                        {\r
                                /* The priority change may have readied a task of higher\r
                                priority than the calling task. */\r
-                               if( uxNewPriority > pxCurrentTCB->uxPriority ) \r
+                               if( uxNewPriority > uxCurrentPriority ) \r
                                {\r
                                        if( pxTask != NULL )\r
                                        {\r
@@ -891,7 +909,26 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                                        xYieldRequired = pdTRUE;\r
                                }\r
                        \r
-                               pxTCB->uxPriority = uxNewPriority;\r
+                               \r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
+                               {\r
+                                       /* Only change the priority being used if the task is not\r
+                                       currently using an inherited priority. */\r
+                                       if( pxTCB->uxBasePriority == pxTCB->uxPriority )\r
+                                       {\r
+                                               pxTCB->uxPriority = uxNewPriority;\r
+                                       }\r
+                                       \r
+                                       /* The base priority gets set whatever. */\r
+                                       pxTCB->uxBasePriority = uxNewPriority;                                  \r
+                               }\r
+                               #else\r
+                               {\r
+                                       pxTCB->uxPriority = uxNewPriority;\r
+                               }\r
+                               #endif\r
+\r
                                listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxNewPriority );\r
 \r
                                /* If the task is in the blocked or suspended list we need do\r
@@ -1051,7 +1088,7 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat
                        {\r
                                /* We cannot access the delayed or ready lists, so will hold this\r
                                task pending until the scheduler is resumed, at which point a\r
-                               yield will be preformed if necessary. */\r
+                               yield will be performed if necessary. */\r
                                vListInsertEnd( ( xList * ) &( xPendingReadyList ), &( pxTCB->xEventListItem ) );\r
                        }\r
                }\r
@@ -1457,7 +1494,7 @@ void vTaskSwitchContext( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskPlaceOnEventList( xList *pxEventList, portTickType xTicksToWait )\r
+void vTaskPlaceOnEventList( const xList * const pxEventList, portTickType xTicksToWait )\r
 {\r
 portTickType xTimeToWake;\r
 \r
@@ -1527,7 +1564,7 @@ portTickType xTimeToWake;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xTaskRemoveFromEventList( const xList *pxEventList )\r
+signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList )\r
 {\r
 tskTCB *pxUnblockedTCB;\r
 portBASE_TYPE xReturn;\r
@@ -1574,14 +1611,14 @@ portBASE_TYPE xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vTaskSetTimeOutState( xTimeOutType *pxTimeOut )\r
+void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut )\r
 {\r
     pxTimeOut->xOverflowCount = xNumOfOverflows;\r
     pxTimeOut->xTimeOnEntering = xTickCount;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType *pxTimeOut, portTickType * const pxTicksToWait )\r
+portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait )\r
 {\r
 portBASE_TYPE xReturn;\r
 \r
@@ -1701,10 +1738,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
 \r
 \r
 \r
-static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStackDepth, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
+static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed portCHAR * const pcName, unsigned portBASE_TYPE uxPriority )\r
 {\r
-       pxTCB->usStackDepth = usStackDepth;\r
-\r
        /* Store the function name in the TCB. */\r
        strncpy( ( char * ) pxTCB->pcTaskName, ( const char * ) pcName, ( unsigned portSHORT ) configMAX_TASK_NAME_LEN );\r
        pxTCB->pcTaskName[ ( unsigned portSHORT ) configMAX_TASK_NAME_LEN - ( unsigned portSHORT ) 1 ] = '\0';\r
@@ -1716,6 +1751,11 @@ static void prvInitialiseTCBVariables( tskTCB *pxTCB, unsigned portSHORT usStack
        }\r
 \r
        pxTCB->uxPriority = uxPriority;\r
+       #if ( configUSE_MUTEXES == 1 )\r
+       {\r
+               pxTCB->uxBasePriority = uxPriority;\r
+       }\r
+       #endif\r
 \r
        vListInitialiseItem( &( pxTCB->xGenericListItem ) );\r
        vListInitialiseItem( &( pxTCB->xEventListItem ) );\r
@@ -1831,7 +1871,7 @@ tskTCB *pxNewTCB;
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
 \r
-       static void prvListTaskWithinSingleList( signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
+       static void prvListTaskWithinSingleList( const signed portCHAR *pcWriteBuffer, xList *pxList, signed portCHAR cStatus )\r
        {\r
        volatile tskTCB *pxNextTCB, *pxFirstTCB;\r
        static portCHAR pcStatusString[ 50 ];\r
@@ -1853,7 +1893,7 @@ tskTCB *pxNewTCB;
 /*-----------------------------------------------------------*/\r
 \r
 #if ( configUSE_TRACE_FACILITY == 1 )\r
-       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR *pucStackByte )\r
+       unsigned portSHORT usTaskCheckFreeStackSpace( const unsigned portCHAR * pucStackByte )\r
        {\r
        register unsigned portSHORT usCount = 0;\r
 \r
@@ -1933,4 +1973,63 @@ tskTCB *pxNewTCB;
 \r
 #endif\r
 \r
+#if ( configUSE_MUTEXES == 1 )\r
+       \r
+       void vTaskPriorityInherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
+               {\r
+                       /* Adjust the mutex holder state to account for its new priority. */\r
+                       listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority );\r
+\r
+                       /* If the task being modified is in the read state it will need to\r
+                       be moved in to a new list. */\r
+                       if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) )\r
+                       {\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Inherit the priority before being moved into the new list. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Just inherit the priority. */\r
+                               pxTCB->uxPriority = pxCurrentTCB->uxPriority;\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+\r
+#if ( configUSE_MUTEXES == 1 ) \r
+\r
+       void vTaskPriorityDisinherit( xTaskHandle * const pxMutexHolder )\r
+       {\r
+       tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder;\r
+\r
+               if( pxMutexHolder != NULL )\r
+               {\r
+                       if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
+                       {\r
+                               /* We must be the running task to be able to give the mutex back.\r
+                               Remove ourselves from the ready list we currently appear in. */\r
+                               vListRemove( &( pxTCB->xGenericListItem ) );\r
+\r
+                               /* Disinherit the priority before adding ourselves into the new\r
+                               ready list. */\r
+                               pxTCB->uxPriority = pxTCB->uxBasePriority;\r
+                               listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority );\r
+                               prvAddTaskToReadyQueue( pxTCB );\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+\r
+       \r
+\r
+       \r
 \r