]> git.sur5r.net Git - freertos/blobdiff - Source/queue.c
Remove unnecessary ';' characters from a couple of macro definitions in the IAR MSP43...
[freertos] / Source / queue.c
index 28961d2dd1dfffd0e4c85e993c8b08be8d728f1d..e08cc2878797bb03b1152e50ed3aa9d83f635cbb 100644 (file)
 /*\r
-       FreeRTOS.org V4.8.0 - Copyright (C) 2003-2008 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
+    FreeRTOS V6.1.0 - Copyright (C) 2010 Real Time Engineers Ltd.\r
 \r
-    ***************************************************************************\r
     ***************************************************************************\r
     *                                                                         *\r
-    * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
-    * and even write all or part of your application on your behalf.          *\r
-    * See http://www.OpenRTOS.com for details of the services we provide to   *\r
-    * expedite your project.                                                  *\r
+    * If you are:                                                             *\r
+    *                                                                         *\r
+    *    + New to FreeRTOS,                                                   *\r
+    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *\r
+    *    + Looking for basic training,                                        *\r
+    *    + Wanting to improve your FreeRTOS skills and productivity           *\r
+    *                                                                         *\r
+    * then take a look at the FreeRTOS books - available as PDF or paperback  *\r
+    *                                                                         *\r
+    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *\r
+    *                  http://www.FreeRTOS.org/Documentation                  *\r
+    *                                                                         *\r
+    * A pdf reference manual is also available.  Both are usually delivered   *\r
+    * to your inbox within 20 minutes to two hours when purchased between 8am *\r
+    * and 8pm GMT (although please allow up to 24 hours in case of            *\r
+    * exceptional circumstances).  Thank you for your support!                *\r
     *                                                                         *\r
     ***************************************************************************\r
-    ***************************************************************************\r
-\r
-       Please ensure to read the configuration and relevant port sections of the\r
-       online documentation.\r
-\r
-       http://www.FreeRTOS.org - Documentation, latest information, license and \r
-       contact details.\r
 \r
-       http://www.SafeRTOS.com - A version that is certified for use in safety \r
-       critical systems.\r
-\r
-       http://www.OpenRTOS.com - Commercial support, development, porting, \r
-       licensing and training services.\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
+    ***NOTE*** The exception to the GPL is included to allow you to distribute\r
+    a combined work that includes FreeRTOS without being obliged to provide the\r
+    source code for proprietary components outside of the FreeRTOS kernel.\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT\r
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
+    more details. You should have received a copy of the GNU General Public \r
+    License and the FreeRTOS license exception along with FreeRTOS; if not it \r
+    can be viewed here: http://www.freertos.org/a00114.html and also obtained \r
+    by writing to Richard Barry, contact details for whom are available on the\r
+    FreeRTOS WEB site.\r
+\r
+    1 tab == 4 spaces!\r
+\r
+    http://www.FreeRTOS.org - Documentation, latest information, license and\r
+    contact details.\r
+\r
+    http://www.SafeRTOS.com - A version that is certified for use in safety\r
+    critical systems.\r
+\r
+    http://www.OpenRTOS.com - Commercial support, development, porting,\r
+    licensing and training services.\r
 */\r
 \r
 #include <stdlib.h>\r
 #include <string.h>\r
+\r
+/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
+all the API functions to use the MPU wrappers.  That should only be done when\r
+task.h is included from an application file. */\r
+#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
 #include "croutine.h"\r
 \r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
+\r
 /*-----------------------------------------------------------\r
  * PUBLIC LIST API documented in list.h\r
  *----------------------------------------------------------*/\r
 \r
 /* Constants used with the cRxLock and cTxLock structure members. */\r
-#define queueUNLOCKED                                                  ( ( signed portBASE_TYPE ) -1 )\r
-#define queueLOCKED_UNMODIFIED                                 ( ( signed portBASE_TYPE ) 0 )\r
+#define queueUNLOCKED                                  ( ( signed portBASE_TYPE ) -1 )\r
+#define queueLOCKED_UNMODIFIED                 ( ( signed portBASE_TYPE ) 0 )\r
 \r
-#define queueERRONEOUS_UNBLOCK                                 ( -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
+#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 uxRecursiveCallCount           pcReadFrom\r
-#define queueQUEUE_IS_MUTEX                    NULL\r
+#define pxMutexHolder                                  pcTail\r
+#define uxQueueType                                            pcHead\r
+#define uxRecursiveCallCount                   pcReadFrom\r
+#define queueQUEUE_IS_MUTEX                            NULL\r
 \r
 /* Semaphores do not actually store or copy data, so have an items size of\r
 zero. */\r
 #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )\r
 #define queueDONT_BLOCK                                         ( ( portTickType ) 0 )\r
 #define queueMUTEX_GIVE_BLOCK_TIME              ( ( portTickType ) 0 )\r
