]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/Common/Minimal/StaticAllocation.c
- Rework the StaticAllocation.c common demo file to reflect the changes to the static...
[freertos] / FreeRTOS / Demo / Common / Minimal / StaticAllocation.c
index ee35d4ec1c8fbe3879eba5071ff6b1c09756fee1..4b4232b55dcfe788547d09a7bfac297b006f26a4 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-    FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 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
  * Demonstrates how to create FreeRTOS objects using pre-allocated memory,\r
- * rather than the normal dynamically allocated memory.\r
+ * rather than the normal dynamically allocated memory, and tests objects being\r
+ * created and deleted with both statically allocated memory and dynamically\r
+ * allocated memory.\r
  *\r
- * Two buffers are required by a task - one that is used by the task as its\r
- * stack, and one that holds the task's control block (TCB).\r
- * prvStaticallyAllocatedCreator() creates and deletes tasks with all\r
- * possible combinations of statically allocated and dynamically allocated\r
- * stacks and TCBs.\r
+ * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html\r
  */\r
 \r
 /* Scheduler include files. */\r
@@ -84,6 +82,8 @@
 #include "task.h"\r
 #include "queue.h"\r
 #include "semphr.h"\r
+#include "event_groups.h"\r
+#include "timers.h"\r
 \r
 /* Demo program include files. */\r
 #include "StaticAllocation.h"\r
@@ -104,14 +104,14 @@ allocation tests. */
 /* Binary semaphores have a maximum count of 1. */\r
 #define staticBINARY_SEMAPHORE_MAX_COUNT       ( 1 )\r
 \r
+/* The size of the stack used by the task that runs the tests. */\r
+#define staticCREATOR_TASK_STACK_SIZE          ( configMINIMAL_STACK_SIZE * 2 )\r
 \r
-/*-----------------------------------------------------------*/\r
+/* The number of times the software timer will execute before stopping itself. */\r
+#define staticMAX_TIMER_CALLBACK_EXECUTIONS    ( 5 )\r
 \r
-/*\r
- * A task that is created and deleted multiple times, using both statically and\r
- * dynamically allocated stack and TCB.\r
- */\r
-static void prvStaticallyAllocatedTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
  * The task that repeatedly creates and deletes statically allocated tasks, and\r
@@ -120,53 +120,71 @@ static void prvStaticallyAllocatedTask( void *pvParameters );
 static void prvStaticallyAllocatedCreator( void *pvParameters );\r
 \r
 /*\r
- * Utility function to create pseudo random numbers.\r
+ * The callback function used by the software timer that is repeatedly created\r
+ * and deleted using both static and dynamically allocated memory.\r
  */\r
-static UBaseType_t prvRand( void );\r
+static void prvTimerCallback( TimerHandle_t xExpiredTimer );\r
+\r
+/*\r
+ * A task that is created and deleted multiple times, using both statically and\r
+ * dynamically allocated stack and TCB.\r
+ */\r
+static void prvStaticallyAllocatedTask( void *pvParameters );\r
 \r
 /*\r
- * A function that demonstrates and tests the xTaskCreateStatic() API function\r
- * by creating and then deleting tasks with both dynamically and statically\r
- * allocated TCBs and stacks.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete tasks using both statically and dynamically allocated TCBs and stacks.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedTasks( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xQueueCreateStatic() API function\r
- * by creating and then deleting queues with both dynamically and statically\r
- * allocated queue structures and queue storage areas.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete event groups using both statically and dynamically allocated RAM.\r
+ */\r
+static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void );\r
+\r
+/*\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete queues using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedQueues( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API\r
- * macro by creating and then deleting binary semaphores with both dynamically\r
- * and statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete binary semaphores using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateMutexStatic() API\r
- * macro by creating and then deleting mutexes with both dynamically and\r
- * statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete software timers using both statically and dynamically allocated RAM.\r
+ */\r
+static void prvCreateAndDeleteStaticallyAllocatedTimers( void );\r
+\r
+/*\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete mutexes using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedMutexes( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the xSemaphoreCreateCountingStatic()\r
- * API macro by creating and then deleting counting semaphores with both\r
- * dynamically and statically allocated semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete counting semaphores using both statically and dynamically allocated\r
+ * RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void );\r
 \r
 /*\r
- * A function that demonstrates and tests the\r
- * xSemaphoreCreateRecursiveMutexStatic() API macro by creating and then\r
- * deleting recursive mutexes with both dynamically and statically allocated\r
- * semaphore structures.\r
+ * A function that demonstrates and tests the API functions that create and\r
+ * delete recursive mutexes using both statically and dynamically allocated RAM.\r
  */\r
 static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void );\r
 \r
+/*\r
+ * Utility function to create pseudo random numbers.\r
+ */\r
+static UBaseType_t prvRand( void );\r
+\r
 /*\r
  * The task that creates and deletes other tasks has to delay occasionally to\r
  * ensure lower priority tasks are not starved of processing time.  A pseudo\r
@@ -178,34 +196,39 @@ static TickType_t prvGetNextDelayTime( void );
 /*\r
  * Checks the basic operation of a queue after it has been created.\r
  */\r
-static void prvCheckQueueFunction( QueueHandle_t xQueue );\r
+static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue );\r
 \r
 /*\r
  * Checks the basic operation of a recursive mutex after it has been created.\r
  */\r
