]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/Common/Minimal/GenQTest.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / Common / Minimal / GenQTest.c
index 74a15f3321842cdc2606224349e80e6e8f307044..07b72967d8a34dbcbff7732be7fbb1b9a6ffef7b 100644 (file)
@@ -1,79 +1,42 @@
 /*\r
-    FreeRTOS V7.5.3 - Copyright (C) 2013 Real Time Engineers Ltd. \r
-    All rights reserved\r
-\r
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
-\r
-    ***************************************************************************\r
-     *                                                                       *\r
-     *    FreeRTOS provides completely free yet professionally developed,    *\r
-     *    robust, strictly quality controlled, supported, and cross          *\r
-     *    platform software that has become a de facto standard.             *\r
-     *                                                                       *\r
-     *    Help yourself get started quickly and support the FreeRTOS         *\r
-     *    project by purchasing a FreeRTOS tutorial book, reference          *\r
-     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
-     *                                                                       *\r
-     *    Thank you!                                                         *\r
-     *                                                                       *\r
-    ***************************************************************************\r
-\r
-    This file is part of the FreeRTOS distribution.\r
-\r
-    FreeRTOS is free software; you can redistribute it and/or modify it under\r
-    the terms of the GNU General Public License (version 2) as published by the\r
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
-\r
-    >>! NOTE: The modification to the GPL is included to allow you to distribute\r
-    >>! a combined work that includes FreeRTOS without being obliged to provide\r
-    >>! the source code for proprietary components outside of the FreeRTOS\r
-    >>! kernel.\r
-\r
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
-    FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
-    link: http://www.freertos.org/a00114.html\r
-\r
-    1 tab == 4 spaces!\r
-\r
-    ***************************************************************************\r
-     *                                                                       *\r
-     *    Having a problem?  Start by reading the FAQ "My application does   *\r
-     *    not run, what could be wrong?"                                     *\r
-     *                                                                       *\r
-     *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
-     *                                                                       *\r
-    ***************************************************************************\r
-\r
-    http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
-    license and Real Time Engineers Ltd. contact details.\r
-\r
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
-\r
-    http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
-    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
-    licenses offer ticketed support, indemnification and middleware.\r
-\r
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
-    engineered and independently SIL3 certified version for use in safety and\r
-    mission critical applications that require provable dependability.\r
-\r
-    1 tab == 4 spaces!\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
+ * FreeRTOS Kernel V10.0.0\r
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
- * See the comments above the prvSendFrontAndBackTest() and \r
- * prvLowPriorityMutexTask() prototypes below for more information.\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software. If you wish to use our Amazon\r
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
+ *\r
+ * 1 tab == 4 spaces!\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
+/* Standard includes. */\r
 #include <stdlib.h>\r
 \r
 /* Scheduler include files. */\r
@@ -86,7 +49,8 @@
 #include "GenQTest.h"\r
 \r
 #define genqQUEUE_LENGTH               ( 5 )\r
-#define genqNO_BLOCK                   ( 0 )\r
+#define intsemNO_BLOCK                 ( 0 )\r
+#define genqSHORT_BLOCK                        ( pdMS_TO_TICKS( 2 ) )\r
 \r
 #define genqMUTEX_LOW_PRIORITY         ( tskIDLE_PRIORITY )\r
 #define genqMUTEX_TEST_PRIORITY                ( tskIDLE_PRIORITY + 1 )\r
@@ -115,89 +79,135 @@ static void prvSendFrontAndBackTest( void *pvParameters );
  * 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
+ * priority task and then the medium priority 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
+ * Tests the behaviour when a low priority task inherits the priority of a\r
+ * higher priority task when taking two mutexes, and returns the mutexes in\r
+ * first the same order as the two mutexes were obtained, and second the\r
+ * opposite order as the two mutexes were obtained.\r
+ */\r
+static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );\r
+static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );\r
+\r
+#if( INCLUDE_xTaskAbortDelay == 1 )\r
+\r
+       #if( configUSE_PREEMPTION == 0 )\r
+               #error The additional tests included when INCLUDE_xTaskAbortDelay is 1 expect preemption to be used.\r
+       #endif\r
+\r
+       /* Tests the behaviour when a low priority task inherits the priority of a\r
+       high priority task only for the high priority task to timeout before\r
+       obtaining the mutex. */\r
+       static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex );\r
+#endif\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Flag that will be latched to pdTRUE should any unexpected behaviour be\r
 detected in any of the tasks. */\r