+\r
 /*\r
  * Definition of the queue used by the scheduler.\r
  * Items are queued by copy, not reference.\r
  */\r
 typedef struct QueueDefinition\r
 {\r
-       signed portCHAR *pcHead;                                /*< Points to the beginning of the queue storage area. */\r
-       signed portCHAR *pcTail;                                /*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
+       signed char *pcHead;                            /*< Points to the beginning of the queue storage area. */\r
+       signed char *pcTail;                            /*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */\r
 \r
-       signed portCHAR *pcWriteTo;                             /*< Points to the free next place in the storage area. */\r
-       signed portCHAR *pcReadFrom;                    /*< Points to the last place that a queued item was read from. */\r
+       signed char *pcWriteTo;                         /*< Points to the free next place in the storage area. */\r
+       signed char *pcReadFrom;                        /*< Points to the last place that a queued item was read from. */\r
 \r
        xList xTasksWaitingToSend;                              /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */\r
        xList xTasksWaitingToReceive;                   /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */\r
@@ -99,6 +112,7 @@ typedef struct QueueDefinition
 \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
+\r
 } xQUEUE;\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -114,29 +128,58 @@ typedef xQUEUE * xQueueHandle;
  * include the API header file (as it defines xQueueHandle differently).  These\r
  * functions are documented in the API header file.\r
  */\r
-xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );\r
-signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
-unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue );\r
-void vQueueDelete( xQueueHandle xQueue );\r
-signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );\r
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
-xQueueHandle xQueueCreateMutex( void );\r
-xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );\r
-portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );\r
-portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );\r
-signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
-signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
-signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );\r
-signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );\r
-unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );\r
-\r
+xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
 \r
+/*\r
+ * Co-routine queue functions differ from task queue functions.  Co-routines are\r
+ * an optional component.\r
+ */\r
 #if configUSE_CO_ROUTINES == 1\r
-       signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );\r
-       signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );\r
-       signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );\r
-       signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );\r
+       signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;\r
+       signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
+       signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+       signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+#endif\r
+\r
+/*\r
+ * The queue registry is just a means for kernel aware debuggers to locate\r
+ * queue structures.  It has no other purpose so is an optional component.\r
+ */\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+       /* The type stored within the queue registry array.  This allows a name\r
+       to be assigned to each queue making kernel aware debugging a little\r
+       more user friendly. */\r
+       typedef struct QUEUE_REGISTRY_ITEM\r
+       {\r
+               signed char *pcQueueName;\r
+               xQueueHandle xHandle;\r
+       } xQueueRegistryItem;\r
+\r
+       /* The queue registry is simply an array of xQueueRegistryItem structures.\r
+       The pcQueueName member of a structure being NULL is indicative of the\r
+       array position being vacant. */\r
+       xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];\r
+\r
+       /* Removes a queue from the registry by simply setting the pcQueueName\r
+       member to NULL. */\r
+       static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
+       void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;\r
 #endif\r
 \r
 /*\r
@@ -147,32 +190,32 @@ unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue
  * to indicate that a task may require unblocking.  When the queue in unlocked\r
  * these lock counts are inspected, and the appropriate action taken.\r
  */\r
-static void prvUnlockQueue( xQueueHandle pxQueue );\r
+static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Uses a critical section to determine if there is any data in a queue.\r
  *\r
  * @return pdTRUE if the queue contains no items, otherwise pdFALSE.\r
  */\r
-static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue );\r
+static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Uses a critical section to determine if there is any space in a queue.\r
  *\r
  * @return pdTRUE if there is no space, otherwise pdFALSE;\r
  */\r
-static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue );\r
+static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Copies an item into the queue, either at the front of the queue or the\r
  * back of the queue.\r
  */\r
-static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition );\r
+static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;\r
 \r
 /*\r
  * Copies an item out of a queue.\r
  */\r
-static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer );\r
+static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -216,7 +259,7 @@ size_t xQueueSizeInBytes;
                        longer than asked for to make wrap checking easier/faster. */\r
                        xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;\r
 \r
-                       pxNewQueue->pcHead = ( signed portCHAR * ) pvPortMalloc( xQueueSizeInBytes );\r
+                       pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );\r
                        if( pxNewQueue->pcHead != NULL )\r
                        {\r
                                /* Initialise the queue members as described above where the\r
@@ -235,7 +278,6 @@ size_t xQueueSizeInBytes;
                                vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
 \r
                                traceQUEUE_CREATE( pxNewQueue );\r
-\r
                                return  pxNewQueue;\r
                        }\r
                        else\r
@@ -257,7 +299,7 @@ size_t xQueueSizeInBytes;
        xQueueHandle xQueueCreateMutex( void )\r
        {\r
        xQUEUE *pxNewQueue;\r
-       \r
+\r
                /* Allocate the new queue structure. */\r
                pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
                if( pxNewQueue != NULL )\r
@@ -265,12 +307,12 @@ size_t xQueueSizeInBytes;
                        /* Information required for priority inheritance. */\r
                        pxNewQueue->pxMutexHolder = NULL;\r
                        pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
-       \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
+\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
@@ -279,7 +321,7 @@ size_t xQueueSizeInBytes;
                        pxNewQueue->uxItemSize = 0;\r
                        pxNewQueue->xRxLock = queueUNLOCKED;\r
                        pxNewQueue->xTxLock = queueUNLOCKED;\r
-       \r
+\r
                        /* Ensure the event queues start with the correct state. */\r
                        vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
                        vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
@@ -293,7 +335,7 @@ size_t xQueueSizeInBytes;
                {\r
                        traceCREATE_MUTEX_FAILED();\r
                }\r
-       \r
+\r
                return pxNewQueue;\r
        }\r
 \r
@@ -328,10 +370,10 @@ size_t xQueueSizeInBytes;
                        {\r
                                /* Return the mutex.  This will automatically unblock any other\r
                                task that might be waiting to access the mutex. */\r
-                xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
+                               xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
                        }\r
 \r
