#include <zephyr/kernel.h>
#include <zephyr/sys/sys_heap.h>
#include <zephyr/toolchain.h>
#include <zephyr/logging/log.h>
#include <stdlib.h>
LOG_MODULE_REGISTER(ocram2_mem, CONFIG_LOG_DEFAULT_LEVEL);
#define OCRAM2_POOL_SIZE (512 * 1024)
static __attribute__((section(".ocram2"))) uint8_t ocram2_heap_mem[OCRAM2_POOL_SIZE];
static struct sys_heap ocram2_heap;
static bool ocram2_ready = false;
/* Вспомогательная функция для логирования текущего состояния памяти */
static void log_ocram2_stats(void)
{
#if defined(CONFIG_SYS_HEAP_RUNTIME_STATS)
struct sys_heap_runtime_stats stats;
if (sys_heap_runtime_stats_get(&ocram2_heap, &stats) == 0) {
// stats.allocated_bytes показывает точный объем занятой памяти в куче
LOG_INF("[OCRAM2] Занято: %zu из %zu байт (Свободно: %zu)",
stats.allocated_bytes,
OCRAM2_POOL_SIZE,
OCRAM2_POOL_SIZE - stats.allocated_bytes);
}
#else
/* Если сбор статистики выключен в конфиге, выводим напоминание */
LOG_WRN("Включите CONFIG_SYS_HEAP_RUNTIME_STATS=y в prj.conf для точной статистики");
#endif
}
void ocram2_heap_init(void)
{
sys_heap_init(&ocram2_heap, ocram2_heap_mem, OCRAM2_POOL_SIZE);
ocram2_ready = true;
LOG_INF("OCRAM2 heap initialized. Size: %d KB", OCRAM2_POOL_SIZE / 1024);
}
void *ocram2_malloc_fallback(size_t size)
{
void *ptr = NULL;
if (ocram2_ready) {
ptr = sys_heap_alloc(&ocram2_heap, size);
}
if (ptr != NULL) {
LOG_INF("Allocated %zu bytes from OCRAM2 at %p", size, ptr);
log_ocram2_stats(); /* <--- Вывод объема занятой памяти */
return ptr;
}
/* Fallback */
ptr = malloc(size);
if (ptr != NULL) {
LOG_WRN("OCRAM2 full! Fallback: allocated %zu bytes from System Heap at %p", size, ptr);
} else {
LOG_ERR("Out of memory! Failed to allocate %zu bytes", size);
}
return ptr;
}
void ocram2_free_fallback(void *ptr)
{
if (ptr == NULL) {
return;
}
uintptr_t addr = (uintptr_t)ptr;
uintptr_t start = (uintptr_t)ocram2_heap_mem;
uintptr_t end = start + OCRAM2_POOL_SIZE;
if (addr >= start && addr < end) {
LOG_INF("Freeing pointer %p from OCRAM2", ptr);
sys_heap_free(&ocram2_heap, ptr);
log_ocram2_stats(); /* <--- Вывод объема памяти после освобождения */
} else {
LOG_WRN("Freeing pointer %p from System Heap", ptr);
free(ptr);
}
}