feat: rebuild heap4 card around upstream FreeRTOS allocator

This commit is contained in:
user
2026-07-14 23:24:56 +02:00
parent 032a06fdef
commit 2b17bb4ff9
41 changed files with 1462 additions and 2138 deletions
+122
View File
@@ -0,0 +1,122 @@
#include <stddef.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "task.h"
#if defined(HOST_PRINTF)
#include <stdio.h>
#endif
uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((aligned(portBYTE_ALIGNMENT)));
HeapStats_t g_fragmented_stats;
HeapStats_t g_final_stats;
volatile size_t g_initial_free;
volatile size_t g_after_allocations;
volatile size_t g_final_free;
volatile size_t g_minimum_ever_free;
volatile int g_allocations_aligned;
volatile int g_oom_is_null;
volatile int g_malloc_failed_hooks;
volatile int g_assert_failures;
volatile int g_task03_pass;
void vApplicationMallocFailedHook(void)
{
g_malloc_failed_hooks++;
}
void heap4_lab_assert(const char *file, int line)
{
(void)file;
(void)line;
g_assert_failures++;
}
#if defined(HEAP4_HOST_ADAPTER)
void vTaskSuspendAll(void)
{
}
BaseType_t xTaskResumeAll(void)
{
return 0;
}
#endif
__attribute__((noinline)) void heap4_fragmented_checkpoint(void)
{
#if defined(__GNUC__)
__asm__ volatile("" ::: "memory");
#endif
}
__attribute__((noinline)) void task03_debug_checkpoint(void)
{
#if defined(__GNUC__)
__asm__ volatile("" ::: "memory");
#endif
}
int main(void)
{
void *probe;
void *a;
void *b;
void *c;
void *too_large;
vPortHeapResetState();
probe = pvPortMalloc(1U);
if (probe != NULL)
{
vPortFree(probe);
}
g_initial_free = xPortGetFreeHeapSize();
a = pvPortMalloc(24U);
b = pvPortMalloc(40U);
c = pvPortMalloc(16U);
g_after_allocations = xPortGetFreeHeapSize();
g_allocations_aligned =
a != NULL && b != NULL && c != NULL &&
((uintptr_t)a % portBYTE_ALIGNMENT) == 0U &&
((uintptr_t)b % portBYTE_ALIGNMENT) == 0U &&
((uintptr_t)c % portBYTE_ALIGNMENT) == 0U;
vPortFree(a);
vPortFree(c);
vPortGetHeapStats(&g_fragmented_stats);
heap4_fragmented_checkpoint();
vPortFree(b);
g_final_free = xPortGetFreeHeapSize();
g_minimum_ever_free = xPortGetMinimumEverFreeHeapSize();
vPortGetHeapStats(&g_final_stats);
too_large = pvPortMalloc(configTOTAL_HEAP_SIZE * 2U);
g_oom_is_null = too_large == NULL;
g_task03_pass =
probe != NULL && g_allocations_aligned &&
g_initial_free > g_after_allocations &&
g_final_free == g_initial_free &&
g_minimum_ever_free <= g_after_allocations &&
g_fragmented_stats.xNumberOfFreeBlocks == 2U &&
g_final_stats.xNumberOfFreeBlocks == 1U &&
g_final_stats.xSizeOfLargestFreeBlockInBytes == g_initial_free &&
g_oom_is_null && g_malloc_failed_hooks == 1 &&
g_assert_failures == 0;
task03_debug_checkpoint();
#if defined(HOST_PRINTF)
printf("initial=%zu after=%zu fragmented=%zu final=%zu min=%zu "
"aligned=%d oom=%d hooks=%d asserts=%d pass=%d\n",
g_initial_free, g_after_allocations,
g_fragmented_stats.xNumberOfFreeBlocks, g_final_free,
g_minimum_ever_free, g_allocations_aligned, g_oom_is_null,
g_malloc_failed_hooks, g_assert_failures, g_task03_pass);
#endif
return g_task03_pass ? 0 : 1;
}