-static void prvCheckRecursiveSemaphoreFunction( SemaphoreHandle_t xSemaphore );\r
+static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore );\r
 \r
 /*\r
  * Checks the basic operation of a binary semaphore after it has been created.\r
  */\r
-static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount );\r
+static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount );\r
+\r
+/*\r
+ * Checks the basic operation of an event group after it has been created.\r
+ */\r
+static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
-/* StaticTCB_t is a publicly accessible structure that has the same size and\r
+/* StaticTask_t is a publicly accessible structure that has the same size and\r
 alignment requirements as the real TCB structure.  It is provided as a mechanism\r
 for applications to know the size of the TCB (which is dependent on the\r
 architecture and configuration file settings) without breaking the strict data\r
-hiding policy by exposing the real TCB.  This StaticTCB_t variable is passed\r
+hiding policy by exposing the real TCB.  This StaticTask_t variable is passed\r
 into the xTaskCreateStatic() function that creates the\r
 prvStaticallyAllocatedCreator() task, and will hold the TCB of the created\r
 tasks. */\r
-static StaticTCB_t xCreatorTaskTCBBuffer;\r
+static StaticTask_t xCreatorTaskTCBBuffer;\r
 \r
 /* This is the stack that will be used by the prvStaticallyAllocatedCreator()\r
 task, which is itself created using statically allocated buffers (so without any\r
 dynamic memory allocation). */\r
-static StackType_t uxCreatorTaskStackBuffer[ configMINIMAL_STACK_SIZE ];\r
+static StackType_t uxCreatorTaskStackBuffer[ staticCREATOR_TASK_STACK_SIZE ];\r
 \r
 /* Used by the pseudo random number generating function. */\r
 static uint32_t ulNextRand = 0;\r
@@ -215,18 +238,17 @@ stalled. */
 static volatile UBaseType_t uxCycleCounter = 0;\r
 \r
 /* A variable that gets set to pdTRUE if an error is detected. */\r
