diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index ba82cdd35f..c979b60b75 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -116,7 +116,7 @@ config XTENSA_INTBACKTRACE ---help--- Add necessary logic to be able to have a full backtrace from an interrupt context. -config XTENSA_USE_SEPARATE_IMEM +config XTENSA_IMEM_USE_SEPARATE_HEAP bool "Use a separate heap for internal memory" default n help @@ -128,9 +128,17 @@ config XTENSA_USE_SEPARATE_IMEM This separate heap will be part of the internal DRAM. It starts right after .data and ends at the configurable size given by the OPTION XTENSA_IMEM_REGION_SIZE. +config XTENSA_IMEM_MAXIMIZE_HEAP_REGION + bool "Use a maximum separate heap for internal memory" + default n + depends on XTENSA_IMEM_USE_SEPARATE_HEAP + help + This separate heap will be part of the internal DRAM. It starts right after .data + and ends at the (HEAP_REGION1_END - HEAP_REGION_OFFSET). + config XTENSA_IMEM_REGION_SIZE hex "DRAM region size for internal use" - depends on XTENSA_USE_SEPARATE_IMEM + depends on XTENSA_IMEM_USE_SEPARATE_HEAP && !XTENSA_IMEM_MAXIMIZE_HEAP_REGION default 0x18000 source arch/xtensa/src/lx6/Kconfig diff --git a/arch/xtensa/include/arch.h b/arch/xtensa/include/arch.h index b0709788ba..2141b7ced7 100644 --- a/arch/xtensa/include/arch.h +++ b/arch/xtensa/include/arch.h @@ -91,7 +91,7 @@ extern "C" #define EXTERN extern #endif -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP struct mallinfo; /* Forward reference, see malloc.h */ /**************************************************************************** @@ -112,7 +112,7 @@ void xtensa_imm_initialize(void); * ****************************************************************************/ -FAR void *xtensa_imm_malloc(size_t size); +void *xtensa_imm_malloc(size_t size); /**************************************************************************** * Name: xtensa_imm_calloc @@ -123,7 +123,7 @@ FAR void *xtensa_imm_malloc(size_t size); * ****************************************************************************/ -FAR void *xtensa_imm_calloc(size_t n, size_t elem_size); +void *xtensa_imm_calloc(size_t n, size_t elem_size); /**************************************************************************** * Name: xtensa_imm_realloc @@ -133,7 +133,7 @@ FAR void *xtensa_imm_calloc(size_t n, size_t elem_size); * ****************************************************************************/ -FAR void *xtensa_imm_realloc(void *ptr, size_t size); +void *xtensa_imm_realloc(void *ptr, size_t size); /**************************************************************************** * Name: xtensa_imm_zalloc @@ -143,7 +143,7 @@ FAR void *xtensa_imm_realloc(void *ptr, size_t size); * ****************************************************************************/ -FAR void *xtensa_imm_zalloc(size_t size); +void *xtensa_imm_zalloc(size_t size); /**************************************************************************** * Name: xtensa_imm_free @@ -153,7 +153,7 @@ FAR void *xtensa_imm_zalloc(size_t size); * ****************************************************************************/ -void xtensa_imm_free(FAR void *mem); +void xtensa_imm_free(FAR void *mem); /**************************************************************************** * Name: xtensa_imm_memalign @@ -163,12 +163,12 @@ void xtensa_imm_free(FAR void *mem); * within that chunk that meets the alignment request and then frees any * leading or trailing space. * - * The alignment argument must be a power of two (not checked). 8-byte + * The alignment argument must be a power of two (not checked). 8-byte * alignment is guaranteed by normal malloc calls. * ****************************************************************************/ -FAR void *xtensa_imm_memalign(size_t alignment, size_t size); +void *xtensa_imm_memalign(size_t alignment, size_t size); /**************************************************************************** * Name: xtensa_imm_heapmember @@ -180,11 +180,11 @@ FAR void *xtensa_imm_memalign(size_t alignment, size_t size); * mem - The address to check * * Return Value: - * true if the address is a member of the internal heap. false if not + * true if the address is a member of the internal heap. false if not * ****************************************************************************/ -bool xtensa_imm_heapmember(FAR void *mem); +bool xtensa_imm_heapmember(FAR void *mem); /**************************************************************************** * Name: xtensa_imm_mallinfo @@ -195,7 +195,7 @@ bool xtensa_imm_heapmember(FAR void *mem); * ****************************************************************************/ -int xtensa_imm_mallinfo(FAR struct mallinfo *info); +int xtensa_imm_mallinfo(FAR struct mallinfo *info); #endif #undef EXTERN diff --git a/arch/xtensa/src/common/xtensa_initialize.c b/arch/xtensa/src/common/xtensa_initialize.c index 5bf57ad3f8..e5177023aa 100644 --- a/arch/xtensa/src/common/xtensa_initialize.c +++ b/arch/xtensa/src/common/xtensa_initialize.c @@ -150,7 +150,7 @@ void up_initialize(void) /* Initialize the internal heap */ -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP xtensa_imm_initialize(); #endif diff --git a/arch/xtensa/src/common/xtensa_mm.h b/arch/xtensa/src/common/xtensa_mm.h index bfb75b539c..716bc3c114 100644 --- a/arch/xtensa/src/common/xtensa_mm.h +++ b/arch/xtensa/src/common/xtensa_mm.h @@ -34,7 +34,7 @@ * Pre-processor Macros ****************************************************************************/ -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP # define UMM_MALLOC(s) xtensa_imm_malloc(s) # define UMM_MEMALIGN(a,s) xtensa_imm_memalign(a,s) # define UMM_FREE(p) xtensa_imm_free(p) diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index 87305f420f..bcce5f81d8 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -285,6 +285,7 @@ config ESP32_SPIRAM bool "SPI RAM Support" default n select ARCH_HAVE_HEAP2 + select XTENSA_IMEM_USE_SEPARATE_HEAP if ESP32_SPIRAM && SMP diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index d578959632..0271c0c632 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -103,7 +103,7 @@ endif CHIP_CSRCS += esp32_rtc.c -ifeq ($(CONFIG_XTENSA_USE_SEPARATE_IMEM),y) +ifeq ($(CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP),y) CHIP_CSRCS += esp32_imm.c endif diff --git a/arch/xtensa/src/esp32/esp32_allocateheap.c b/arch/xtensa/src/esp32/esp32_allocateheap.c index 13e1af2722..06d16ea331 100644 --- a/arch/xtensa/src/esp32/esp32_allocateheap.c +++ b/arch/xtensa/src/esp32/esp32_allocateheap.c @@ -63,7 +63,7 @@ * * _sheap eg. 3ffc 8c6c * : - * : g_iheap (CONFIG_XTENSA_USE_SEPARATE_IMEM) + * : g_iheap (CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP) * : * _sheap + CONFIG_XTENSA_IMEM_REGION_SIZE eg. 3ffd ebfc * : @@ -87,7 +87,9 @@ * script as "_sheap". Then end is defined here, as follows: */ +#ifndef HEAP_REGION1_END #define HEAP_REGION1_END 0x3ffdfff0 +#endif /* Region 2 of the heap is the area from the end of the ROM data to the end * of DRAM. The linker script has already set "_eheap" as the end of DRAM, @@ -102,12 +104,23 @@ # define HEAP_REGION2_START 0x3ffe7e40 #endif -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP #define XTENSA_IMEM_REGION_SIZE CONFIG_XTENSA_IMEM_REGION_SIZE #else #define XTENSA_IMEM_REGION_SIZE 0 #endif +/* If CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION is defined, it means + * using maximum separate heap for internal memory, but part of + * the available memory is reserved for the Region 1 heap. + */ + +#ifdef CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION +#ifndef HEAP_REGION_OFFSET +#define HEAP_REGION_OFFSET 0x2000 +#endif +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -130,6 +143,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) { board_autoled_on(LED_HEAPALLOCATE); +#ifdef CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION + *heap_size = (size_t)HEAP_REGION_OFFSET; + *heap_start = (FAR void *)(HEAP_REGION1_END - *heap_size); +#else *heap_start = (FAR void *)&_sheap + XTENSA_IMEM_REGION_SIZE; /* If the following DEBUGASSERT fails, @@ -138,6 +155,7 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) DEBUGASSERT(HEAP_REGION1_END > (uintptr_t)*heap_start); *heap_size = (size_t)(HEAP_REGION1_END - (uintptr_t)*heap_start); +#endif } /**************************************************************************** diff --git a/arch/xtensa/src/esp32/esp32_imm.c b/arch/xtensa/src/esp32/esp32_imm.c index 7bfb70314e..824d5a9a77 100644 --- a/arch/xtensa/src/esp32/esp32_imm.c +++ b/arch/xtensa/src/esp32/esp32_imm.c @@ -31,7 +31,31 @@ #include "xtensa.h" -#if CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Region 1 of the heap is the area from the end of the .data section to the + * begining of the ROM data. The start address is defined from the linker + * script as "_sheap". Then end is defined here, as follows: + */ + +#ifndef HEAP_REGION1_END +#define HEAP_REGION1_END 0x3ffdfff0 +#endif + +/* If define CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION, it means + * using maximum separate heap for internal memory, but part of + * the available memory is reserved for the Region 1 heap. + */ + +#ifdef CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION +#ifndef HEAP_REGION_OFFSET +#define HEAP_REGION_OFFSET 0x2000 +#endif +#endif /**************************************************************************** * Private Data @@ -57,7 +81,19 @@ void xtensa_imm_initialize(void) size_t size; start = (FAR void *)&_sheap; +#ifdef CONFIG_XTENSA_IMEM_MAXIMIZE_HEAP_REGION + size_t offset = HEAP_REGION_OFFSET; + size = (size_t)(HEAP_REGION1_END - (uintptr_t)start - offset); +#else + + /* If the following DEBUGASSERT fails, + * probably you have too large CONFIG_XTENSA_IMEM_REGION_SIZE. + */ + size = CONFIG_XTENSA_IMEM_REGION_SIZE; + DEBUGASSERT(HEAP_REGION1_END > ((uintptr_t)start + size)); +#endif + mm_initialize(&g_iheap, start, size); #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MEMINFO) @@ -78,7 +114,7 @@ void xtensa_imm_initialize(void) * ****************************************************************************/ -FAR void *xtensa_imm_malloc(size_t size) +void *xtensa_imm_malloc(size_t size) { return mm_malloc(&g_iheap, size); } @@ -92,7 +128,7 @@ FAR void *xtensa_imm_malloc(size_t size) * ****************************************************************************/ -FAR void *xtensa_imm_calloc(size_t n, size_t elem_size) +void *xtensa_imm_calloc(size_t n, size_t elem_size) { return mm_calloc(&g_iheap, n, elem_size); } @@ -105,7 +141,7 @@ FAR void *xtensa_imm_calloc(size_t n, size_t elem_size) * ****************************************************************************/ -FAR void *xtensa_imm_realloc(void *ptr, size_t size) +void *xtensa_imm_realloc(void *ptr, size_t size) { return mm_realloc(&g_iheap, ptr, size); } @@ -118,7 +154,7 @@ FAR void *xtensa_imm_realloc(void *ptr, size_t size) * ****************************************************************************/ -FAR void *xtensa_imm_zalloc(size_t size) +void *xtensa_imm_zalloc(size_t size) { return mm_zalloc(&g_iheap, size); } @@ -149,7 +185,7 @@ void xtensa_imm_free(FAR void *mem) * ****************************************************************************/ -FAR void *xtensa_imm_memalign(size_t alignment, size_t size) +void *xtensa_imm_memalign(size_t alignment, size_t size) { return mm_memalign(&g_iheap, alignment, size); } @@ -187,4 +223,4 @@ int xtensa_imm_mallinfo(FAR struct mallinfo *info) return mm_mallinfo(&g_iheap, info); } -#endif /* CONFIG_XTENSA_USE_SEPARATE_IMEM */ +#endif /* CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP */ diff --git a/arch/xtensa/src/esp32/esp32_spi.c b/arch/xtensa/src/esp32/esp32_spi.c index 9491b0357e..9c9456a7f6 100644 --- a/arch/xtensa/src/esp32/esp32_spi.c +++ b/arch/xtensa/src/esp32/esp32_spi.c @@ -870,14 +870,14 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv, uint8_t *rp; uint32_t n; uint32_t regval; -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP uint8_t *alloctp; uint8_t *allocrp; #endif /* If the buffer comes from PSRAM, allocate a new one from DRAM */ -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP if (esp32_ptr_extram(txbuffer)) { alloctp = xtensa_imm_malloc(total); @@ -891,7 +891,7 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv, tp = (uint8_t *)txbuffer; } -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP if (esp32_ptr_extram(rxbuffer)) { allocrp = xtensa_imm_malloc(total); @@ -963,7 +963,7 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv, rp += n; } -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP if (esp32_ptr_extram(rxbuffer)) { memcpy(rxbuffer, allocrp, total); @@ -971,7 +971,7 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv, } #endif -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP if (esp32_ptr_extram(txbuffer)) { xtensa_imm_free(alloctp); diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c index b0d3a30b72..cac06cae90 100644 --- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c +++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c @@ -70,6 +70,10 @@ # define NVS_FILE_MODE 0777 #endif +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + #define WIFI_CONNECT_TIMEOUT CONFIG_ESP32_WIFI_CONNECT_TIMEOUT #define TIMER_INITIALIZED_VAL (0x5aa5a55a) @@ -1862,7 +1866,7 @@ static void *esp_malloc(uint32_t size) static void esp_free(void *ptr) { -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP if (xtensa_imm_heapmember(ptr)) { xtensa_imm_free(ptr); @@ -3438,7 +3442,7 @@ uint32_t esp_log_timestamp(void) static void *esp_malloc_internal(size_t size) { -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP return xtensa_imm_malloc(size); #else void *ptr = kmm_malloc(size); @@ -3469,16 +3473,35 @@ static void *esp_malloc_internal(size_t size) static void *esp_realloc_internal(void *ptr, size_t size) { -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP return xtensa_imm_realloc(ptr, size); #else - if (size == 0 || esp32_ptr_extram(ptr)) + void *old_ptr = ptr; + void *new_ptr = NULL; + size_t old_size = 0; + if (size == 0) { - esp_free(ptr); + kmm_free(ptr); return NULL; } - return kmm_realloc(ptr, size); + new_ptr = kmm_malloc(size); + if (new_ptr != NULL) + { + if (esp32_ptr_extram(new_ptr)) + { + kmm_free(new_ptr); + return NULL; + } + + old_size = malloc_usable_size(old_ptr); + DEBUGASSERT(old_size > 0); + memcpy(new_ptr, old_ptr, MIN(old_size, size)); + kmm_free(old_ptr); + return new_ptr; + } + + return NULL; #endif } @@ -3499,7 +3522,7 @@ static void *esp_realloc_internal(void *ptr, size_t size) static void *esp_calloc_internal(size_t n, size_t size) { -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP return xtensa_imm_calloc(n, size); #else void *ptr = kmm_calloc(n, size); @@ -3529,7 +3552,7 @@ static void *esp_calloc_internal(size_t n, size_t size) static void *esp_zalloc_internal(size_t size) { -#ifdef CONFIG_XTENSA_USE_SEPARATE_IMEM +#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP return xtensa_imm_zalloc(size); #else void *ptr = kmm_zalloc(size);