Exercise the new vPortGetHeapStats() function from the Win32 demo projects.

pull/1/head
Richard Barry 6 years ago
parent fa404422b9
commit 4d6570b009

@ -62,7 +62,8 @@
#define configUSE_ALTERNATIVE_API 0
#define configUSE_QUEUE_SETS 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
/* Software timer related configuration options. */
#define configUSE_TIMERS 1

@ -81,6 +81,7 @@
<ClCompile Include="..\..\Source\event_groups.c" />
<ClCompile Include="..\..\Source\portable\MemMang\heap_5.c" />
<ClCompile Include="..\..\Source\stream_buffer.c" />
<ClCompile Include="..\..\Source\task_pool.c" />
<ClCompile Include="..\..\Source\timers.c" />
<ClCompile Include="..\Common\Minimal\AbortDelay.c" />
<ClCompile Include="..\Common\Minimal\BlockQ.c" />

@ -160,6 +160,9 @@
<ClCompile Include="..\Common\Minimal\MessageBufferAMP.c">
<Filter>Demo App Source\Full_Demo\Common Demo Tasks</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\task_pool.c">
<Filter>FreeRTOS Source\Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="FreeRTOSConfig.h">

@ -245,6 +245,7 @@ static void prvCheckTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xCycleFrequency = pdMS_TO_TICKS( 4000UL );
HeapStats_t xHeapStats;
/* Just to remove compiler warning. */
( void ) pvParameters;
@ -370,10 +371,17 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 4000UL );
/* This is the only task that uses stdout so its ok to call printf()
directly. */
printf( "%s - tick count %zu - free heap %zu - min free heap %zu\r\n", pcStatusMessage,
xTaskGetTickCount(),
xPortGetFreeHeapSize(),
xPortGetMinimumEverFreeHeapSize() );
vPortGetHeapStats( &xHeapStats );
configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() );
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() );
printf( "%s - tick count %zu - free heap %zu - min free heap %zu - largest free block %zu \r\n",
pcStatusMessage,
xTaskGetTickCount(),
xHeapStats.xAvailableHeapSpaceInBytes,
xHeapStats.xMinimumEverFreeBytesRemaining,
xHeapStats.xSizeOfLargestFreeBlockInBytes );
}
}
/*-----------------------------------------------------------*/