-static BaseType_t xErrorOccurred = pdFALSE;\r
+static volatile BaseType_t xErrorOccurred = pdFALSE;\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
 void vStartStaticallyAllocatedTasks( void  )\r
 {\r
-       /* Create a single task, which then repeatedly creates and deletes the\r
-       task implemented by prvStaticallyAllocatedTask() at various different\r
-       priorities, and both with and without statically allocated TCB and stack. */\r
-       xTaskCreateStatic( prvStaticallyAllocatedCreator,       /* The function that implements the task being created. */\r
+       /* Create a single task, which then repeatedly creates and deletes the other\r
+       RTOS objects using both statically and dynamically allocated RAM. */\r
+       xTaskCreateStatic( prvStaticallyAllocatedCreator,               /* The function that implements the task being created. */\r
                                           "StatCreate",                                                /* Text name for the task - not used by the RTOS, its just to assist debugging. */\r
-                                          configMINIMAL_STACK_SIZE,                    /* Size of the buffer passed in as the stack - in words, not bytes! */\r
+                                          staticCREATOR_TASK_STACK_SIZE,               /* Size of the buffer passed in as the stack - in words, not bytes! */\r
                                           NULL,                                                                /* Parameter passed into the task - not used in this case. */\r
                                           staticTASK_PRIORITY,                                 /* Priority of the task. */\r
                                           NULL,                                                                /* Handle of the task being created, not used in this case. */\r
@@ -245,201 +267,32 @@ static void prvStaticallyAllocatedCreator( void *pvParameters )
 \r
        for( ;; )\r
        {\r
-               /* Loop, running functions that create and delete the various objects\r
-               that can be optionally created using either static or dynamic memory\r
-               allocation. */\r
+               /* Loop, running functions that create and delete the various RTOS\r
+               objects that can be optionally created using either static or dynamic\r
+               memory allocation. */\r
                prvCreateAndDeleteStaticallyAllocatedTasks();\r
                prvCreateAndDeleteStaticallyAllocatedQueues();\r
-               prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();\r
-               prvCreateAndDeleteStaticallyAllocatedCountingSemaphores();\r
-               prvCreateAndDeleteStaticallyAllocatedMutexes();\r
-               prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes();\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
-{\r
-BaseType_t xReturned;\r
-UBaseType_t x;\r
-const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );\r
-TickType_t xTickCount;\r
-\r
-       /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()\r
-       should fail. */\r
-       xTickCount = xTaskGetTickCount();\r
-       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
-\r
-       if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )\r
-       {\r
-               /* Did not block on the semaphore as long as expected. */\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount\r
-       times. */\r
-       for( x = 0; x < uxMaxCount; x++ )\r
-       {\r
-               xReturned = xSemaphoreGive( xSemaphore );\r
-\r
-               if( xReturned == pdFAIL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* Giving the semaphore again should fail, as it is 'full'. */\r
-       xReturned = xSemaphoreGive( xSemaphore );\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );\r
-\r
-       /* Should now be possible to 'take' the semaphore up to a maximum of\r
-       uxMaxCount times without blocking. */\r
-       for( x = 0; x < uxMaxCount; x++ )\r
-       {\r
-               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
-\r
-               if( xReturned == pdFAIL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-\r
-       /* Back to the starting condition, where the semaphore should not be\r
-       available. */\r
-       xTickCount = xTaskGetTickCount();\r
-       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
-\r
-       if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )\r
-       {\r
-               /* Did not block on the semaphore as long as expected. */\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-\r
-       configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckQueueFunction( QueueHandle_t xQueue )\r
-{\r
-uint64_t ull, ullRead;\r
-BaseType_t xReturned, xLoop;\r
-\r
-       /* This test is done twice to ensure the queue storage area wraps. */\r
-       for( xLoop = 0; xLoop < 2; xLoop++ )\r
-       {\r
-               /* A very basic test that the queue can be written to and read from as\r
-               expected.  First the queue should be empty. */\r
-               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_EMPTY )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-\r
-               /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS\r
-               times. */\r
-               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
-               {\r
-                       xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
-                       if( xReturned != pdPASS )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-               }\r
-\r
-               /* Should not now be possible to write to the queue again. */\r
-               xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_FULL )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-\r
-               /* Now read back from the queue to ensure the data read back matches that\r
-               written. */\r
-               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
-               {\r
-                       xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );\r
-\r
-                       if( xReturned != pdPASS )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-\r
-                       if( ullRead != ull )\r
-                       {\r
-                               xErrorOccurred = pdTRUE;\r
-                       }\r
-               }\r
-\r
-               /* The queue should be empty again. */\r
-               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
-               if( xReturned != errQUEUE_EMPTY )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCheckRecursiveSemaphoreFunction( SemaphoreHandle_t xSemaphore )\r
-{\r
-const BaseType_t xLoops = 5;\r
-BaseType_t x, xReturned;\r
-\r
-       /* A very basic test that the recursive semaphore behaved like a recursive\r
-       semaphore. First the semaphore should not be able to be given, as it has not\r
-       yet been taken. */\r
-       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
-\r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
 \r
-       /* Now it should be possible to take the mutex a number of times. */\r
-       for( x = 0; x < xLoops; x++ )\r
-       {\r
-               xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );\r
+               /* Delay to ensure lower priority tasks get CPU time, and increment the\r
+               cycle counter so a 'check' task can determine that this task is still\r
+               executing. */\r
+               vTaskDelay( prvGetNextDelayTime() );\r
+               uxCycleCounter++;\r
 \r
-               if( xReturned != pdPASS )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
+               prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();\r
+               prvCreateAndDeleteStaticallyAllocatedCountingSemaphores();\r
 \r
-       /* Should be possible to give the semaphore the same number of times as it\r
-       was given in the loop above. */\r
-       for( x = 0; x < xLoops; x++ )\r
-       {\r
-               xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+               vTaskDelay( prvGetNextDelayTime() );\r
+               uxCycleCounter++;\r
 \r
-               if( xReturned != pdPASS )\r
-               {\r
-                       xErrorOccurred = pdTRUE;\r
-               }\r
-       }\r
+               prvCreateAndDeleteStaticallyAllocatedMutexes();\r
+               prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes();\r
 \r
-       /* No more gives should be possible though. */\r
-       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+               vTaskDelay( prvGetNextDelayTime() );\r
+               uxCycleCounter++;\r
 \r
-       if( xReturned != pdFAIL )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
+               prvCreateAndDeleteStaticallyAllocatedEventGroups();\r
+               prvCreateAndDeleteStaticallyAllocatedTimers();\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -458,10 +311,10 @@ StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic()
 function calls within this function.  NOTE: In most usage scenarios now it is\r
 faster and more memory efficient to use a direct to task notification instead of\r
 a counting semaphore.  http://www.freertos.org/RTOS-task-notifications.html */\r
-static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */\r
+StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateCountingStatic() has one more\r
-       parameter than the usual xSemaphoreCreateCounting() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateCounting() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -473,29 +326,22 @@ static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much
        configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );\r
 \r
        /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, uxMaxCount );\r
-\r
-       /* Delete the semaphore again so the buffers can be reused. */\r
-       vSemaphoreDelete( xSemaphore );\r
-\r
-\r
-       /* The semaphore created above had a statically allocated semaphore\r
-       structure.  Repeat the above using NULL as the third\r
-       xSemaphoreCreateCountingStatic() parameter so the semaphore structure is\r
-       instead allocated dynamically. */\r
-       xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, NULL );\r
-\r
-       /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, uxMaxCount );\r
+       prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );\r
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
 \r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               /* Now do the same but using dynamically allocated buffers to ensure the\r
+               delete functions are working correctly in both the static and dynamic\r
+               allocation cases. */\r
+               xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 );\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -510,7 +356,7 @@ on the architecture and configuration file settings) without breaking the strict
 data hiding policy by exposing the real semaphore internals.  This\r
 StaticSemaphore_t variable is passed into the\r
 xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */\r
-static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */\r
+StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateRecursiveMutexStatic() has one\r
        more parameter than the usual xSemaphoreCreateRecursiveMutex() function.\r
@@ -526,29 +372,22 @@ static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much
 \r
        /* Ensure the semaphore passes a few sanity checks as a valid\r
        recursive semaphore. */\r
-       prvCheckRecursiveSemaphoreFunction( xSemaphore );\r
-\r
-       /* Delete the semaphore again so the buffers can be reused. */\r
-       vSemaphoreDelete( xSemaphore );\r
-\r
-\r
-       /* The semaphore created above had a statically allocated semaphore\r
-       structure.  Repeat the above using NULL as the\r
-       xSemaphoreCreateRecursiveMutexStatic() parameter so the semaphore structure\r
-       is instead allocated dynamically. */\r
-       xSemaphore = xSemaphoreCreateRecursiveMutexStatic( NULL );\r
-\r
-       /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckRecursiveSemaphoreFunction( xSemaphore );\r
+       prvSanityCheckCreatedRecursiveMutex( xSemaphore );\r
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
 \r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