-                       xReturn = pdPASS;                       \r
+                       xReturn = pdPASS;\r
                }\r
                else\r
                {\r
@@ -365,7 +407,7 @@ size_t xQueueSizeInBytes;
                }\r
                else\r
                {\r
-            xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );\r
+                       xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );\r
 \r
                        /* pdPASS will only be returned if we successfully obtained the mutex,\r
                        we may have blocked to reach here. */\r
@@ -373,7 +415,11 @@ size_t xQueueSizeInBytes;
                        {\r
                                ( pxMutex->uxRecursiveCallCount )++;\r
                        }\r
-               }               \r
+                       else\r
+                       {\r
+                               traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex );\r
+                       }\r
+               }\r
 \r
                return xReturn;\r
        }\r
@@ -386,7 +432,7 @@ size_t xQueueSizeInBytes;
        xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
        {\r
        xQueueHandle pxHandle;\r
-       \r
+\r
                pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );\r
 \r
                if( pxHandle != NULL )\r
@@ -408,128 +454,117 @@ size_t xQueueSizeInBytes;
 \r
 signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
 {\r
-signed portBASE_TYPE xReturn = pdTRUE;\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
 xTimeOutType xTimeOut;\r
 \r
-       do\r
+       /* This function relaxes the coding standard somewhat to allow return\r
+       statements within the function itself.  This is done in the interest\r
+       of execution time efficiency. */\r
+       for( ;; )\r
        {\r
-       /* If xTicksToWait is zero then we are not going to block even\r
-       if there is no room in the queue to post. */\r
-               if( xTicksToWait > ( portTickType ) 0 )\r
-               {\r
-                       vTaskSuspendAll();\r
-                       prvLockQueue( pxQueue );\r
-\r
-                       if( xReturn == pdTRUE )\r
-                       {\r
-                               /* This is the first time through - we need to capture the\r
-                               time while the scheduler is locked to ensure we attempt to\r
-                               block at least once. */\r
-                               vTaskSetTimeOutState( &xTimeOut );\r
-                       }\r
-\r
-                       if( prvIsQueueFull( pxQueue ) )\r
-                       {\r
-                       /* Need to call xTaskCheckForTimeout again as time could\r
-                       have passed since it was last called if this is not the\r
-                       first time around this loop.  */\r
-                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                               {\r
-                                       traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
-                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-                                               \r
-                                       /* Unlocking the queue means queue events can effect the\r
-                                       event list.  It is possible     that interrupts occurring now\r
-                                       remove this task from the event list again - but as the\r
-                                       scheduler is suspended the task will go onto the pending\r
-                                       ready last instead of the actual ready list. */\r
-                                       prvUnlockQueue( pxQueue );\r
-                                               \r
-                                       /* Resuming the scheduler will move tasks from the pending\r
-                                       ready list into the ready list - so it is feasible that this\r
-                                       task is already in a ready list before it yields - in which\r
-                                       case the yield will not cause a context switch unless there\r
-                                       is also a higher priority task in the pending ready list. */\r
-                                       if( !xTaskResumeAll() )\r
-                                       {\r
-                                               taskYIELD();\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       prvUnlockQueue( pxQueue );\r
-                                       ( void ) xTaskResumeAll();\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                       /* The queue was not full so we can just unlock the\r
-                       scheduler and queue again before carrying on. */\r
-                               prvUnlockQueue( pxQueue );\r
-                               ( void ) xTaskResumeAll();\r
-                       }\r
-               }\r
-                       \r
-               /* Higher priority tasks and interrupts can execute during\r
-               this time and could possible refill the queue - even if we\r
-               unblocked because space became available. */\r
-               \r
                taskENTER_CRITICAL();\r
                {\r
-                       /* Is there room on the queue now?  To be running we must be\r
-                       the highest priority task wanting to access the queue. */\r
+                       /* Is there room on the queue now?  To be running we must be\r
+                       the highest priority task wanting to access the queue. */\r
                        if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                        {\r
                                traceQUEUE_SEND( pxQueue );\r
                                prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-                               xReturn = pdPASS;\r
-                                       \r
+\r
                                /* If there was a task waiting for data to arrive on the\r
                                queue then unblock it now. */\r
                                if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
                                {\r
                                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )\r
                                        {\r
-                                           /* The unblocked task has a priority higher than\r
-                                           our own so yield immediately. */\r
-                                           taskYIELD();\r
+                                               /* The unblocked task has a priority higher than\r
+                                               our own so yield immediately.  Yes it is ok to do\r
+                                               this from within the critical section - the kernel\r
+                                               takes care of that. */\r
+                                               portYIELD_WITHIN_API();\r
                                        }\r
                                }\r
+\r
+                               taskEXIT_CRITICAL();\r
+\r
+                               /* Return to the original privilege level before exiting the\r
+                               function. */\r
+                               return pdPASS;\r
                        }\r
                        else\r
                        {\r
-                               /* Setting xReturn to errQUEUE_FULL will force its timeout\r
-                               to be re-evaluated.  This is necessary in case interrupts\r
-                               and higher priority tasks accessed the queue between this\r
-                               task being unblocked and subsequently attempting to write\r
-                               to the queue. */\r
-                               xReturn = errQUEUE_FULL;\r
+                               if( xTicksToWait == ( portTickType ) 0 )\r
+                               {\r
+                                       /* The queue was full and no block time is specified (or\r
+                                       the block time has expired) so leave now. */\r
+                                       taskEXIT_CRITICAL();\r
+\r
+                                       /* Return to the original privilege level before exiting\r
+                                       the function. */\r
+                                       traceQUEUE_SEND_FAILED( pxQueue );\r
+                                       return errQUEUE_FULL;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       /* The queue was full and a block time was specified so\r
+                                       configure the timeout structure. */\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
                        }\r
                }\r
                taskEXIT_CRITICAL();\r
 \r
-               if( xReturn == errQUEUE_FULL )\r
+               /* Interrupts and other tasks can send to and receive from the queue\r
+               now the critical section has been exited. */\r
+\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
+\r
+               /* Update the timeout state to see if it has expired yet. */\r
+               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                {\r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
+                       if( prvIsQueueFull( pxQueue ) )\r
                        {\r
-                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                               {\r
-                                       xReturn = queueERRONEOUS_UNBLOCK;\r
-                               }\r
-                               else\r
+                               traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+\r
+                               /* Unlocking the queue means queue events can effect the\r
+                               event list.  It is possible     that interrupts occurring now\r
+                               remove this task from the event list again - but as the\r
+                               scheduler is suspended the task will go onto the pending\r
+                               ready last instead of the actual ready list. */\r
+                               prvUnlockQueue( pxQueue );\r
+\r
+                               /* Resuming the scheduler will move tasks from the pending\r
+                               ready list into the ready list - so it is feasible that this\r
+                               task is already in a ready list before it yields - in which\r
+                               case the yield will not cause a context switch unless there\r
+                               is also a higher priority task in the pending ready list. */\r
+                               if( !xTaskResumeAll() )\r
                                {\r
-                                       traceQUEUE_SEND_FAILED( pxQueue );\r
+                                       portYIELD_WITHIN_API();\r
                                }\r
                        }\r
                        else\r
                        {\r
-                               traceQUEUE_SEND_FAILED( pxQueue );\r
+                               /* Try again. */\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
                        }\r
                }\r
+               else\r
+               {\r
+                       /* The timeout has expired. */\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+\r
+                       /* Return to the original privilege level before exiting the\r
+                       function. */\r
+                       traceQUEUE_SEND_FAILED( pxQueue );\r
+                       return errQUEUE_FULL;\r
+               }\r
        }\r
-       while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-       return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -537,65 +572,20 @@ xTimeOutType xTimeOut;
 \r
        signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
        {\r
-       signed portBASE_TYPE xReturn = pdPASS;\r
+       signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
        xTimeOutType xTimeOut;\r
 \r
-               /* The source code that implements the alternative (Alt) API is\r
-               simpler because it makes more use of critical sections.  This is        \r
-               the approach taken by many other RTOSes, but FreeRTOS.org has the\r
-               preferred fully featured API too.  The fully featured API has more\r
-               complex code that takes longer to execute, but makes less use of\r
-               critical sections.  */\r
-\r
-               do\r
+               for( ;; )\r
                {\r
-               /* If xTicksToWait is zero then we are not going to block even\r
-               if there is no room in the queue to post. */\r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
-                       {\r
-                               portENTER_CRITICAL();\r
-                               {\r
-                                       if( xReturn == pdPASS )\r
-                                       {\r
-                                               /* This is the first time through - capture the time\r
-                                               inside the critical section to ensure we attempt to\r
-                                               block at least once. */\r
-                                               vTaskSetTimeOutState( &xTimeOut );\r
-                                       }\r
-                                       \r
-                                       if( prvIsQueueFull( pxQueue ) )\r
-                                       {\r
-                                       /* Need to call xTaskCheckForTimeout again as time could\r
-                                       have passed since it was last called if this is not the\r
-                                       first time around this loop.  */\r
-                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                               {\r
-                                                       traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
-                                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
-\r
-                                                       /* This will exit the critical section, then re-enter when\r
-                                                       the task next runs. */\r
-                                                       taskYIELD();\r
-                                               }\r
-                                       }\r
-                               }\r
-                               portEXIT_CRITICAL();\r
-                       }\r
-                               \r
-                       /* Higher priority tasks and interrupts can execute during\r
-                       this time and could possible refill the queue - even if we\r
-                       unblocked because space became available. */\r
-                       \r
                        taskENTER_CRITICAL();\r
                        {\r
-                               /* Is there room on the queue now?  To be running we must be\r
-                               the highest priority task wanting to access the queue. */\r
+                               /* Is there room on the queue now?  To be running we must be\r
+                               the highest priority task wanting to access the queue. */\r
                                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                                {\r
                                        traceQUEUE_SEND( pxQueue );\r
                                        prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
-                                       xReturn = pdPASS;\r
-                                               \r
+\r
                                        /* If there was a task waiting for data to arrive on the\r
                                        queue then unblock it now. */\r
                                        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
@@ -604,44 +594,49 @@ xTimeOutType xTimeOut;
                                                {\r
                                                        /* The unblocked task has a priority higher than\r
                                                        our own so yield immediately. */\r
-                                                       taskYIELD();\r
+                                                       portYIELD_WITHIN_API();\r
                                                }\r
                                        }\r
+\r
+                                       taskEXIT_CRITICAL();\r
+                                       return pdPASS;\r
                                }\r
                                else\r
                                {\r
-                                       /* Setting xReturn to errQUEUE_FULL will force its timeout\r
-                                       to be re-evaluated.  This is necessary in case interrupts\r
-                                       and higher priority tasks accessed the queue between this\r
-                                       task being unblocked and subsequently attempting to write\r
-                                       to the queue. */\r
-                                       xReturn = errQUEUE_FULL;\r
+                                       if( xTicksToWait == ( portTickType ) 0 )\r
+                                       {\r
+                                               taskEXIT_CRITICAL();\r
+                                               return errQUEUE_FULL;\r
+                                       }\r
+                                       else if( xEntryTimeSet == pdFALSE )\r
+                                       {\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
+                                               xEntryTimeSet = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
                        taskEXIT_CRITICAL();\r
 \r
-                       if( xReturn == errQUEUE_FULL )\r
+                       taskENTER_CRITICAL();\r
                        {\r
-                               if( xTicksToWait > ( portTickType ) 0 )\r
+                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
-                                       if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                       {\r
-                                               xReturn = queueERRONEOUS_UNBLOCK;\r
-                                       }\r
-                                       else\r
+                                       if( prvIsQueueFull( pxQueue ) )\r
                                        {\r
-                                               traceQUEUE_SEND_FAILED( pxQueue );\r
+                                               traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
+                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
+                                               portYIELD_WITHIN_API();\r
                                        }\r
                                }\r
                                else\r
                                {\r
+                                       taskEXIT_CRITICAL();\r
                                        traceQUEUE_SEND_FAILED( pxQueue );\r
+                                       return errQUEUE_FULL;\r
                                }\r
                        }\r
+                       taskEXIT_CRITICAL();\r
                }\r
-               while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-               return xReturn;\r
        }\r
 \r
 #endif /* configUSE_ALTERNATIVE_API */\r
@@ -649,62 +644,14 @@ xTimeOutType xTimeOut;
 \r
 #if configUSE_ALTERNATIVE_API == 1\r
 \r
-       signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
+       signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
        {\r
-       signed portBASE_TYPE xReturn = pdTRUE;\r
+       signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
        xTimeOutType xTimeOut;\r
-       signed portCHAR *pcOriginalReadPosition;\r
-\r
-               /* The source code that implements the alternative (Alt) API is\r
-               simpler because it makes more use of critical sections.  This is        \r
-               the approach taken by many other RTOSes, but FreeRTOS.org has the\r
-               preferred fully featured API too.  The fully featured API has more\r
-               complex code that takes longer to execute, but makes less use of\r
-               critical sections.  */\r
+       signed char *pcOriginalReadPosition;\r
 \r
-               do\r
+               for( ;; )\r
                {\r
-                       /* If there are no messages in the queue we may have to block. */\r
-                       if( xTicksToWait > ( portTickType ) 0 )\r
-                       {\r
-                               portENTER_CRITICAL();\r
-                               {\r
-                                       if( xReturn == pdPASS )\r
-                                       {\r
-                                               /* This is the first time through - capture the time\r
-                                               inside the critical section to ensure we attempt to\r
-                                               block at least once. */\r
-                                               vTaskSetTimeOutState( &xTimeOut );\r
-                                       }\r
-                                       \r
-                                       if( prvIsQueueEmpty( pxQueue ) )\r
-                                       {\r
-                                       /* Need to call xTaskCheckForTimeout again as time could\r
-                                       have passed since it was last called if this is not the\r
-                                       first time around this loop. */\r
-                                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                               {\r
-                                                       traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
-\r
-                                                       #if ( configUSE_MUTEXES == 1 )\r
-                                                       {\r
-                                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
-                                                               {\r
-                                                                       portENTER_CRITICAL();\r
-                                                                               vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
-                                                                       portEXIT_CRITICAL();\r
-                                                               }\r
-                                                       }\r
-                                                       #endif\r
-\r
-                                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
-                                                       taskYIELD();\r
-                                               }\r
-                                       }\r
-                               }\r
-                               portEXIT_CRITICAL();\r
-                       }\r
-               \r
                        taskENTER_CRITICAL();\r
                        {\r
                                if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
@@ -731,12 +678,12 @@ xTimeOutType xTimeOut;
                                                        }\r
                                                }\r
                                                #endif\r
-                                                       \r
+\r
                                                if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
                                                {\r
                                                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
                                                        {\r
-                                                               taskYIELD();\r
+                                                               portYIELD_WITHIN_API();\r
                                                        }\r
                                                }\r
                                        }\r
@@ -756,43 +703,65 @@ xTimeOutType xTimeOut;
                                                        the pending ready list as the scheduler is still suspended. */\r
                                                        if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
                                                        {\r
-                                                               /* The task waiting has a higher priority that this task. */\r
-                                                               taskYIELD();\r
+                                                               /* The task waiting has a higher priority than this task. */\r
+                                                               portYIELD_WITHIN_API();\r
                                                        }\r
-                                               }                       \r
+                                               }\r
 \r
                                        }\r
-                                       \r
-                                       xReturn = pdPASS;                                       \r
+\r
+                                       taskEXIT_CRITICAL();\r
+                                       return pdPASS;\r
                                }\r
                                else\r
                                {\r
-                                       xReturn = errQUEUE_EMPTY;\r
+                                       if( xTicksToWait == ( portTickType ) 0 )\r
+                                       {\r
+                                               taskEXIT_CRITICAL();\r
+                                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                               return errQUEUE_EMPTY;\r
+                                       }\r
+                                       else if( xEntryTimeSet == pdFALSE )\r
+                                       {\r
+                                               vTaskSetTimeOutState( &xTimeOut );\r
+                                               xEntryTimeSet = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
                        taskEXIT_CRITICAL();\r
 \r
-                       if( xReturn == errQUEUE_EMPTY )\r
+                       taskENTER_CRITICAL();\r
                        {\r
-                               if( xTicksToWait > ( portTickType ) 0 )\r
+                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                                {\r
-                                       if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                                       {\r
-                                               xReturn = queueERRONEOUS_UNBLOCK;\r
-                                       }\r
-                                       else\r
+                                       if( prvIsQueueEmpty( pxQueue ) )\r
                                        {\r
-                                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                                               #if ( configUSE_MUTEXES == 1 )\r
+                                               {\r
+                                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                                       {\r
+                                                               portENTER_CRITICAL();\r
+                                                                       vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                                               portEXIT_CRITICAL();\r
+                                                       }\r
+                                               }\r
+                                               #endif\r
+\r
+                                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                                               portYIELD_WITHIN_API();\r
                                        }\r
                                }\r
                                else\r
                                {\r
+                                       taskEXIT_CRITICAL();\r
                                        traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       return errQUEUE_EMPTY;\r
                                }\r
                        }\r
-               } while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-               return xReturn;\r
+                       taskEXIT_CRITICAL();\r
+               }\r
        }\r
 \r
 \r