-static volatile portBASE_TYPE xErrorDetected = pdFALSE;\r
+static volatile BaseType_t 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
+static volatile uint32_t ulLoopCounter = 0;\r
+static volatile uint32_t 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
+static volatile uint32_t ulGuardedVariable = 0;\r
 \r
-/* Handles used in the mutext test to suspend and resume the high and medium\r
+/* Handles used in the mutex test to suspend and resume the high and medium\r
 priority mutex test tasks. */\r
-static xTaskHandle xHighPriorityMutexTask, xMediumPriorityMutexTask;\r
+static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask;\r
+\r
+/* If INCLUDE_xTaskAbortDelay is 1 additional tests are performed, requiring an\r
+additional task. */\r
+#if( INCLUDE_xTaskAbortDelay == 1 )\r
+       static TaskHandle_t xSecondMediumPriorityMutexTask;\r
+#endif\r
+\r
+/* Lets the high priority semaphore task know that its wait for the semaphore\r
+was aborted, in which case not being able to obtain the semaphore is not to be\r
+considered an error. */\r
+static volatile BaseType_t xBlockWasAborted = pdFALSE;\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
-void vStartGenericQueueTasks( unsigned portBASE_TYPE uxPriority )\r
+void vStartGenericQueueTasks( UBaseType_t uxPriority )\r
 {\r
-xQueueHandle xQueue;\r
-xSemaphoreHandle xMutex;\r
+QueueHandle_t xQueue;\r
+SemaphoreHandle_t xMutex;\r
 \r
        /* Create the queue that we are going to use for the\r
        prvSendFrontAndBackTest demo. */\r
-       xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( unsigned portLONG ) );\r
-\r
-       /* vQueueAddToRegistry() adds the queue to the queue registry, if one is\r
-       in use.  The queue registry is provided as a means for kernel aware \r
-       debuggers to locate queues and has no purpose if a kernel aware debugger\r
-       is not being used.  The call to vQueueAddToRegistry() will be removed\r
-       by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
-       defined to be less than 1. */\r
-       vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "Gen_Queue_Test" );\r
+       xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) );\r
 \r
-       /* Create the demo task and pass it the queue just created.  We are\r
-       passing the queue handle by value so it does not matter that it is\r
-       declared on the stack here. */\r
-       xTaskCreate( prvSendFrontAndBackTest, ( signed portCHAR * )"GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );\r
+       if( xQueue != NULL )\r
+       {\r
+               /* vQueueAddToRegistry() adds the queue to the queue registry, if one\r
+               is in use.  The queue registry is provided as a means for kernel aware\r
+               debuggers to locate queues and has no purpose if a kernel aware debugger\r
+               is not being used.  The call to vQueueAddToRegistry() will be removed\r
+               by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is\r
+               defined to be less than 1. */\r
+               vQueueAddToRegistry( xQueue, "Gen_Queue_Test" );\r
+\r
+               /* Create the demo task and pass it the queue just created.  We are\r
+               passing the queue handle by value so it does not matter that it is\r
+               declared on the stack here. */\r
+               xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL );\r
+       }\r
 \r
        /* Create the mutex used by the prvMutexTest task. */\r
        xMutex = xSemaphoreCreateMutex();\r
 \r