+       /* Now do the same using dynamically allocated buffers to ensure the delete\r
+       functions are working correctly in both the static and dynamic memory\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xSemaphore = xSemaphoreCreateRecursiveMutex();\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedRecursiveMutex( xSemaphore );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -573,11 +412,11 @@ http://www.freertos.org/Embedded-RTOS-Queues.html */
 static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];\r
 \r
        /* Create the queue.  xQueueCreateStatic() has two more parameters than the\r
-       usual xQueueCreate() function.  The first new paraemter is a pointer to the\r
+       usual xQueueCreate() function.  The first new parameter is a pointer to the\r
        pre-allocated queue storage area.  The second new parameter is a pointer to\r
        the StaticQueue_t structure that will hold the queue state information in\r
-       an anonymous way.  If either pointer is passed as NULL then the respective\r
-       data will be allocated dynamically as if xQueueCreate() had been called. */\r
+       an anonymous way.  If the two pointers are passed as NULL then the data\r
+       will be allocated dynamically as if xQueueCreate() had been called. */\r
        xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
                                                                 sizeof( uint64_t ), /* The size of each item. */\r
                                                                 ucQueueStorageArea, /* The buffer used to hold items within the queue. */\r
@@ -588,59 +427,37 @@ static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_
        configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );\r
 \r
        /* Ensure the queue passes a few sanity checks as a valid queue. */\r
-       prvCheckQueueFunction( xQueue );\r
+       prvSanityCheckCreatedQueue( xQueue );\r
 \r
        /* Delete the queue again so the buffers can be reused. */\r
        vQueueDelete( xQueue );\r
 \r
+       /* Now do the same using a dynamically allocated queue to ensure the delete\r
+       function is working correctly in both the static and dynamic memory\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
+                                                          sizeof( uint64_t ) );                /* The size of each item. */\r
 \r
-       /* The queue created above had a statically allocated queue storage area and\r
-       queue structure.  Repeat the above with three more times - with different\r
-       combinations of static and dynamic allocation. */\r
-\r
-       xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
-                                                                sizeof( uint64_t ), /* The size of each item. */\r
-                                                                NULL,                           /* Allocate the buffer used to hold items within the queue dynamically. */\r
-                                                                &xStaticQueue );        /* The static queue structure that will hold the state of the queue. */\r
+               /* The queue handle should equal the static queue structure passed into the\r
+               xQueueCreateStatic() function. */\r
+               configASSERT( xQueue != NULL );\r
 \r
-       configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );\r
-       prvCheckQueueFunction( xQueue );\r
-       vQueueDelete( xQueue );\r
+               /* Ensure the queue passes a few sanity checks as a valid queue. */\r
+               prvSanityCheckCreatedQueue( xQueue );\r
 \r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
+               /* Delete the queue again so the buffers can be reused. */\r
+               vQueueDelete( xQueue );\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
-\r
-       xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
-                                                                sizeof( uint64_t ), /* The size of each item. */\r
-                                                                ucQueueStorageArea, /* The buffer used to hold items within the queue. */\r
-                                                                NULL );                         /* The queue structure is allocated dynamically. */\r
-\r
-       prvCheckQueueFunction( xQueue );\r
-       vQueueDelete( xQueue );\r
-\r
-       xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\r
-                                                                sizeof( uint64_t ), /* The size of each item. */\r
-                                                                NULL,                           /* Allocate the buffer used to hold items within the queue dynamically. */\r
-                                                                NULL );                         /* The queue structure is allocated dynamically. */\r
-\r
-       prvCheckQueueFunction( xQueue );\r
-       vQueueDelete( xQueue );\r
-\r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCreateAndDeleteStaticallyAllocatedMutexes( void )\r
-{\r
-SemaphoreHandle_t xSemaphore;\r
-BaseType_t xReturned;\r
+static void prvCreateAndDeleteStaticallyAllocatedMutexes( void )\r
+{\r
+SemaphoreHandle_t xSemaphore;\r
+BaseType_t xReturned;\r
 \r
 /* StaticSemaphore_t is a publicly accessible structure that has the same size\r
 and alignment requirements as the real semaphore structure.  It is provided as a\r
@@ -649,10 +466,10 @@ on the architecture and configuration file settings) without breaking the strict
 data hiding policy by exposing the real semaphore internals.  This\r
 StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic()\r
 function calls within this function. */\r
-static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */\r
+StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateMutexStatic() has one more\r
-       parameter than the usual xSemaphoreCreateMutex() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateMutex() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -664,7 +481,7 @@ static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much
        configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );\r
 \r
        /* Take the mutex so the mutex is in the state expected by the\r
-       prvCheckSemaphoreFunction() function. */\r
+       prvSanityCheckCreatedSemaphore() function. */\r
        xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
 \r
        if( xReturned != pdPASS )\r
@@ -673,37 +490,38 @@ static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much
        }\r
 \r
        /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+       prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
 \r