@@ -802,115 +771,72 @@ xTimeOutType xTimeOut;
 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )\r
 {\r
 signed portBASE_TYPE xReturn;\r
+unsigned portBASE_TYPE uxSavedInterruptStatus;\r
 \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
+       uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
        {\r
-               traceQUEUE_SEND_FROM_ISR( pxQueue );\r
+               if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
+               {\r
+                       traceQUEUE_SEND_FROM_ISR( pxQueue );\r
 \r
-               prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\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
-               if( pxQueue->xTxLock == queueUNLOCKED )\r
-               {\r
-                       if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\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
+                       if( pxQueue->xTxLock == queueUNLOCKED )\r
                        {\r
-                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                               if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
                                {\r
-                                       /* The task waiting has a higher priority so record that a\r
-                                       context switch is required. */\r
-                                       *pxHigherPriorityTaskWoken = pdTRUE;\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
+                                       {\r
+                                               /* The task waiting has a higher priority so record that a\r
+                                               context switch is required. */\r
+                                               *pxHigherPriorityTaskWoken = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
+                       else\r
+                       {\r
+                               /* Increment the lock count so the task that unlocks the queue\r
+                               knows that data was posted while it was locked. */\r
+                               ++( pxQueue->xTxLock );\r
+                       }\r
+\r
+                       xReturn = pdPASS;\r
                }\r
                else\r
                {\r
-                       /* Increment the lock count so the task that unlocks the queue\r
-                       knows that data was posted while it was locked. */\r
-                       ++( pxQueue->xTxLock );\r
+                       traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );\r
+                       xReturn = errQUEUE_FULL;\r
                }\r
-\r
-               xReturn = pdPASS;\r
-       }\r
-       else\r
-       {\r
-               traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );\r
-               xReturn = errQUEUE_FULL;\r
        }\r
+       portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
 \r
        return xReturn;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
+signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
 {\r
-signed portBASE_TYPE xReturn = pdTRUE;\r
+signed portBASE_TYPE xEntryTimeSet = pdFALSE;\r
 xTimeOutType xTimeOut;\r
-signed portCHAR *pcOriginalReadPosition;\r
-\r
-       do\r
-       {\r
-               /* If there are no messages in the queue we may have to block. */\r
-               if( xTicksToWait > ( portTickType ) 0 )\r
-               {\r
-                       vTaskSuspendAll();\r
-                       prvLockQueue( pxQueue );\r
-\r
-                       if( xReturn == pdTRUE )\r
-                       {\r
-                               /* This is the first time through - we need to capture the\r
-                               time while the scheduler is locked to ensure we attempt to\r
-                               block at least once. */\r
-                               vTaskSetTimeOutState( &xTimeOut );\r
-                       }\r
+signed char *pcOriginalReadPosition;\r
 \r
-                       if( prvIsQueueEmpty( pxQueue ) )\r
-                       {\r
-                       /* Need to call xTaskCheckForTimeout again as time could\r
-                       have passed since it was last called if this is not the\r
-                       first time around this loop. */\r
-                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
-                               {\r
-                                       traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+       /* This function relaxes the coding standard somewhat to allow return\r
+       statements within the function itself.  This is done in the interest\r
+       of execution time efficiency. */\r
 \r
-                                       #if ( configUSE_MUTEXES == 1 )\r
-                                       {\r
-                                               if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
-                                               {\r
-                                                       portENTER_CRITICAL();\r
-                                                               vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
-                                                       portEXIT_CRITICAL();\r
-                                               }\r
-                                       }\r
-                                       #endif\r
-\r
-                                       vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
-                                       prvUnlockQueue( pxQueue );\r
-                                       if( !xTaskResumeAll() )\r
-                                       {\r
-                                               taskYIELD();\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       prvUnlockQueue( pxQueue );\r
-                                       ( void ) xTaskResumeAll();\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               prvUnlockQueue( pxQueue );\r
-                               ( void ) xTaskResumeAll();\r
-                       }\r
-               }\r
-       \r
+       for( ;; )\r
+       {\r
                taskENTER_CRITICAL();\r
                {\r
+                       /* Is there data in the queue now?  To be running we must be\r
+                       the highest priority task wanting to access the queue. */\r
                        if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
                        {\r
                                /* Remember our read position in case we are just peeking. */\r
@@ -935,12 +861,12 @@ signed portCHAR *pcOriginalReadPosition;
                                                }\r
                                        }\r
                                        #endif\r
-                                               \r
+\r
                                        if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
                                        {\r
                                                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
                                                {\r
-                                                       taskYIELD();\r
+                                                       portYIELD_WITHIN_API();\r
                                                }\r
                                        }\r
                                }\r
@@ -960,87 +886,134 @@ signed portCHAR *pcOriginalReadPosition;
                                                the pending ready list as the scheduler is still suspended. */\r
                                                if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
                                                {\r
-                                                       /* The task waiting has a higher priority that this task. */\r
-                                                       taskYIELD();\r
+                                                       /* The task waiting has a higher priority than this task. */\r
+                                                       portYIELD_WITHIN_API();\r
                                                }\r
-                                       }                       \r
+                                       }\r
 \r
                                }\r
-                               \r
-                               xReturn = pdPASS;                                       \r
+\r
+                               taskEXIT_CRITICAL();\r
+                               return pdPASS;\r
                        }\r
                        else\r
                        {\r
-                               xReturn = errQUEUE_EMPTY;\r
+                               if( xTicksToWait == ( portTickType ) 0 )\r
+                               {\r
+                                       /* The queue was empty and no block time is specified (or\r
+                                       the block time has expired) so leave now. */\r
+                                       taskEXIT_CRITICAL();\r
+                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       return errQUEUE_EMPTY;\r
+                               }\r
+                               else if( xEntryTimeSet == pdFALSE )\r
+                               {\r
+                                       /* The queue was empty and a block time was specified so\r
+                                       configure the timeout structure. */\r
+                                       vTaskSetTimeOutState( &xTimeOut );\r
+                                       xEntryTimeSet = pdTRUE;\r
+                               }\r
                        }\r
                }\r
                taskEXIT_CRITICAL();\r
 \r
-               if( xReturn == errQUEUE_EMPTY )\r
+               /* Interrupts and other tasks can send to and receive from the queue\r
+               now the critical section has been exited. */\r
+\r
+               vTaskSuspendAll();\r
+               prvLockQueue( pxQueue );\r
+\r
+               /* Update the timeout state to see if it has expired yet. */\r
+               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
                {\r
-                       if( xTicksToWait > 0 )\r
+                       if( prvIsQueueEmpty( pxQueue ) )\r
                        {\r
-                               if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
+                               traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
+\r
+                               #if ( configUSE_MUTEXES == 1 )\r
                                {\r
-                                       xReturn = queueERRONEOUS_UNBLOCK;\r
+                                       if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )\r
+                                       {\r
+                                               portENTER_CRITICAL();\r
+                                               {\r
+                                                       vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );\r
+                                               }\r
+                                               portEXIT_CRITICAL();\r
+                                       }\r
                                }\r
-                               else\r
+                               #endif\r
+\r
+                               vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
+                               prvUnlockQueue( pxQueue );\r
+                               if( !xTaskResumeAll() )\r
                                {\r
-                                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                                       portYIELD_WITHIN_API();\r
                                }\r
                        }\r
                        else\r
                        {\r
-                               traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                               /* Try again. */\r
+                               prvUnlockQueue( pxQueue );\r
+                               ( void ) xTaskResumeAll();\r
                        }\r
                }\r
