+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