]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Demo/WIN32-MingW/main_full.c
Ensure both one-shot and auto-reload are written consistently with a hyphen in comments.
[freertos] / FreeRTOS / Demo / WIN32-MingW / main_full.c
index 312e67fa73ae07ac9d84c058cd7b4f4c97543f6e..718c1e1b0a86edcc052fc646f43a7855cdecd2ce 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * FreeRTOS Kernel V10.0.0\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2019 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
@@ -10,8 +10,7 @@
  * subject to the following conditions:\r
  *\r
  * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software. If you wish to use our Amazon\r
- * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
+ * 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
@@ -47,7 +46,7 @@
  * in main.c.  This file implements the comprehensive test and demo version.\r
  *\r
  * NOTE 3:  This file only contains the source code that is specific to the\r
- * basic demo.  Generic functions, such FreeRTOS hook functions, are defined in\r
+ * full demo.  Generic functions, such FreeRTOS hook functions, are defined in\r
  * main.c.\r
  *******************************************************************************\r
  *\r
 \r
 /* Kernel includes. */\r
 #include <FreeRTOS.h>\r
-#include "task.h"\r
-#include "queue.h"\r
-#include "timers.h"\r
-#include "semphr.h"\r
+#include <task.h>\r
+#include <queue.h>\r
+#include <timers.h>\r
+#include <semphr.h>\r
 \r
 /* Standard demo includes. */\r
 #include "BlockQ.h"\r
 #include "IntSemTest.h"\r
 #include "TaskNotify.h"\r
 #include "QueueSetPolling.h"\r
+#include "StaticAllocation.h"\r
 #include "blocktim.h"\r
 #include "AbortDelay.h"\r
 #include "MessageBufferDemo.h"\r
 #include "StreamBufferDemo.h"\r
+#include "StreamBufferInterrupt.h"\r
+#include "MessageBufferAMP.h"\r
 \r
 /* Priorities at which the tasks are created. */\r
 #define mainCHECK_TASK_PRIORITY                        ( configMAX_PRIORITIES - 2 )\r
 \r
 #define mainTIMER_TEST_PERIOD                  ( 50 )\r
 \r
+/*\r
+ * Exercises code that is not otherwise covered by the standard demo/test\r
+ * tasks.\r
+ */\r
+extern BaseType_t xRunCodeCoverageTestAdditions( void );\r
+\r
 /* Task function prototypes. */\r
 static void prvCheckTask( void *pvParameters );\r
 \r
@@ -163,6 +171,13 @@ static void prvDemoQueueSpaceFunctions( void *pvParameters );
 static void prvPermanentlyBlockingSemaphoreTask( void *pvParameters );\r
 static void prvPermanentlyBlockingNotificationTask( void *pvParameters );\r
 \r
+/*\r
+ * The test function and callback function used when exercising the timer AP\r
+ * function that changes the timer's auto-reload mode.\r
+ */\r
+static void prvDemonstrateChangingTimerReloadMode( void *pvParameters );\r
+static void prvReloadModeTestTimerCallback( TimerHandle_t xTimer );\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /* The variable into which error messages are latched. */\r
@@ -193,7 +208,7 @@ int main_full( void )
        vStartDynamicPriorityTasks();\r
        vStartQueueSetTasks();\r
        vStartQueueOverwriteTask( mainQUEUE_OVERWRITE_PRIORITY );\r
-       xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( prvDemoQueueSpaceFunctions, NULL, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); /* Name is null for code coverage. */\r
        vStartEventGroupTasks();\r
        vStartInterruptSemaphoreTasks();\r
        vStartQueueSetPollingTask();\r