-       } while( xReturn == queueERRONEOUS_UNBLOCK );\r
-\r
-       return xReturn;\r
+               else\r
+               {\r
+                       prvUnlockQueue( pxQueue );\r
+                       ( void ) xTaskResumeAll();\r
+                       traceQUEUE_RECEIVE_FAILED( pxQueue );\r
+                       return errQUEUE_EMPTY;\r
+               }\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, const void * const 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
+unsigned portBASE_TYPE uxSavedInterruptStatus;\r
 \r
-       /* We cannot block from an ISR, so check there is data available. */\r
-       if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+       uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
        {\r
-               traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
+               /* We cannot block from an ISR, so check there is data available. */\r
+               if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
+               {\r
+                       traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
 \r
-               prvCopyDataFromQueue( pxQueue, pvBuffer );\r
-               --( pxQueue->uxMessagesWaiting );\r
+                       prvCopyDataFromQueue( pxQueue, pvBuffer );\r
+                       --( pxQueue->uxMessagesWaiting );\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
-               that an ISR has removed data while the queue was locked. */\r
-               if( pxQueue->xRxLock == queueUNLOCKED )\r
-               {\r
-                       if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\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
+                       that an ISR has removed data while the queue was locked. */\r
+                       if( pxQueue->xRxLock == queueUNLOCKED )\r
                        {\r
-                               if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+                               if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )\r
                                {\r
-                                       /* The task waiting has a higher priority than us so\r
-                                       force a context switch. */\r
-                                       *pxTaskWoken = pdTRUE;\r
+                                       if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )\r
+                                       {\r
+                                               /* The task waiting has a higher priority than us so\r
+                                               force a context switch. */\r
+                                               *pxTaskWoken = pdTRUE;\r
+                                       }\r
                                }\r
                        }\r
+                       else\r
+                       {\r
+                               /* Increment the lock count so the task that unlocks the queue\r
+                               knows that data was removed while it was locked. */\r
+                               ++( pxQueue->xRxLock );\r
+                       }\r
+\r
+                       xReturn = pdPASS;\r
                }\r
                else\r
                {\r
-                       /* Increment the lock count so the task that unlocks the queue\r
-                       knows that data was removed while it was locked. */\r
-                       ++( pxQueue->xRxLock );\r
+                       xReturn = pdFAIL;\r
+                       traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );\r
                }\r