-\r
-       /* The semaphore created above had a statically allocated semaphore\r
-       structure.  Repeat the above using NULL as the xSemaphoreCreateMutexStatic()\r
-       parameter so the semaphore structure is instead allocated dynamically. */\r
-       xSemaphore = xSemaphoreCreateMutexStatic( NULL );\r
-\r
-       /* Take the mutex so the mutex is in the state expected by the\r
-       prvCheckSemaphoreFunction() function. */\r
-       xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
-\r
-       if( xReturned != pdPASS )\r
+       /* Now do the same using a dynamically allocated mutex to ensure the delete\r
+       function is working correctly in both the static and dynamic allocation\r
+       cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
        {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
+               xSemaphore = xSemaphoreCreateMutex();\r
 \r
-       /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+               /* The semaphore handle should equal the static semaphore structure\r
+               passed into the xSemaphoreCreateMutexStatic() function. */\r
+               configASSERT( xSemaphore != NULL );\r
 \r
-       /* Delete the semaphore again so the buffers can be reused. */\r
-       vSemaphoreDelete( xSemaphore );\r
+               /* Take the mutex so the mutex is in the state expected by the\r
+               prvSanityCheckCreatedSemaphore() function. */\r
+               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
 \r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
+               /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
 \r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
+               /* Delete the semaphore again so the buffers can be reused. */\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -720,10 +538,10 @@ StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic()
 function calls within this function.  NOTE: In most usage scenarios now it is\r
 faster and more memory efficient to use a direct to task notification instead of\r
 a binary semaphore.  http://www.freertos.org/RTOS-task-notifications.html */\r
-static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */\r
+StaticSemaphore_t xSemaphoreBuffer;\r
 \r
        /* Create the semaphore.  xSemaphoreCreateBinaryStatic() has one more\r
-       parameter than the usual xSemaphoreCreateBinary() function.  The paraemter\r
+       parameter than the usual xSemaphoreCreateBinary() function.  The parameter\r
        is a pointer to the pre-allocated StaticSemaphore_t structure, which will\r
        hold information on the semaphore in an anonymous way.  If the pointer is\r
        passed as NULL then the structure will be allocated dynamically, just as\r
@@ -735,46 +553,220 @@ static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much
        configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );\r
 \r
        /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+       prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
 \r
        /* Delete the semaphore again so the buffers can be reused. */\r
        vSemaphoreDelete( xSemaphore );\r
 \r
+       /* Now do the same using a dynamically allocated semaphore to check the\r
+       delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xSemaphore = xSemaphoreCreateBinary();\r
+               configASSERT( xSemaphore != NULL );\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
 \r
-       /* The semaphore created above had a statically allocated semaphore\r
-       structure.  Repeat the above using NULL as the xSemaphoreCreateBinaryStatic()\r
-       parameter so the semaphore structure is instead allocated dynamically. */\r
-       xSemaphore = xSemaphoreCreateBinaryStatic( NULL );\r
+       /* There isn't a static version of the old and deprecated\r
+       vSemaphoreCreateBinary() macro (because its deprecated!), but check it is\r
+       still functioning correctly. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               vSemaphoreCreateBinary( xSemaphore );\r
 \r
-       /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
-       prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+               /* The macro starts with the binary semaphore available, but the test\r
+               function expects it to be unavailable. */\r
+               if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
 \r
-       /* Delete the semaphore again so the buffers can be reused. */\r
-       vSemaphoreDelete( xSemaphore );\r
+               prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+               vSemaphoreDelete( xSemaphore );\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
+static void prvTimerCallback( TimerHandle_t xExpiredTimer )\r
+{\r
+UBaseType_t *puxVariableToIncrement;\r
+BaseType_t xReturned;\r
 \r
+       /* The timer callback just demonstrates it is executing by incrementing a\r
+       variable - the address of which is passed into the timer as its ID.  Obtain\r
+       the address of the variable to increment. */\r
+       puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );\r
 \r
-       /* There isn't a static version of the old and deprecated\r
-       vSemaphoreCreateBinary() macro (because its deprecated!), but check it is\r
-       still functioning correctly when configSUPPORT_STATIC_ALLOCATION is set to\r
-       1. */\r
-       vSemaphoreCreateBinary( xSemaphore );\r
+       /* Increment the variable to show the timer callback has executed. */\r
+       ( *puxVariableToIncrement )++;\r
 \r
-       /* The macro starts with the binary semaphore available, but the test\r
-       function expects it to be unavailable. */\r
-       if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )\r
+       /* If this callback has executed the required number of times, stop the\r
+       timer. */\r
+       if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
+       {\r
+               /* This is called from a timer callback so must not block.  See\r
+               http://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */\r
+               xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateAndDeleteStaticallyAllocatedTimers( void )\r
+{\r
+TimerHandle_t xTimer;\r
+UBaseType_t uxVariableToIncrement;\r
+const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 );\r
+BaseType_t xReturned;\r
+\r
+/* StaticTimer_t is a publicly accessible structure that has the same size\r
+and alignment requirements as the real timer structure.  It is provided as a\r
+mechanism for applications to know the size of the timer structure (which is\r
+dependent on the architecture and configuration file settings) without breaking\r
+the strict data hiding policy by exposing the real timer internals.  This\r
+StaticTimer_t variable is passed into the xTimerCreateStatic() function calls\r
+within this function. */\r
+StaticTimer_t xTimerBuffer;\r
+\r
+       /* Create the software time.  xTimerCreateStatic() has an extra parameter\r
+       than the normal xTimerCreate() API function.  The parameter is a pointer to\r
+       the StaticTimer_t structure that will hold the software timer structure.  If\r
+       the parameter is passed as NULL then the structure will be allocated\r
+       dynamically, just as if xTimerCreate() had been called. */\r
+       xTimer = xTimerCreateStatic( "T1",                                      /* Text name for the task.  Helps debugging only.  Not used by FreeRTOS. */\r
+                                                                xTimerPeriod,                  /* The period of the timer in ticks. */\r
+                                                                pdTRUE,                                /* This is an auto-reload timer. */\r
+                                                                ( void * ) &uxVariableToIncrement,     /* The variable incremented by the test is passed into the timer callback using the timer ID. */\r
+                                                                prvTimerCallback,              /* The function to execute when the timer expires. */\r
+                                                                &xTimerBuffer );               /* The buffer that will hold the software timer structure. */\r
+\r
+       /* The timer handle should equal the static timer structure passed into the\r
+       xTimerCreateStatic() function. */\r
+       configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer );\r
+\r
+       /* Set the variable to 0, wait for a few timer periods to expire, then check\r
+       the timer callback has incremented the variable to the expected value. */\r
+       uxVariableToIncrement = 0;\r
+\r
+       /* This is a low priority so a block time should not be needed. */\r
+       xReturned = xTimerStart( xTimer, staticDONT_BLOCK );\r
+\r
+       if( xReturned != pdPASS )\r
        {\r
                xErrorOccurred = pdTRUE;\r
        }\r
 \r