@@ -202,9 +217,18 @@ int main_full( void )
        xTaskCreate( prvDemoQueueSpaceFunctions, "QSpace", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
        xTaskCreate( prvPermanentlyBlockingSemaphoreTask, "BlockSem", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
        xTaskCreate( prvPermanentlyBlockingNotificationTask, "BlockNoti", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( prvDemonstrateChangingTimerReloadMode, "TimerMode", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );\r
 \r
-       vStartMessageBufferTasks();\r
+       vStartMessageBufferTasks( configMINIMAL_STACK_SIZE );\r
        vStartStreamBufferTasks();\r
+       vStartStreamBufferInterruptDemo();\r
+       vStartMessageBufferAMPTasks( configMINIMAL_STACK_SIZE );\r
+\r
+       #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+       {\r
+               vStartStaticallyAllocatedTasks();\r
+       }\r
+       #endif\r
 \r
        #if( configUSE_PREEMPTION != 0  )\r
        {\r
@@ -236,6 +260,7 @@ static void prvCheckTask( void *pvParameters )
 {\r
 TickType_t xNextWakeTime;\r
 const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );\r
+HeapStats_t xHeapStats;\r
 \r
        /* Just to remove compiler warning. */\r
        ( void ) pvParameters;\r
@@ -343,10 +368,37 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
                {\r
                        pcStatusMessage = "Error: Abort delay";\r
                }\r
+               else if( xIsInterruptStreamBufferDemoStillRunning() != pdPASS )\r
+               {\r
+                       pcStatusMessage = "Error: Stream buffer interrupt";\r
+               }\r
+               else if( xAreMessageBufferAMPTasksStillRunning() != pdPASS )\r
+               {\r
+                       pcStatusMessage = "Error: Message buffer AMP";\r
+               }\r
+\r
+               #if( configSUPPORT_STATIC_ALLOCATION == 1 )\r
+                       else if( xAreStaticAllocationTasksStillRunning() != pdPASS )\r
+                       {\r
+                               pcStatusMessage = "Error: Static allocation";\r
+                       }\r
+               #endif /* configSUPPORT_STATIC_ALLOCATION */\r
 \r
                /* This is the only task that uses stdout so its ok to call printf()\r
                directly. */\r
-               printf( ( char * ) "%s - %u\r\n", pcStatusMessage, ( unsigned int ) xTaskGetTickCount() );\r
+               vPortGetHeapStats( &xHeapStats );\r
+\r
+               configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() );\r
+               configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() );\r
+\r
+               printf( "%s - tick count %u - free heap %u - min free heap %u - largest free block %u - number of free blocks %u\r\n",\r
+                                       pcStatusMessage,\r
+                                       xTaskGetTickCount(),\r
+                                       xHeapStats.xAvailableHeapSpaceInBytes,\r
+                                       xHeapStats.xMinimumEverFreeBytesRemaining,\r
+                                       xHeapStats.xSizeOfLargestFreeBlockInBytes,\r
+                                       xHeapStats.xNumberOfFreeBlocks );\r
+\r
                fflush( stdout );\r
        }\r
 }\r
@@ -392,7 +444,6 @@ void *pvAllocated;
        timer. */\r
        prvDemonstrateTimerQueryFunctions();\r
 \r
-\r
        /* If xMutexToDelete has not already been deleted, then delete it now.\r
        This is done purely to demonstrate the use of, and test, the\r
        vSemaphoreDelete() macro.  Care must be taken not to delete a semaphore\r
@@ -417,6 +468,25 @@ void *pvAllocated;
        allocations so there is no need to test here. */\r
        pvAllocated = pvPortMalloc( ( rand() % 500 ) + 1 );\r
        vPortFree( pvAllocated );\r
+\r
+       /* Exit after a fixed time so code coverage results are written to the\r
+       disk. */\r
+       #if( projCOVERAGE_TEST == 1 )\r
+       {\r
+               const TickType_t xMaxRunTime = pdMS_TO_TICKS( 30000UL );\r
+\r
+               /* Exercise code not otherwise executed by standard demo/test tasks. */\r
+               if( xRunCodeCoverageTestAdditions() != pdPASS )\r
+               {\r
+                       pcStatusMessage = "Code coverage additions failed.\r\n";\r
+               }\r
+\r
+               if( ( xTaskGetTickCount() - configINITIAL_TICK_COUNT ) >= xMaxRunTime )\r
+               {\r
+                       vTaskEndScheduler();\r
+               }\r
+       }\r
+       #endif\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -455,6 +525,10 @@ TaskHandle_t xTimerTask;
        level functionality. */\r
        vPeriodicStreamBufferProcessing();\r
 \r
+       /* Writes a string to a string buffer four bytes at a time to demonstrate\r
+       a stream being sent from an interrupt to a task. */\r
+       vBasicStreamBufferSendFromISR();\r
+\r
        /* For code coverage purposes. */\r
        xTimerTask = xTimerGetTimerDaemonTaskHandle();\r
        configASSERT( uxTaskPriorityGetFromISR( xTimerTask ) == configTIMER_TASK_PRIORITY );\r
@@ -552,6 +626,9 @@ char *pcTaskName;
 static portBASE_TYPE xPerformedOneShotTests = pdFALSE;\r
 TaskHandle_t xTestTask;\r
 TaskStatus_t xTaskInfo;\r
