\r
/*\r
* Demonstrates how to create FreeRTOS objects using pre-allocated memory,\r
- * rather than the normal dynamically 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
+ * 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
\r
/* Scheduler include files. */\r
#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
/* 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
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
*/\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
+ */\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
*/\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
+ */\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
*/\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
/*\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
/* 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
+ 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
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 prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
+static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )\r
{\r
BaseType_t xReturned;\r
UBaseType_t x;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvCheckQueueFunction( QueueHandle_t xQueue )\r
+static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue )\r
{\r
uint64_t ull, ullRead;\r
BaseType_t xReturned, xLoop;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvCheckRecursiveSemaphoreFunction( SemaphoreHandle_t xSemaphore )\r
+static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )\r
{\r
const BaseType_t xLoops = 5;\r
BaseType_t x, xReturned;\r
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
configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );\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
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
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
\r
/* Ensure the semaphore passes a few sanity checks as a valid\r
recursive semaphore. */\r
- prvCheckRecursiveSemaphoreFunction( xSemaphore );\r
+ prvSanityCheckCreatedRecursiveMutex( xSemaphore );\r
\r
/* Delete the semaphore again so the buffers can be reused. */\r
vSemaphoreDelete( xSemaphore );\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
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
&xStaticQueue ); /* The static queue structure that will hold the state of the queue. */\r
\r
configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );\r
- prvCheckQueueFunction( xQueue );\r
+ prvSanityCheckCreatedQueue( xQueue );\r
vQueueDelete( xQueue );\r
\r
/* Ensure lower priority tasks get CPU time. */\r
ucQueueStorageArea, /* The buffer used to hold items within the queue. */\r
NULL ); /* The queue structure is allocated dynamically. */\r
\r
- prvCheckQueueFunction( xQueue );\r
+ prvSanityCheckCreatedQueue( xQueue );\r
vQueueDelete( xQueue );\r
\r
xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */\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
+ prvSanityCheckCreatedQueue( xQueue );\r
vQueueDelete( xQueue );\r
\r
/* Ensure lower priority tasks get CPU time. */\r
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
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
}\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
xSemaphore = xSemaphoreCreateMutexStatic( NULL );\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
}\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
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
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
xSemaphore = xSemaphoreCreateBinaryStatic( NULL );\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
xErrorOccurred = pdTRUE;\r
}\r
\r
- prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
+ prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );\r
vSemaphoreDelete( xSemaphore );\r
\r
/* Ensure lower priority tasks get CPU time. */\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvTimerCallback( TimerHandle_t xExpiredTimer )\r
+{\r
+UBaseType_t *puxVariableToIncrement;\r
+BaseType_t xReturned;\r
+\r
+ /* Obtain the address of the variable to increment from the timer ID. */\r
+ puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );\r
+\r
+ /* Increment the variable to show the timer callback has executed. */\r
+ ( *puxVariableToIncrement )++;\r
+\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. */\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
+ vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
+\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
+ /* 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
+ {\r
+ xErrorOccurred = pdTRUE;\r
+ }\r
+\r
+ vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );\r
+\r
+ /* Just to show the check task that this task is still executing. */\r
+ uxCycleCounter++;\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
+ /* Just to show the check task that this task is still executing. */\r
+ uxCycleCounter++;\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
+\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
+}\r
+/*-----------------------------------------------------------*/\r
+\r
static void prvCreateAndDeleteStaticallyAllocatedTasks( void )\r
{\r
TaskHandle_t xCreatedTask;\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
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
/* 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 either pointer is\r
passed as NULL then the respective object will be allocated dynamically as\r
if xTaskCreate() had been called. */\r
xReturned = xTaskCreateStatic(\r
} eDummy;\r
\r
/*\r
- * In line with software engineering best practice, FreeRTOS implements a strict\r
- * data hiding policy, so the real task control block (TCB) structure is not\r
- * accessible to the application code. However, if the application writer wants\r
- * to statically allocate a TCB then the size of the TCB needs to be know. The\r
- * dummy TCB structure below is used for this purpose. Its size will allows\r
- * match the size of the real TCB, no matter what the FreeRTOSConfig.h settings.\r
+ * In line with software engineering best practice, especially when supplying a\r
+ * library that is likely to change in future versions, FreeRTOS implements a\r
+ * strict data hiding policy. This means the Task structure used internally by\r
+ * FreeRTOS is not accessible to application code. However, if the application\r
+ * writer wants to statically allocate the memory required to create a task then\r
+ * the size of the task object needs to be know. The StaticTask_t structure\r
+ * below is provided for this purpose. Its sizes and alignment requirements are\r
+ * guaranteed to match those of the genuine structure, no matter which\r
+ * architecture is being used, and no matter how the values in FreeRTOSConfig.h\r
+ * are set. Its contents are somewhat obfuscated in the hope users will\r
+ * recognise that it would be unwise to make direct use of the structure members.\r
*/\r
typedef struct xSTATIC_TCB\r
{\r
uint8_t uxDummy20;\r
#endif\r
\r
-} StaticTCB_t;\r
+} StaticTask_t;\r
\r
/*\r
- * In line with software engineering best practice, FreeRTOS implements a strict\r
- * data hiding policy, so the queue structure is not accessible to the\r
- * application code. However, if the application writer wants to statically\r
- * allocate a queue (or one of the other objects that uses a queue as its base\r
- * structure) then the size of the queue needs to be know. The dummy queue\r
- * structure below is used for this purpose. Its size will allows match the\r
- * size of the real queue, no matter what the FreeRTOSConfig.h settings.\r
+ * In line with software engineering best practice, especially when supplying a\r
+ * library that is likely to change in future versions, FreeRTOS implements a\r
+ * strict data hiding policy. This means the Queue structure used internally by\r
+ * FreeRTOS is not accessible to application code. However, if the application\r
+ * writer wants to statically allocate the memory required to create a queue\r
+ * then the size of the queue object needs to be know. The StaticQueue_t\r
+ * structure below is provided for this purpose. Its sizes and alignment\r
+ * requirements are guaranteed to match those of the genuine structure, no\r
+ * matter which architecture is being used, and no matter how the values in\r
+ * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope\r
+ * users will recognise that it would be unwise to make direct use of the\r
+ * structure members.\r
*/\r
typedef struct xSTATIC_QUEUE\r
{\r
#endif\r
\r
} StaticQueue_t;\r
-\r
typedef StaticQueue_t StaticSemaphore_t;\r
\r
+/*\r
+ * In line with software engineering best practice, especially when supplying a\r
+ * library that is likely to change in future versions, FreeRTOS implements a\r
+ * strict data hiding policy. This means the event group structure used\r
+ * internally by FreeRTOS is not accessible to application code. However, if\r
+ * the application writer wants to statically allocate the memory required to\r
+ * create an event group then the size of the event group object needs to be\r
+ * know. The StaticEventGroup_t structure below is provided for this purpose.\r
+ * Its sizes and alignment requirements are guaranteed to match those of the\r
+ * genuine structure, no matter which architecture is being used, and no matter\r
+ * how the values in FreeRTOSConfig.h are set. Its contents are somewhat\r
+ * obfuscated in the hope users will recognise that it would be unwise to make\r
+ * direct use of the structure members.\r
+ */\r
+typedef struct xSTATIC_EVENT_GROUP\r
+{\r
+ TickType_t xDummy1;\r
+ StaticList_t xDummy2;\r
+\r
+ #if( configUSE_TRACE_FACILITY == 1 )\r
+ UBaseType_t uxDummy3;\r
+ #endif\r
+\r
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+ uint8_t ucStaticallyAllocated;\r
+ #endif\r
+\r
+} StaticEventGroup_t;\r
+\r
+/*\r
+ * In line with software engineering best practice, especially when supplying a\r
+ * library that is likely to change in future versions, FreeRTOS implements a\r
+ * strict data hiding policy. This means the software timer structure used\r
+ * internally by FreeRTOS is not accessible to application code. However, if\r
+ * the application writer wants to statically allocate the memory required to\r
+ * create a software timer then the size of the queue object needs to be know.\r
+ * The StaticTimer_t structure below is provided for this purpose. Its sizes\r
+ * and alignment requirements are guaranteed to match those of the genuine\r
+ * structure, no matter which architecture is being used, and no matter how the\r
+ * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in\r
+ * the hope users will recognise that it would be unwise to make direct use of\r
+ * the structure members.\r
+ */\r
+typedef struct xSTATIC_TIMER\r
+{\r
+ void *pvDummy1;\r
+ StaticListItem_t xDummy2;\r
+ TickType_t xDummy3;\r
+ UBaseType_t uxDummy4;\r
+ void *pvDummy5[ 2 ];\r
+ #if( configUSE_TRACE_FACILITY == 1 )\r
+ UBaseType_t uxDummy6;\r
+ #endif\r
+\r
+ #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+ uint8_t ucStaticallyAllocated;\r
+ #endif\r
+\r
+} StaticTimer_t;\r
\r
#ifdef __cplusplus\r
}\r