/*\r
- FreeRTOS V8.2.3 - Copyright (C) 2015 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
- 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
- ***************************************************************************\r
- >>! NOTE: The modification to the GPL is included to allow you to !<<\r
- >>! distribute a combined work that includes FreeRTOS without being !<<\r
- >>! obliged to provide the source code for proprietary components !<<\r
- >>! outside of the FreeRTOS kernel. !<<\r
- ***************************************************************************\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 on the following\r
- link: http://www.freertos.org/a00114.html\r
-\r
- ***************************************************************************\r
- * *\r
- * FreeRTOS provides completely free yet professionally developed, *\r
- * robust, strictly quality controlled, supported, and cross *\r
- * platform software that is more than just the market leader, it *\r
- * is the industry's de facto standard. *\r
- * *\r
- * Help yourself get started quickly while simultaneously helping *\r
- * to support the FreeRTOS project by purchasing a FreeRTOS *\r
- * tutorial book, reference manual, or both: *\r
- * http://www.FreeRTOS.org/Documentation *\r
- * *\r
- ***************************************************************************\r
-\r
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading\r
- the FAQ page "My application does not run, what could be wrong?". Have you\r
- defined configASSERT()?\r
-\r
- http://www.FreeRTOS.org/support - In return for receiving this top quality\r
- embedded software for free we request you assist our global community by\r
- participating in the support forum.\r
-\r
- http://www.FreeRTOS.org/training - Investing in training allows your team to\r
- be as productive as possible as early as possible. Now you can receive\r
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
- Ltd, and the world's leading authority on the world's leading RTOS.\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.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
-\r
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS\r
- licenses offer ticketed support, indemnification and commercial 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
+ * FreeRTOS Kernel V10.1.0\r
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
+ *\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.\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
* 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
+ * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html\r
*/\r
\r
/* Scheduler include files. */\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 xEventGroupCreateStatic() API\r
- * function by creating and then deleting event groups using both dynamically\r
- * and statically allocated event group structures.\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 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 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 xTimerCreateStatic() API macro by\r
- * creating and then deleting software timers with both dynamically and\r
- * statically allocated timer 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 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 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
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
+ /* 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
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
&( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */\r
&xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */\r
-\r
- /* Pseudo seed the random number generator. */\r
- ulNextRand = ( uint32_t ) prvRand;\r
}\r
/*-----------------------------------------------------------*/\r
\r
\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
- prvCreateAndDeleteStaticallyAllocatedEventGroups();\r
- prvCreateAndDeleteStaticallyAllocatedTimers();\r
- }\r
-}\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( ( 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 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
+ /* 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
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
/* 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
- 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
/* 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
- 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
-}\r
-/*-----------------------------------------------------------*/\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
static void prvCreateAndDeleteStaticallyAllocatedQueues( void )\r
{\r
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
/* 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
-\r
- configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );\r
- prvSanityCheckCreatedQueue( 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
- 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
- prvSanityCheckCreatedQueue( 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
- prvSanityCheckCreatedQueue( xQueue );\r
- vQueueDelete( xQueue );\r
+ /* The queue handle should equal the static queue structure passed into the\r
+ xQueueCreateStatic() function. */\r
+ configASSERT( xQueue != NULL );\r
\r
- /* Ensure lower priority tasks get CPU time. */\r
- vTaskDelay( prvGetNextDelayTime() );\r
+ /* Ensure the queue passes a few sanity checks as a valid queue. */\r
+ prvSanityCheckCreatedQueue( xQueue );\r
\r
- /* Just to show the check task that this task is still executing. */\r
- uxCycleCounter++;\r
+ /* Delete the queue again so the buffers can be reused. */\r
+ vQueueDelete( xQueue );\r
+ }\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\r
\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
/* 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
- prvSanityCheckCreatedSemaphore() 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
- prvSanityCheckCreatedSemaphore( 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
- /* Ensure lower priority tasks get CPU time. */\r
- vTaskDelay( prvGetNextDelayTime() );\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
+ /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\r
+ prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+\r
+ /* Delete the semaphore again so the buffers can be reused. */\r
+ vSemaphoreDelete( xSemaphore );\r
+ }\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\r
\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
/* 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 xSemaphoreCreateBinaryStatic()\r
- parameter so the semaphore structure is instead allocated dynamically. */\r
- xSemaphore = xSemaphoreCreateBinaryStatic( NULL );\r
-\r
- /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */\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
+ /* 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
/* 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
-\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
+ still functioning correctly. */\r
+ #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )\r
{\r
- xErrorOccurred = pdTRUE;\r
- }\r
-\r
- prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
- vSemaphoreDelete( xSemaphore );\r
+ vSemaphoreCreateBinary( xSemaphore );\r
\r
- /* Ensure lower priority tasks get CPU time. */\r
- vTaskDelay( prvGetNextDelayTime() );\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
- /* Just to show the check task that this task is still executing. */\r
- uxCycleCounter++;\r
+ prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+ vSemaphoreDelete( xSemaphore );\r
+ }\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
UBaseType_t *puxVariableToIncrement;\r
BaseType_t xReturned;\r
\r
- /* Obtain the address of the variable to increment from the timer ID. */\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
/* Increment the variable to show the timer callback has executed. */\r
timer. */\r
if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
{\r
- /* This is called from a timer callback so must not block. */\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
/* Just to show the check task that this task is still executing. */\r
uxCycleCounter++;\r
\r
- /* The software timer created above had a statically allocated timer\r
- structure. Repeat the above using NULL as the xTimerCreateStatic()\r
- parameter so the timer structure is instead allocated dynamically. */\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
- NULL ); /* A buffer is not passed this time, so the timer should be allocated dynamically. */\r
- uxVariableToIncrement = 0;\r
- xReturned = xTimerStart( xTimer, staticDONT_BLOCK );\r
-\r
- if( xReturned != pdPASS )\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
- xErrorOccurred = pdTRUE;\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
- vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
+ configASSERT( xTimer != NULL );\r
\r
- /* Just to show the check task that this task is still executing. */\r
- uxCycleCounter++;\r
+ uxVariableToIncrement = 0;\r
+ xReturned = xTimerStart( xTimer, staticDONT_BLOCK );\r
\r
- if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
+ if( xReturned != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
\r
- xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );\r
+ vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
\r
- if( xReturned != pdPASS )\r
- {\r
- xErrorOccurred = pdTRUE;\r
- }\r
+ if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
\r
- /* Just to show the check task that this task is still executing. */\r
- uxCycleCounter++;\r
+ xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );\r
+\r
+ if( xReturned != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ }\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\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
+ structure. */\r
xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );\r
\r
/* The event group handle should equal the static event group structure\r
/* Delete the event group again so the buffers can be reused. */\r
vEventGroupDelete( xEventGroup );\r
\r
-\r
- /* The event group created above had a statically allocated event group\r
- structure. Repeat the above using NULL as the xEventGroupCreateStatic()\r
- parameter so the event group structure is instead allocated dynamically. */\r
- xEventGroup = xEventGroupCreateStatic( NULL );\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
- /* 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 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
static void prvCreateAndDeleteStaticallyAllocatedTasks( void )\r
{\r
TaskHandle_t xCreatedTask;\r
-BaseType_t xReturned;\r
\r
/* 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
/* 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
- StaticTask_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
+ xCreatedTask = 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
+ uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */\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
+ if( xCreatedTask == NULL )\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
- configASSERT( xReturned == pdPASS );\r
- if( xReturned != pdPASS )\r
+ else if( eTaskGetState( xCreatedTask ) != eSuspended )\r
{\r
+ /* The created task had a higher priority so should have executed and\r
+ suspended itself by now. */\r
xErrorOccurred = pdTRUE;\r
}\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
+ else\r
{\r
- xErrorOccurred = pdTRUE;\r
+ vTaskDelete( xCreatedTask );\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
-\r
- configASSERT( xReturned == pdPASS );\r
- if( xReturned != pdPASS )\r
+\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
+ BaseType_t xReturned;\r
\r
- /* Ensure lower priority tasks get CPU time. */\r
- vTaskDelay( prvGetNextDelayTime() );\r
+ xReturned = xTaskCreate(\r
+ prvStaticallyAllocatedTask, /* Function that implements the task - the same function is used but is actually dynamically allocated this time. */\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
- /* Just to show the check task that this task is still executing. */\r
- uxCycleCounter++;\r
+ if( eTaskGetState( xCreatedTask ) != eSuspended )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ configASSERT( xReturned == pdPASS );\r
+ if( xReturned != pdPASS )\r
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+ vTaskDelete( xCreatedTask );\r
+ }\r
+ #endif\r
}\r
/*-----------------------------------------------------------*/\r
\r
{\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
}\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