+extern StackType_t uxTimerTaskStack[];\r
+static TickType_t xLastIdleExecutionTime = 0;\r
+TickType_t xIdleExecutionTime;\r
 \r
        /* Demonstrate the use of the xTimerGetTimerDaemonTaskHandle() and\r
        xTaskGetIdleTaskHandle() functions.  Also try using the function that sets\r
@@ -612,6 +689,7 @@ TaskStatus_t xTaskInfo;
        if( ( xTaskInfo.eCurrentState != eBlocked )                                              ||\r
                ( strcmp( xTaskInfo.pcTaskName, "Tmr Svc" ) != 0 )                       ||\r
                ( xTaskInfo.uxCurrentPriority != configTIMER_TASK_PRIORITY ) ||\r
+               ( xTaskInfo.pxStackBase != uxTimerTaskStack )                            ||\r
                ( xTaskInfo.xHandle != xTimerTaskHandle ) )\r
        {\r
                pcStatusMessage = "Error:  vTaskGetInfo() returned incorrect information about the timer task";\r
@@ -649,6 +727,13 @@ TaskStatus_t xTaskInfo;
                        }\r
                }\r
        }\r
+\r
+       xIdleExecutionTime = xTaskGetIdleRunTimeCounter();\r
+       if( xIdleExecutionTime == xLastIdleExecutionTime )\r
+       {\r
+               pcStatusMessage = "Error: Total amount of Idle task execution time did not change";\r
+       }\r
+       xLastIdleExecutionTime = xIdleExecutionTime;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -757,5 +842,66 @@ static void prvPermanentlyBlockingNotificationTask( void *pvParameters )
        configASSERT( pvParameters != NULL );\r
        vTaskDelete( NULL );\r
 }\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvReloadModeTestTimerCallback( TimerHandle_t xTimer )\r
+{\r
+uint32_t ulTimerID;\r
 \r
+       /* Increment the timer's ID to show the callback has executed. */\r
+       ulTimerID = ( uint32_t ) pvTimerGetTimerID( xTimer );\r
+       ulTimerID++;\r
+       vTimerSetTimerID( xTimer, ( void * ) ulTimerID );\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
+static void prvDemonstrateChangingTimerReloadMode( void *pvParameters )\r
+{\r
+TimerHandle_t xTimer;\r
+const char * const pcTimerName = "TestTimer";\r
+const TickType_t x100ms = pdMS_TO_TICKS( 100UL );\r
+\r
+       /* Avoid compiler warnings about unused parameter. */\r
+       ( void ) pvParameters;\r
+\r
+       xTimer = xTimerCreate(  pcTimerName,\r
+                                                       x100ms,\r
+                                                       pdFALSE, /* Created as a one-shot timer. */\r
+                                                       0,\r
+                                                       prvReloadModeTestTimerCallback );\r
+       configASSERT( xTimer );\r
+       configASSERT( xTimerIsTimerActive( xTimer ) == pdFALSE );\r
+       configASSERT( xTimerGetTimerDaemonTaskHandle() != NULL );\r
+       configASSERT( strcmp( pcTimerName, pcTimerGetName( xTimer ) ) == 0 );\r
+       configASSERT( xTimerGetPeriod( xTimer ) == x100ms );\r
+\r
+       /* Timer was created as a one-shot timer.  Its callback just increments the\r
+       timer's ID - so set the ID to 0, let the timer run for a number of timeout\r
+       periods, then check the timer has only executed once. */\r
+       vTimerSetTimerID( xTimer, ( void * ) 0 );\r
+       xTimerStart( xTimer, portMAX_DELAY );\r
+       vTaskDelay( 3UL * x100ms );\r
+       configASSERT( ( ( uint32_t ) ( pvTimerGetTimerID( xTimer ) ) ) == 1UL );\r
+\r
+       /* Now change the timer to be an auto-reload timer and check it executes\r
+       the expected number of times. */\r
+       vTimerSetReloadMode( xTimer, pdTRUE );\r
+       vTimerSetTimerID( xTimer, ( void * ) 0 );\r
+       xTimerStart( xTimer, 0 );\r
+       vTaskDelay( ( 3UL * x100ms ) + ( x100ms / 2UL ) ); /* Three full periods. */\r
+       configASSERT( ( uint32_t ) ( pvTimerGetTimerID( xTimer ) ) == 3UL );\r
+       configASSERT( xTimerStop( xTimer, 0 ) != pdFAIL );\r
+\r
+       /* Now change the timer back to be a one-shot timer and check it only\r
+       executes once. */\r
+       vTimerSetReloadMode( xTimer, pdFALSE );\r
+       vTimerSetTimerID( xTimer, ( void * ) 0 );\r
+       xTimerStart( xTimer, 0 );\r
+       vTaskDelay( 3UL * x100ms );\r
+       configASSERT( xTimerStop( xTimer, 0 ) != pdFAIL );\r
+       configASSERT( ( uint32_t ) ( pvTimerGetTimerID( xTimer ) ) == 1UL );\r
+\r
+       /* Clean up at the end. */\r
+       xTimerDelete( xTimer, portMAX_DELAY );\r
+       vTaskDelete( NULL );\r
+}\r