-\r
-               xReturn = pdPASS;\r
-       }\r
-       else\r
-       {\r
-               xReturn = pdFAIL;\r
-               traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );\r
        }\r
+       portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
 \r
        return xReturn;\r
 }\r
@@ -1071,7 +1044,7 @@ unsigned portBASE_TYPE uxReturn;
 void vQueueDelete( xQueueHandle pxQueue )\r
 {\r
        traceQUEUE_DELETE( pxQueue );\r
-\r
+       vQueueUnregisterQueue( pxQueue );\r
        vPortFree( pxQueue->pcHead );\r
        vPortFree( pxQueue );\r
 }\r
@@ -1079,7 +1052,7 @@ void vQueueDelete( xQueueHandle pxQueue )
 \r
 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
 {\r
-       if( pxQueue->uxItemSize == 0 )\r
+       if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )\r
        {\r
                #if ( configUSE_MUTEXES == 1 )\r
                {\r
@@ -1087,7 +1060,7 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
                        {\r
                                /* The mutex is no longer being held. */\r
                                vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );\r
-                pxQueue->pxMutexHolder = NULL;\r
+                               pxQueue->pxMutexHolder = NULL;\r
                        }\r
                }\r
                #endif\r
@@ -1108,7 +1081,7 @@ static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, port
                if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
                {\r
                        pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
-               }               \r
+               }\r
        }\r
 \r
        ++( pxQueue->uxMessagesWaiting );\r