@ -103,6 +103,12 @@ void vFullDemoIdleFunction( void );
*/
static void prvInitialiseHeap( void );
/*
* Performs a few sanity checks on the behaviour of the vPortGetHeapStats()
* function.
*/
static void prvExerciseHeapStats( void );
/*
* Prototypes for the standard FreeRTOS application hook (callback) functions
* implemented within this file. See http://www.freertos.org/a00016.html .
@ -344,6 +350,8 @@ offsets into the array - with gaps in between and messy alignment just for test
purposes. */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
volatile uint32_t ulAdditionalOffset = 19; /* Just to prevent 'condition is always true' warnings in configASSERT(). */
HeapStats_t xHeapStats;
const HeapStats_t xZeroHeapStats = { 0 };
const HeapRegion_t xHeapRegions[] =
{
/* Start address with dummy offsets Size */
@ -360,7 +368,80 @@ const HeapRegion_t xHeapRegions[] =
/* Prevent compiler warnings when configASSERT() is not defined. */
( void ) ulAdditionalOffset;
/* The heap has not been initialised yet so expect stats to all be zero. */
vPortGetHeapStats( &xHeapStats );
configASSERT( memcmp( &xHeapStats, &xZeroHeapStats, sizeof( HeapStats_t ) ) == 0 );
vPortDefineHeapRegions( xHeapRegions );
/* Sanity check vTaskGetHeapStats(). */
prvExerciseHeapStats();
}
/*-----------------------------------------------------------*/
static void prvExerciseHeapStats( void )
{
HeapStats_t xHeapStats;
size_t xInitialFreeSpace = xPortGetFreeHeapSize(), xMinimumFreeBytes;
size_t xMetaDataOverhead, i;
void *pvAllocatedBlock;
const size_t xArraySize = 5, xBlockSize = 1000UL;
void *pvAllocatedBlocks[ xArraySize ];
/* Check heap stats are as expected after initialisation but before any
allocations. */
vPortGetHeapStats( &xHeapStats );
/* Minimum ever free bytes remaining should be the same as the total number
of bytes as nothing has been allocated yet. */
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes );
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xInitialFreeSpace );
/* Nothing has been allocated or freed yet. */
configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 0 );
configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 0 );
/* Allocate a 1000 byte block then measure what the overhead of the
allocation in regards to how many bytes more than 1000 were actually
removed from the heap in order to store metadata about the allocation. */
pvAllocatedBlock = pvPortMalloc( xBlockSize );
configASSERT( pvAllocatedBlock );
xMetaDataOverhead = ( xInitialFreeSpace - xPortGetFreeHeapSize() ) - xBlockSize;
/* Free the block again to get back to where we started. */
vPortFree( pvAllocatedBlock );
vPortGetHeapStats( &xHeapStats );
configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xInitialFreeSpace );
configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == 1 );
configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 );
/* Allocate blocks checking some stats value on each allocation. */
for( i = 0; i < xArraySize; i++ )
{
pvAllocatedBlocks[ i ] = pvPortMalloc( xBlockSize );
configASSERT( pvAllocatedBlocks[ i ] );
vPortGetHeapStats( &xHeapStats );
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == ( xInitialFreeSpace - ( ( i + 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) );
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xHeapStats.xAvailableHeapSpaceInBytes );
configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( 2Ul + i ) );
configASSERT( xHeapStats.xNumberOfSuccessfulFrees == 1 ); /* Does not increase during allocations. */
}
configASSERT( xPortGetFreeHeapSize() == xPortGetMinimumEverFreeHeapSize() );
xMinimumFreeBytes = xPortGetFreeHeapSize();
/* Free the blocks again. */
for( i = 0; i < xArraySize; i++ )
{
vPortFree( pvAllocatedBlocks[ i ] );
vPortGetHeapStats( &xHeapStats );
configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == ( xInitialFreeSpace - ( ( ( xArraySize - i - 1 ) * ( xBlockSize + xMetaDataOverhead ) ) ) ) );
configASSERT( xHeapStats.xNumberOfSuccessfulAllocations == ( xArraySize + 1 ) ); /* Does not increase during frees. */
configASSERT( xHeapStats.xNumberOfSuccessfulFrees == ( 2UL + i ) );
}
/* The minimum ever free heap size should not change as blocks are freed. */
configASSERT( xMinimumFreeBytes == xPortGetMinimumEverFreeHeapSize() );
}
/*-----------------------------------------------------------*/

@ -260,6 +260,7 @@ static void prvCheckTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
HeapStats_t xHeapStats;
/* Just to remove compiler warning. */
( void ) pvParameters;
@ -385,10 +386,19 @@ const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
/* This is the only task that uses stdout so its ok to call printf()
directly. */
printf( "%s - tick count %u - free heap %u - min free heap %u\r\n", pcStatusMessage,
xTaskGetTickCount(),
xPortGetFreeHeapSize(),
xPortGetMinimumEverFreeHeapSize() );
vPortGetHeapStats( &xHeapStats );
configASSERT( xHeapStats.xAvailableHeapSpaceInBytes == xPortGetFreeHeapSize() );
configASSERT( xHeapStats.xMinimumEverFreeBytesRemaining == xPortGetMinimumEverFreeHeapSize() );
printf( "%s - tick count %u - free heap %u - min free heap %u - largest free block %u - number of free blocks %u\r\n",
pcStatusMessage,
xTaskGetTickCount(),
xHeapStats.xAvailableHeapSpaceInBytes,
xHeapStats.xMinimumEverFreeBytesRemaining,
xHeapStats.xSizeOfLargestFreeBlockInBytes,
xHeapStats.xNumberOfFreeBlocks );
fflush( stdout );
}
}

Loading…
Cancel
Save