-       prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
-       vSemaphoreDelete( xSemaphore );\r
+       vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
 \r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
+       /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS\r
+       times, and then stopped itself. */\r
+       if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Finished with the timer, delete it. */\r
+       xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );\r
+\r
+       /* Again, as this is a low priority task it is expected that the timer\r
+       command will have been sent even without a block time being used. */\r
+       if( xReturned != pdPASS )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
 \r
        /* Just to show the check task that this task is still executing. */\r
        uxCycleCounter++;\r
+\r
+       /* Now do the same using a dynamically allocated software timer to ensure\r
+       the delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xTimer = xTimerCreate( "T1",                                                            /* Text name for the task.  Helps debugging only.  Not used by FreeRTOS. */\r
+                                                           xTimerPeriod,                                               /* The period of the timer in ticks. */\r
+                                                               pdTRUE,                                                         /* This is an auto-reload timer. */\r
+                                                               ( void * ) &uxVariableToIncrement,      /* The variable incremented by the test is passed into the timer callback using the timer ID. */\r
+                                                               prvTimerCallback );                                     /* The function to execute when the timer expires. */\r
+\r
+               configASSERT( xTimer != NULL );\r
+\r
+               uxVariableToIncrement = 0;\r
+               xReturned = xTimerStart( xTimer, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
+\r
+               if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void )\r
+{\r
+EventGroupHandle_t xEventGroup;\r
+\r
+/* StaticEventGroup_t is a publicly accessible structure that has the same size\r
+and alignment requirements as the real event group structure.  It is provided as\r
+a mechanism for applications to know the size of the event group (which is\r
+dependent on the architecture and configuration file settings) without breaking\r
+the strict data hiding policy by exposing the real event group internals.  This\r
+StaticEventGroup_t variable is passed into the xSemaphoreCreateEventGroupStatic()\r
+function calls within this function. */\r
+StaticEventGroup_t xEventGroupBuffer;\r
+\r
+       /* Create the event group.  xEventGroupCreateStatic() has an extra parameter\r
+       than the normal xEventGroupCreate() API function.  The parameter is a\r
+       pointer to the StaticEventGroup_t structure that will hold the event group\r
+       structure.  If the parameter is passed as NULL then the structure will be\r
+       allocated dynamically, just as if xEventGroupCreate() had been called. */\r
+       xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );\r
+\r
+       /* The event group handle should equal the static event group structure\r
+       passed into the xEventGroupCreateStatic() function. */\r
+       configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer );\r
+\r
+       /* Ensure the event group passes a few sanity checks as a valid event\r
+       group. */\r
+       prvSanityCheckCreatedEventGroup( xEventGroup );\r
+\r
+       /* Delete the event group again so the buffers can be reused. */\r
+       vEventGroupDelete( xEventGroup );\r
+\r
+       /* Now do the same using a dynamically allocated event group to ensure the\r
+       delete function is working correctly in both the static and dynamic\r
+       allocation cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
+       {\r
+               xEventGroup = xEventGroupCreate();\r
+               configASSERT( xEventGroup != NULL );\r
+               prvSanityCheckCreatedEventGroup( xEventGroup );\r
+               vEventGroupDelete( xEventGroup );\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -786,7 +778,7 @@ BaseType_t xReturned;
 /* The variable that will hold the TCB of tasks created by this function.  See\r
 the comments above the declaration of the xCreatorTaskTCBBuffer variable for\r
 more information. */\r