@@ -1125,7 +1098,7 @@ static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
                        pxQueue->pcReadFrom = pxQueue->pcHead;\r
                }\r
                memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
-       }       \r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -1241,7 +1214,7 @@ signed portBASE_TYPE xReturn;
 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
 {\r
 signed portBASE_TYPE xReturn;\r
-               \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
        between the check to see if the queue is full and blocking on the queue. */\r
@@ -1255,7 +1228,7 @@ signed portBASE_TYPE xReturn;
                        {\r
                                /* As this is called from a coroutine we cannot block directly, but\r
                                return indicating that we need to block. */\r
-                               vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );                          \r
+                               vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
                                portENABLE_INTERRUPTS();\r
                                return errQUEUE_BLOCKED;\r
                        }\r
@@ -1267,14 +1240,14 @@ signed portBASE_TYPE xReturn;
                }\r
        }\r
        portENABLE_INTERRUPTS();\r
-               \r
+\r
        portNOP();\r
 \r
        portDISABLE_INTERRUPTS();\r
        {\r
                if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
                {\r
-                       /* There is room in the queue, copy the data into the queue. */                 \r
+                       /* There is room in the queue, copy the data into the queue. */\r
                        prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
                        xReturn = pdPASS;\r
 \r
@@ -1318,7 +1291,7 @@ signed portBASE_TYPE xReturn;
                if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
                {\r
                        /* There are no messages in the queue, do we want to block or just\r
-                       leave with nothing? */                  \r
+                       leave with nothing? */\r
                        if( xTicksToWait > ( portTickType ) 0 )\r
                        {\r
                                /* As this is a co-routine we cannot block directly, but return\r
@@ -1364,7 +1337,7 @@ signed portBASE_TYPE xReturn;
                                {\r
                                        xReturn = errQUEUE_YIELD;\r
                                }\r
-                       }       \r
+                       }\r
                }\r
                else\r
                {\r
@@ -1391,7 +1364,7 @@ signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvIt
 \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
+               if( !xCoRoutinePreviouslyWoken )\r
                {\r
                        if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
                        {\r
@@ -1449,3 +1422,48 @@ signed portBASE_TYPE xReturn;
 #endif\r
 /*-----------------------------------------------------------*/\r
 \r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+       void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )\r
+       {\r
+       unsigned portBASE_TYPE ux;\r
+\r
+               /* See if there is an empty space in the registry.  A NULL name denotes\r
+               a free slot. */\r
+               for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )\r
+               {\r
+                       if( xQueueRegistry[ ux ].pcQueueName == NULL )\r
+                       {\r
+                               /* Store the information on this queue. */\r
+                               xQueueRegistry[ ux ].pcQueueName = pcQueueName;\r
+                               xQueueRegistry[ ux ].xHandle = xQueue;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+#endif\r
+       /*-----------------------------------------------------------*/\r
+\r
+#if configQUEUE_REGISTRY_SIZE > 0\r
+\r
+       static void vQueueUnregisterQueue( xQueueHandle xQueue )\r
+       {\r
+       unsigned portBASE_TYPE ux;\r
+\r
+               /* See if the handle of the queue being unregistered in actually in the\r
+               registry. */\r
+               for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )\r
+               {\r
+                       if( xQueueRegistry[ ux ].xHandle == xQueue )\r
+                       {\r
+                               /* Set the name to NULL to show that this slot if free again. */\r
+                               xQueueRegistry[ ux ].pcQueueName = NULL;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+#endif\r
+\r