-       /* vQueueAddToRegistry() adds the mutex to the registry, if one is\r
-       in use.  The registry is provided as a means for kernel aware \r
-       debuggers to locate mutexes and has no purpose if a kernel aware debugger\r
-       is not being used.  The call to vQueueAddToRegistry() will be removed\r
-       by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is \r
-       defined to be less than 1. */\r
-       vQueueAddToRegistry( ( xQueueHandle ) xMutex, ( signed portCHAR * ) "Gen_Queue_Mutex" );\r
-\r
-       /* Create the mutex demo tasks and pass it the mutex just created.  We are\r
-       passing the mutex handle by value so it does not matter that it is declared\r
-       on the stack here. */\r
-       xTaskCreate( prvLowPriorityMutexTask, ( signed portCHAR * )"MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );\r
-       xTaskCreate( prvMediumPriorityMutexTask, ( signed portCHAR * )"MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );\r
-       xTaskCreate( prvHighPriorityMutexTask, ( signed portCHAR * )"MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );\r
+       if( xMutex != NULL )\r
+       {\r
+               /* vQueueAddToRegistry() adds the mutex to the registry, if one is\r
+               in use.  The registry is provided as a means for kernel aware\r
+               debuggers to locate mutexes and has no purpose if a kernel aware\r
+               debugger is not being used.  The call to vQueueAddToRegistry() will be\r
+               removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not\r
+               defined or is defined to be less than 1. */\r
+               vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" );\r
+\r
+               /* Create the mutex demo tasks and pass it the mutex just created.  We\r
+               are passing the mutex handle by value so it does not matter that it is\r
+               declared 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
+               /* If INCLUDE_xTaskAbortDelay is set then additional tests are performed,\r
+               requiring two instances of prvHighPriorityMutexTask(). */\r
+               #if( INCLUDE_xTaskAbortDelay == 1 )\r
+               {\r
+                       xTaskCreate( prvHighPriorityMutexTask, "MuHigh2", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_MEDIUM_PRIORITY, &xSecondMediumPriorityMutexTask );\r
+               }\r
+               #endif /* INCLUDE_xTaskAbortDelay */\r
+       }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 static void prvSendFrontAndBackTest( void *pvParameters )\r
 {\r
-unsigned portLONG ulData, ulData2;\r
-xQueueHandle xQueue;\r
+uint32_t ulData, ulData2, ulLoopCounterSnapshot;\r
+QueueHandle_t 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
+       void vPrintDisplayMessage( const char * const * ppcMessageToSend );\r
+\r
+               const char * 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
+       xQueue = ( QueueHandle_t ) pvParameters;\r
 \r
        for( ;; )\r
        {\r
@@ -205,14 +215,15 @@ xQueueHandle xQueue;
                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
+               ulLoopCounterSnapshot = ulLoopCounter;\r
+               xQueueSendToFront( xQueue, ( void * ) &ulLoopCounterSnapshot, intsemNO_BLOCK );\r
 \r
                if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
@@ -231,14 +242,15 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK );\r
+               ulLoopCounterSnapshot = ulLoopCounter;\r
+               xQueueSendToBack( xQueue, ( void * ) &ulLoopCounterSnapshot, intsemNO_BLOCK );\r
 \r
                if( uxQueueMessagesWaiting( xQueue ) != 1 )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+               if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
@@ -248,8 +260,8 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               /* The data we sent to the queue should equal the data we just received\r
-               from the queue. */\r
+               /* The data sent to the queue should equal the data just received from\r
+               the queue. */\r
                if( ulLoopCounter != ulData )\r
                {\r
                        xErrorDetected = pdTRUE;\r
@@ -264,7 +276,7 @@ xQueueHandle xQueue;
                /* 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
+                       xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK );\r
                }\r
 \r
                /* Now the order in the queue should be 2, 3, 4, with 2 being the first\r
@@ -274,9 +286,9 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
                ulData = 1;\r
-               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK );\r
                ulData = 0;\r
-               xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK );\r
+               xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_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
@@ -285,12 +297,12 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
@@ -303,7 +315,7 @@ xQueueHandle xQueue;
                for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ )\r
                {\r
                        /* Try peeking the data first. */\r
-                       if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS )\r
+                       if( xQueuePeek( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )\r
                        {\r
                                xErrorDetected = pdTRUE;\r
                        }\r
@@ -312,12 +324,12 @@ xQueueHandle xQueue;
                        {\r
                                xErrorDetected = pdTRUE;\r
                        }\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
+                       if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )\r
                        {\r
                                xErrorDetected = pdTRUE;\r
                        }\r
@@ -341,12 +353,12 @@ xQueueHandle xQueue;
 \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
+               if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
                ulData = 11;\r
-               if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS )\r
+               if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
@@ -360,7 +372,7 @@ xQueueHandle xQueue;
                front. */\r
                for( ulData = 9; ulData >= 7; ulData-- )\r
                {\r
-                       if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS )\r
+                       if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS )\r
                        {\r
                                xErrorDetected = pdTRUE;\r
                        }\r
@@ -373,12 +385,12 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL )\r
+               if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
@@ -390,7 +402,7 @@ xQueueHandle xQueue;
                /* 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
+                       if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS )\r
                        {\r
                                xErrorDetected = pdTRUE;\r
                        }\r
@@ -406,36 +418,29 @@ xQueueHandle xQueue;
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
+               /* Increment the loop counter to indicate these tasks are still\r
+               executing. */\r
                ulLoopCounter++;\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-static void prvLowPriorityMutexTask( void *pvParameters )\r
-{\r
-xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+#if( INCLUDE_xTaskAbortDelay == 1 )\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
+       static void prvHighPriorityTimeout( SemaphoreHandle_t xMutex )\r
+       {\r
+       static UBaseType_t uxLoopCount = 0;\r
 \r
-               /* Queue a message for printing to say the task has started. */\r
-               vPrintDisplayMessage( &pcTaskStartMsg );\r
-       #endif\r
+               /* The tests in this function are very similar, the slight variations\r
+               are for code coverage purposes. */\r
 \r
-       for( ;; )\r
-       {\r
                /* Take the mutex.  It should be available now. */\r
-               if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )\r
+               if( xSemaphoreTake( xMutex, intsemNO_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
+               /* This task's priority should be as per that assigned when the task was\r
                created. */\r
                if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
                {\r
@@ -446,65 +451,469 @@ xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
                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
+               /* This task should now have inherited the priority of the high priority\r
+               task as by now the high priority task will have attempted to obtain the\r
+               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
+               /* Unblock a second medium priority task.  It too will attempt to take\r
+               the mutex and enter the Blocked state - it won't run yet though as this\r
+               task has inherited a priority above it. */\r
+               vTaskResume( xSecondMediumPriorityMutexTask );\r
+\r
+               /* This task should still have the priority of the high priority task as\r
+               that had already been inherited as is the highest priority of the three\r
+               tasks using the mutex. */\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
+               /* On some loops, block for a short while to provide additional\r
+               code coverage.  Blocking here will allow the medium priority task to\r
+               execute and so also block on the mutex so when the high priority task\r
+               causes this task to disinherit the high priority it is inherited down to\r
+               the priority of the medium priority task.  When there is no delay the\r
+               medium priority task will not run until after the disinheritance, so\r
+               this task will disinherit back to its base priority, then only up to the\r
+               medium priority after the medium priority has executed. */\r
+               vTaskDelay( uxLoopCount & ( UBaseType_t ) 0x07 );\r
+\r
+               /* Now force the high priority task to unblock.  It will fail to obtain\r
+               the mutex and go back to the suspended state - allowing this task to\r
+               execute again.  xBlockWasAborted is set to pdTRUE so the higher priority\r
+               task knows that its failure to obtain the semaphore is not an error. */\r
+               xBlockWasAborted = pdTRUE;\r
+               if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* This task has inherited the priority of xHighPriorityMutexTask so\r
+               could still be running even though xHighPriorityMutexTask is no longer\r
+               blocked.  Delay for a short while to ensure xHighPriorityMutexTask gets\r
+               a chance to run - indicated by this task changing priority.  It should\r
+               disinherit the high priority task, but then inherit the priority of the\r
+               medium priority task that is waiting for the same mutex. */\r
+               while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY )\r
+               {\r
+                       /* If this task gets stuck here then the check variables will stop\r
+                       incrementing and the check task will detect the error. */\r
+                       vTaskDelay( genqSHORT_BLOCK );\r
+               }\r
+\r
+               /* Now force the medium priority task to unblock.  xBlockWasAborted is\r
+               set to pdTRUE so the medium priority task knows that its failure to\r
+               obtain the semaphore is not an error. */\r
+               xBlockWasAborted = pdTRUE;\r
+               if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* This time no other tasks are waiting for the mutex, so this task\r
+               should return to its base priority.  This might not happen straight\r
+               away as it is running at the same priority as the task it just\r
+               unblocked. */\r
+               while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+               {\r
+                       /* If this task gets stuck here then the check variables will stop\r
+                       incrementing and the check task will detect the error. */\r
+                       vTaskDelay( genqSHORT_BLOCK );\r
+               }\r
+\r
+               /* Give the semaphore back ready for the next test. */\r
+               xSemaphoreGive( xMutex );\r
+\r
+               configASSERT( xErrorDetected == pdFALSE );\r
+\r
+\r
+\r
+               /* Now do the same again, but this time unsuspend the tasks in the\r
+               opposite order.  This takes a different path though the code because\r
+               when the high priority task has its block aborted there is already\r
+               another task in the list of tasks waiting for the mutex, and the\r
+               low priority task drops down to that priority, rather than dropping\r
+               down to its base priority before inheriting the priority of the medium\r
+               priority task. */\r
+               if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+               {\r
+                       xErrorDetected = pdTRUE;\r
+               }\r
+\r
+               /* This time unsuspend the medium priority task first.  This will\r
+               attempt to take the mutex, and block when it finds it cannot obtain it. */\r
+               vTaskResume( xSecondMediumPriorityMutexTask );\r
 \r
-               /* If the did run then it will have incremented our guarded variable. */\r
-               if( ulGuardedVariable != 0 )\r
+               /* This time this task should now have inherited the priority of the\r
+               medium task. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY )\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
+               /* This time the high priority task in unsuspended second. */\r
+               vTaskResume( xHighPriorityMutexTask );\r
+\r
+               /* The high priority task should already have run, causing this task to\r
+               inherit a priority for the second time. */\r
+               if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
                {\r
                        xErrorDetected = pdTRUE;\r
                }\r
 \r
-               /* Check that the guarded variable did indeed increment... */\r
-               if( ulGuardedVariable != 1 )\r
+               /* This time, when the high priority task has its delay aborted and it\r
+               fails to obtain the mutex this task will immediately have its priority\r
+               lowered down to that of the highest priority task waiting on the mutex,\r
+               which is the medium priority task. */\r
+               xBlockWasAborted = pdTRUE;\r
+               if( xTaskAbortDelay( xHighPriorityMutexTask ) != pdPASS )\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
+               while( uxTaskPriorityGet( NULL ) != genqMUTEX_MEDIUM_PRIORITY )\r
+               {\r
+                       /* If this task gets stuck here then the check variables will stop\r
+                       incrementing and the check task will detect the error. */\r
+                       vTaskDelay( genqSHORT_BLOCK );\r
+               }\r
+\r
+               /* And finally, when the medium priority task also have its delay\r
+               aborted there are no other tasks waiting for the mutex so this task\r
+               returns to its base priority. */\r
+               xBlockWasAborted = pdTRUE;\r
+               if( xTaskAbortDelay( xSecondMediumPriorityMutexTask ) != pdPASS )\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
+               while( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+               {\r
+                       /* If this task gets stuck here then the check variables will stop\r
+                       incrementing and the check task will detect the error. */\r
+                       vTaskDelay( genqSHORT_BLOCK );\r
+               }\r
+\r
+               /* Give the semaphore back ready for the next test. */\r
+               xSemaphoreGive( xMutex );\r
+\r
+               configASSERT( xErrorDetected == pdFALSE );\r
+\r
+               /* uxLoopCount is used to add a variable delay, and in-so-doing provide\r
+               additional code coverage. */\r
+               uxLoopCount++;\r
+       }\r
+\r
+#endif /* INCLUDE_xTaskAbortDelay == 1 */\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )\r
+{\r
+       /* Take the mutex.  It should be available now. */\r
+       if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Set the guarded variable to a known start value. */\r
+       ulGuardedVariable = 0;\r
+\r
+       /* This task's 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
-               /* Just to show we are still running. */\r
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* Ensure the task is reporting its priority as blocked and not\r
+       suspended (as it would have done in versions up to V7.5.3). */\r
+       #if( INCLUDE_eTaskGetState == 1 )\r
+       {\r
+               configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );\r
+       }\r
+       #endif /* INCLUDE_eTaskGetState */\r
+\r
+       /* This task should now have inherited the priority of the high priority\r
+       task as by now the high priority task will have attempted to obtain the\r
+       mutex. */\r
+       if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Attempt to set the priority of this task to the test priority -\r
+       between the idle priority and the medium/high test priorities, but the\r
+       actual priority 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 the\r
+       inherited priority of this task is above that of the medium priority\r
+       task. */\r
+       vTaskResume( xMediumPriorityMutexTask );\r
+\r
+       /* If the medium priority task did run then it will have incremented the\r
+       guarded variable. */\r
+       if( ulGuardedVariable != 0 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Take the local mutex too, so two mutexes are now held. */\r
+       if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* When the semaphore is given back the priority of this task should not\r
+       yet be disinherited because the local mutex is still held.  This is a\r
+       simplification to allow FreeRTOS to be integrated with middleware that\r
+       attempts to hold multiple mutexes without bloating the code with complex\r
+       algorithms.  It is possible that the high priority mutex task will\r
+       execute as it shares a priority with this task. */\r
+       if( xSemaphoreGive( xMutex ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* The guarded variable is only incremented by the medium priority task,\r
+       which still should not have executed as this task should remain at the\r
+       higher priority, ensure this is the case. */\r
+       if( ulGuardedVariable != 0 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Now also give back the local mutex, taking the held count back to 0.\r
+       This time the priority of this task should be disinherited back to the\r
+       priority to which it was set while the mutex was held.  This means\r
+       the medium priority task should execute and increment the guarded\r
+       variable.   When this task next runs both the high and medium priority\r
+       tasks will have been suspended again. */\r
+       if( xSemaphoreGive( xLocalMutex ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* Check the guarded variable did indeed increment... */\r
+       if( ulGuardedVariable != 1 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* ... and that the priority of this task has been disinherited to\r
+       genqMUTEX_TEST_PRIORITY. */\r
+       if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Set the priority of this task back to its original value, ready for\r
+       the next loop around this test. */\r
+       vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )\r
+{\r
+       /* Take the mutex.  It should be available now. */\r
+       if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Set the guarded variable to a known start value. */\r
+       ulGuardedVariable = 0;\r
+\r
+       /* This task's 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
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* Ensure the task is reporting its priority as blocked and not\r
+       suspended (as it would have done in versions up to V7.5.3). */\r
+       #if( INCLUDE_eTaskGetState == 1 )\r
+       {\r
+               configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );\r
+       }\r
+       #endif /* INCLUDE_eTaskGetState */\r
+\r
+       /* This task should now have inherited the priority of the high priority\r
+       task as by now the high priority task will have attempted to obtain the\r
+       mutex. */\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 the\r
+       inherited priority of this task is above that of the medium priority\r
+       task. */\r
+       vTaskResume( xMediumPriorityMutexTask );\r
+\r
+       /* If the medium priority task did run then it will have incremented the\r
+       guarded variable. */\r
+       if( ulGuardedVariable != 0 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Take the local mutex too, so two mutexes are now held. */\r
+       if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* When the local semaphore is given back the priority of this task should\r
+       not yet be disinherited because the shared mutex is still held.  This is a\r
+       simplification to allow FreeRTOS to be integrated with middleware that\r
+       attempts to hold multiple mutexes without bloating the code with complex\r
+       algorithms.  It is possible that the high priority mutex task will\r
+       execute as it shares a priority with this task. */\r
+       if( xSemaphoreGive( xLocalMutex ) != pdPASS )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* The guarded variable is only incremented by the medium priority task,\r
+       which still should not have executed as this task should remain at the\r
+       higher priority, ensure this is the case. */\r
+       if( ulGuardedVariable != 0 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* Now also give back the shared mutex, taking the held count back to 0.\r
+       This time the priority of this task should be disinherited back to the\r
+       priority at which it was created.  This means the medium priority task\r
+       should execute and increment the guarded variable.  When this task next runs\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
+       #if configUSE_PREEMPTION == 0\r
+               taskYIELD();\r
+       #endif\r
+\r
+       /* Check the guarded variable did indeed increment... */\r
+       if( ulGuardedVariable != 1 )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+\r
+       /* ... and that the priority of this task has been disinherited to\r
+       genqMUTEX_LOW_PRIORITY. */\r
+       if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )\r
+       {\r
+               xErrorDetected = pdTRUE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvLowPriorityMutexTask( void *pvParameters )\r
+{\r
+SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex;\r
+\r
+       #ifdef USE_STDIO\r
+       void vPrintDisplayMessage( const char * const * ppcMessageToSend );\r
+\r
+               const char * 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
+       /* The local mutex is used to check the 'mutexs held' count. */\r
+       xLocalMutex = xSemaphoreCreateMutex();\r
+       configASSERT( xLocalMutex );\r
+\r
+       for( ;; )\r
+       {\r
+               /* The first tests exercise the priority inheritance when two mutexes\r
+               are taken then returned in a different order to which they were\r
+               taken. */\r
+               prvTakeTwoMutexesReturnInDifferentOrder( xMutex, xLocalMutex );\r
+\r
+               /* Just to show this task is still running. */\r
                ulLoopCounter2++;\r
 \r
                #if configUSE_PREEMPTION == 0\r
                        taskYIELD();\r
-               #endif          \r
+               #endif\r
+\r
+               /* The second tests exercise the priority inheritance when two mutexes\r
+               are taken then returned in the same order in which they were taken. */\r
+               prvTakeTwoMutexesReturnInSameOrder( xMutex, xLocalMutex );\r
+\r
+               /* Just to show this task is still running. */\r
+               ulLoopCounter2++;\r
+\r
+               #if configUSE_PREEMPTION == 0\r
+                       taskYIELD();\r
+               #endif\r
+\r
+               #if( INCLUDE_xTaskAbortDelay == 1 )\r
+               {\r
+                       /* Tests the behaviour when a low priority task inherits the\r
+                       priority of a high priority task only for the high priority task to\r
+                       timeout before obtaining the mutex. */\r
+                       prvHighPriorityTimeout( xMutex );\r
+               }\r
+               #endif\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -529,7 +938,7 @@ static void prvMediumPriorityMutexTask( void *pvParameters )
 \r
 static void prvHighPriorityMutexTask( void *pvParameters )\r
 {\r
-xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;\r
+SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;\r
 \r
        for( ;; )\r
        {\r
@@ -537,30 +946,42 @@ xSemaphoreHandle xMutex = ( xSemaphoreHandle ) pvParameters;
                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
+               /* When this task unsuspends all it does is attempt to obtain the\r
+               mutex.  It should find the mutex is not available so a block time is\r
+               specified. */\r
                if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS )\r
                {\r
-                       xErrorDetected = pdTRUE;\r
+                       /* This task would expect to obtain the mutex unless its wait for\r
+                       the mutex was aborted. */\r
+                       if( xBlockWasAborted == pdFALSE )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+                       else\r
+                       {\r
+                               xBlockWasAborted = pdFALSE;\r
+                       }\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
+               else\r
                {\r
-                       xErrorDetected = pdTRUE;\r
-               }               \r
+                       /* When the mutex is eventually obtained it is just given back before\r
+                       returning to suspend ready for the next cycle. */\r
+                       if( xSemaphoreGive( xMutex ) != pdPASS )\r
+                       {\r
+                               xErrorDetected = pdTRUE;\r
+                       }\r
+               }\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
+BaseType_t xAreGenericQueueTasksStillRunning( void )\r
 {\r
-static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;\r
+static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;\r
 \r
-       /* If the demo task is still running then we expect the loopcounters to\r
+       /* If the demo task is still running then we expect the loop counters to\r
        have incremented since this function was last called. */\r
        if( ulLastLoopCounter == ulLoopCounter )\r
        {\r
@@ -573,12 +994,12 @@ static unsigned portLONG ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
        }\r
 \r
        ulLastLoopCounter = ulLoopCounter;\r
-       ulLastLoopCounter2 = ulLoopCounter2;    \r
+       ulLastLoopCounter2 = ulLoopCounter2;\r
 \r
        /* Errors detected in the task itself will have latched xErrorDetected\r
        to true. */\r
 \r
-       return ( portBASE_TYPE ) !xErrorDetected;\r
+       return ( BaseType_t ) !xErrorDetected;\r
 }\r
 \r
 \r