-static StaticTCB_t xTCBBuffer; /* Static so it does not use too much stack space. */\r
+StaticTask_t xTCBBuffer;\r
 \r
 /* This buffer that will be used as the stack of tasks created by this function.\r
 See the comments above the declaration of the uxCreatorTaskStackBuffer[] array\r
@@ -796,42 +788,27 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
        /* Create the task.  xTaskCreateStatic() has two more parameters than\r
        the usual xTaskCreate() function.  The first new parameter is a pointer to\r
        the pre-allocated stack.  The second new parameter is a pointer to the\r
-       StaticTCB_t structure that will hold the task's TCB.  If either pointer is\r
+       StaticTask_t structure that will hold the task's TCB.  If both pointers are\r
        passed as NULL then the respective object will be allocated dynamically as\r
        if xTaskCreate() had been called. */\r
        xReturned = xTaskCreateStatic(\r
-                                               prvStaticallyAllocatedTask, /* Function that implements the task. */\r
-                                               "Static",                                       /* Human readable name for the task. */\r
-                                               configMINIMAL_STACK_SIZE,       /* Task's stack size, in words (not bytes!). */\r
-                                               NULL,                                           /* Parameter to pass into the task. */\r
-                                               tskIDLE_PRIORITY,                       /* The priority of the task. */\r
-                                               &xCreatedTask,                          /* Handle of the task being created. */\r
-                                               &( uxStackBuffer[ 0 ] ),        /* The buffer to use as the task's stack. */\r
-                                               &xTCBBuffer );                          /* The variable that will hold that task's TCB. */\r
-\r
-       /* Check the task was created correctly, then delete the task. */\r
-       configASSERT( xReturned == pdPASS );\r
-       if( xReturned != pdPASS )\r
+                                               prvStaticallyAllocatedTask,     /* Function that implements the task. */\r
+                                               "Static",                                               /* Human readable name for the task. */\r
+                                               configMINIMAL_STACK_SIZE,               /* Task's stack size, in words (not bytes!). */\r
+                                               NULL,                                                   /* Parameter to pass into the task. */\r
+                                               uxTaskPriorityGet( NULL ) + 1,  /* The priority of the task. */\r
+                                               &xCreatedTask,                                  /* Handle of the task being created. */\r
+                                               &( uxStackBuffer[ 0 ] ),                /* The buffer to use as the task's stack. */\r
+                                               &xTCBBuffer );                                  /* The variable that will hold that task's TCB. */\r
+\r
+       /* The created task had a higher priority so should have executed and\r
+       suspended itself by now. */\r
+       if( eTaskGetState( xCreatedTask ) != eSuspended )\r
        {\r
                xErrorOccurred = pdTRUE;\r
        }\r
-       vTaskDelete( xCreatedTask );\r
-\r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       /* Create and delete the task a few times again - testing both static and\r
-       dynamic allocation for the stack and TCB. */\r
-       xReturned = xTaskCreateStatic(\r
-                                               prvStaticallyAllocatedTask, /* Function that implements the task. */\r
-                                               "Static",                                       /* Human readable name for the task. */\r
-                                               configMINIMAL_STACK_SIZE,       /* Task's stack size, in words (not bytes!). */\r
-                                               NULL,                                           /* Parameter to pass into the task. */\r
-                                               staticTASK_PRIORITY + 1,        /* The priority of the task. */\r
-                                               &xCreatedTask,                          /* Handle of the task being created. */\r
-                                               NULL,                                           /* This time, dynamically allocate the stack. */\r
-                                               &xTCBBuffer );                          /* The variable that will hold that task's TCB. */\r
 \r
+       /* Check the task was created correctly, then delete the task. */\r
        configASSERT( xReturned == pdPASS );\r
        if( xReturned != pdPASS )\r
        {\r
@@ -839,54 +816,32 @@ static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
        }\r
        vTaskDelete( xCreatedTask );\r
 \r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
-\r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       xReturned = xTaskCreateStatic(\r
-                                               prvStaticallyAllocatedTask, /* Function that implements the task. */\r
-                                               "Static",                                       /* Human readable name for the task. */\r
-                                               configMINIMAL_STACK_SIZE,       /* Task's stack size, in words (not bytes!). */\r
-                                               NULL,                                           /* Parameter to pass into the task. */\r
-                                               staticTASK_PRIORITY - 1,        /* The priority of the task. */\r
-                                               &xCreatedTask,                          /* Handle of the task being created. */\r
-                                               &( uxStackBuffer[ 0 ] ),        /* The buffer to use as the task's stack. */\r
-                                               NULL );                                         /* This time dynamically allocate the TCB. */\r
-\r
-       configASSERT( xReturned == pdPASS );\r
-       if( xReturned != pdPASS )\r
+       /* Now do the same using a dynamically allocated task to ensure the delete\r
+       function is working correctly in both the static and dynamic allocation\r
+       cases. */\r
+       #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
        {\r
-               xErrorOccurred = pdTRUE;\r
-       }\r
-       vTaskDelete( xCreatedTask );\r
-\r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       xReturned = xTaskCreateStatic(\r
-                                               prvStaticallyAllocatedTask, /* Function that implements the task. */\r
-                                               "Static",                                       /* Human readable name for the task. */\r
-                                               configMINIMAL_STACK_SIZE,       /* Task's stack size, in words (not bytes!). */\r
-                                               NULL,                                           /* Parameter to pass into the task. */\r
-                                               staticTASK_PRIORITY,            /* The priority of the task. */\r
-                                               &xCreatedTask,                          /* Handle of the task being created. */\r
-                                               NULL,                                           /* This time dynamically allocate the stack and TCB. */\r
-                                               NULL );                                         /* This time dynamically allocate the stack and TCB. */\r
+               xReturned = xTaskCreate(\r
+                                                                       prvStaticallyAllocatedTask,             /* Function that implements the task. */\r
+                                                                       "Static",                                               /* Human readable name for the task. */\r
+                                                                       configMINIMAL_STACK_SIZE,               /* Task's stack size, in words (not bytes!). */\r
+                                                                       NULL,                                                   /* Parameter to pass into the task. */\r
+                                                                       uxTaskPriorityGet( NULL ) + 1,  /* The priority of the task. */\r
+                                                                       &xCreatedTask );                                /* Handle of the task being created. */\r
+\r
+               if( eTaskGetState( xCreatedTask ) != eSuspended )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
 \r
