Commit 5dc54529 authored by Lucas Tamborrino's avatar Lucas Tamborrino Committed by Anas Nashif
Browse files

soc: espressif: psram as shared multi heap



Currently, if the user wants to allocate heap on external RAM
he needs to enable CONFIG_ESP_SPIRAM and set a threshold defined
with CONFIG_ESP_HEAP_MIN_EXTRAM_THRESHOLD.

This approach requires that we re-implement `k_malloc` and allocate
the memory on the proper region based on the block size.

By using the shared multi heap feature the proccess of allocating
memory from external memory becomes more fluent and simple.

The attribute SMH_REG_ATTR_EXTERNAL was added to reference the
external memory.

Signed-off-by: default avatarLucas Tamborrino <lucas.tamborrino@espressif.com>
parent cfeb325b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@ enum shared_multi_heap_attr {
	/** non-cacheable */
	SMH_REG_ATTR_NON_CACHEABLE,

	/** external Memory */
	SMH_REG_ATTR_EXTERNAL,

	/** must be the last item */
	SMH_REG_ATTR_NUM,
};
+2 −0
Original line number Diff line number Diff line
@@ -4,3 +4,5 @@
if(CONFIG_SOC_SERIES_ESP32 OR CONFIG_SOC_SERIES_ESP32S2 OR CONFIG_SOC_SERIES_ESP32S3)
  zephyr_include_directories(include)
endif()

zephyr_sources_ifdef(CONFIG_ESP_SPIRAM psram.c)
+1 −9
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ config ESP_SPIRAM
	bool "Support for external, SPI-connected RAM"
	default n if MCUBOOT
	default n if ESP32_USE_UNSUPPORTED_REVISION && SOC_SERIES_ESP32
	select SHARED_MULTI_HEAP
	help
	  This enables support for an external SPI RAM chip, connected in
	  parallel with the main SPI flash chip.
@@ -14,15 +15,6 @@ config ESP_SPIRAM
menu "SPI RAM config"
	depends on ESP_SPIRAM

config ESP_HEAP_MIN_EXTRAM_THRESHOLD
	int "Minimum threshold for external RAM allocation"
	default 8192
	range 1024 131072
	help
	  Threshold to decide if memory will be allocated from DRAM
	  or SPIRAM. If value of allocation size is less than this value,
	  memory will be allocated from internal RAM.

config ESP_HEAP_SEARCH_ALL_REGIONS
	bool "Search for all available heap regions"
	default y
+10 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

int esp_init_psram(void);

int esp_psram_smh_init(void);
+52 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/kernel.h>
#include <rom/ets_sys.h>
#include <esp_psram.h>
#include <esp_private/esp_psram_extram.h>
#include <zephyr/multi_heap/shared_multi_heap.h>

#define PSRAM_ADDR (DT_REG_ADDR(DT_NODELABEL(psram0)))

extern int _spiram_heap_start;
extern int _ext_ram_bss_start;
extern int _ext_ram_bss_end;

struct shared_multi_heap_region smh_psram = {
	.addr = (uintptr_t)&_spiram_heap_start,
	.size = CONFIG_ESP_SPIRAM_SIZE,
	.attr = SMH_REG_ATTR_EXTERNAL,
};

int esp_psram_smh_init(void)
{
	shared_multi_heap_pool_init();
	smh_psram.size = CONFIG_ESP_SPIRAM_SIZE - ((int)&_spiram_heap_start - PSRAM_ADDR);
	return shared_multi_heap_add(&smh_psram, NULL);
}

void esp_init_psram(void)
{
	if (esp_psram_init()) {
		ets_printf("Failed to Initialize external RAM, aborting.\n");
		return;
	}

	if (esp_psram_get_size() < CONFIG_ESP_SPIRAM_SIZE) {
		ets_printf("External RAM size is less than configured.\n");
	}

	if (esp_psram_is_initialized()) {
		if (!esp_psram_extram_test()) {
			ets_printf("External RAM failed memory test!");
			return;
		}
	}

	memset(&_ext_ram_bss_start, 0,
	       (&_ext_ram_bss_end - &_ext_ram_bss_start) * sizeof(_ext_ram_bss_start));
}
Loading