#include <zephyr/toolchain.h>
#include <zephyr/sys/printk.h>
// ============================================================================
// 1. ОПРЕДЕЛЕНИЕ ПУЛОВ ПАМЯТИ (Максимально утилизируем свободное место)
// ============================================================================
// В DTCM у вас свободно ~82 КБ. Безопасно забираем 64 КБ под самые горячие данные.
#define SPEEX_DTCM_POOL_SIZE (64 * 1024)
static __dtcm_bss uint8_t speex_dtcm_pool[SPEEX_DTCM_POOL_SIZE];
static size_t dtcm_ptr = 0;
// В OCRAM свободно все 64 КБ. Забираем 32 КБ под буферы, которые не влезут в DTCM.
#define SPEEX_OCRAM_POOL_SIZE (32 * 1024)
static __attribute__((section(".ocram.bss"))) uint8_t speex_ocram_pool[SPEEX_OCRAM_POOL_SIZE];
static size_t ocram_ptr = 0;
// ============================================================================
// 2. АВТОМАТИЧЕСКИЙ ДИНАМИЧЕСКИЙ АЛЛОКАТОР
// ============================================================================
static void *custom_speex_alloc_smart(size_t size)
{
// Выравнивание по 4 байта (критически важно для шины Cortex-M7)
size = (size + 3) & ~3;
// СТРАТЕГИЯ 1: Сначала пытаемся забрать из DTCM (пока есть место)
if (dtcm_ptr + size <= SPEEX_DTCM_POOL_SIZE) {
void *ptr = &speex_dtcm_pool[dtcm_ptr];
dtcm_ptr += size;
return ptr;
}
// СТРАТЕГИЯ 2: Если в DTCM места нет, плавно перетекаем в OCRAM
if (ocram_ptr + size <= SPEEX_OCRAM_POOL_SIZE) {
void *ptr = &speex_ocram_pool[ocram_ptr];
ocram_ptr += size;
return ptr;
}
// СТРАТЕГИЯ 3: Если и OCRAM закончился, берем из обычной RAM (системный malloc)
printk("AEC Warning: DTCM and OCRAM exhausted! Falling back to system heap for %d bytes\n", size);
// Вызываем оригинальный аллокатор Zephyr / PJSIP
extern void *k_malloc(size_t size);
return malloc(size);
}
// Переопределяем макрос выделения памяти для текущего файла mdf.c
#undef speex_alloc
#define speex_alloc(size) custom_speex_alloc_smart(size)