-       configASSERT( xReturned == pdPASS );\r
-       if( xReturned != pdPASS )\r
-       {\r
-               xErrorOccurred = pdTRUE;\r
+               configASSERT( xReturned == pdPASS );\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+               vTaskDelete( xCreatedTask );\r
        }\r
-       vTaskDelete( xCreatedTask );\r
-\r
-       /* Ensure lower priority tasks get CPU time. */\r
-       vTaskDelay( prvGetNextDelayTime() );\r
-\r
-       /* Just to show the check task that this task is still executing. */\r
-       uxCycleCounter++;\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -894,7 +849,9 @@ static void prvStaticallyAllocatedTask( void *pvParameters )
 {\r
        ( void ) pvParameters;\r
 \r
-       /* The created task doesn't do anything - just waits to get deleted. */\r
+       /* The created task just suspends itself to wait to get deleted.  The task\r
+       that creates this task checks this task is in the expected Suspended state\r
+       before deleting it. */\r
        vTaskSuspend( NULL );\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -932,6 +889,237 @@ const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )\r
+{\r
+EventBits_t xEventBits;\r
+const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;\r
+\r
+       /* The event group should not have any bits set yet. */\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != ( EventBits_t ) 0 )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Some some bits, then read them back to check they are as expected. */\r
+       xEventGroupSetBits( xEventGroup, xFirstTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != xFirstTestBits )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       xEventGroupSetBits( xEventGroup, xSecondTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Finally try clearing some bits too and check that operation proceeds as\r
+       expected. */\r
+       xEventGroupClearBits( xEventGroup, xFirstTestBits );\r
+\r
+       xEventBits = xEventGroupGetBits( xEventGroup );\r
+\r
+       if( xEventBits != xSecondTestBits )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
+{\r
+BaseType_t xReturned;\r
+UBaseType_t x;\r
+const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );\r
+TickType_t xTickCount;\r
+\r
+       /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()\r
+       should fail. */\r
+       xTickCount = xTaskGetTickCount();\r
+       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
+\r
+       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
+       {\r
+               /* Did not block on the semaphore as long as expected. */\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount\r
+       times. */\r
+       for( x = 0; x < uxMaxCount; x++ )\r
+       {\r
+               xReturned = xSemaphoreGive( xSemaphore );\r
+\r
+               if( xReturned == pdFAIL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Giving the semaphore again should fail, as it is 'full'. */\r
+       xReturned = xSemaphoreGive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );\r
+\r
+       /* Should now be possible to 'take' the semaphore up to a maximum of\r
+       uxMaxCount times without blocking. */\r
+       for( x = 0; x < uxMaxCount; x++ )\r
+       {\r
+               xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned == pdFAIL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Back to the starting condition, where the semaphore should not be\r
+       available. */\r
+       xTickCount = xTaskGetTickCount();\r
+       xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );\r
+\r
+       if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime )\r
+       {\r
+               /* Did not block on the semaphore as long as expected. */\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue )\r
+{\r
+uint64_t ull, ullRead;\r
+BaseType_t xReturned, xLoop;\r
+\r
+       /* This test is done twice to ensure the queue storage area wraps. */\r
+       for( xLoop = 0; xLoop < 2; xLoop++ )\r
+       {\r
+               /* A very basic test that the queue can be written to and read from as\r
+               expected.  First the queue should be empty. */\r
+               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_EMPTY )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS\r
+               times. */\r
+               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
+               {\r
+                       xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
+                       if( xReturned != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* Should not now be possible to write to the queue again. */\r
+               xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_FULL )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+\r
+               /* Now read back from the queue to ensure the data read back matches that\r
+               written. */\r
+               for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )\r
+               {\r
+                       xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );\r
+\r
+                       if( xReturned != pdPASS )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+\r
+                       if( ullRead != ull )\r
+                       {\r
+                               xErrorOccurred = pdTRUE;\r
+                       }\r
+               }\r
+\r
+               /* The queue should be empty again. */\r
+               xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );\r
+               if( xReturned != errQUEUE_EMPTY )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )\r
+{\r
+const BaseType_t xLoops = 5;\r
+BaseType_t x, xReturned;\r
+\r
+       /* A very basic test that the recursive semaphore behaved like a recursive\r
+       semaphore. First the semaphore should not be able to be given, as it has not\r
+       yet been taken. */\r
+       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+\r
+       /* Now it should be possible to take the mutex a number of times. */\r
+       for( x = 0; x < xLoops; x++ )\r
+       {\r
+               xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* Should be possible to give the semaphore the same number of times as it\r
+       was given in the loop above. */\r
+       for( x = 0; x < xLoops; x++ )\r
+       {\r
+               xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+               if( xReturned != pdPASS )\r
+               {\r
+                       xErrorOccurred = pdTRUE;\r
+               }\r
+       }\r
+\r
+       /* No more gives should be possible though. */\r
+       xReturned = xSemaphoreGiveRecursive( xSemaphore );\r
+\r
+       if( xReturned != pdFAIL )\r
+       {\r
+               xErrorOccurred = pdTRUE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 BaseType_t xAreStaticAllocationTasksStillRunning( void )\r
 {\r
 static UBaseType_t uxLastCycleCounter = 0;\r