You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/18 09:41:16 UTC

[nuttx] 01/03: xtensa/esp32: Support allocation of userspace heap into External RAM

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 705e29fb274a615d8c36fda2d19e5a5fd696786a
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Wed Jan 11 15:37:13 2023 -0300

    xtensa/esp32: Support allocation of userspace heap into External RAM
    
    Signed-off-by: Gustavo Henrique Nihei <gu...@espressif.com>
---
 arch/xtensa/src/esp32/Kconfig                      |  77 ++++++++++-----
 arch/xtensa/src/esp32/esp32_allocateheap.c         | 105 +++++++++++++++------
 arch/xtensa/src/esp32/esp32_himem.h                |   2 +
 .../esp32/esp32-devkitc/configs/psram/defconfig    |   4 +-
 .../configs/{psram => psram_usrheap}/defconfig     |   8 +-
 5 files changed, 137 insertions(+), 59 deletions(-)

diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 1249edd131..da92b64e8d 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -182,16 +182,6 @@ config ESP32_RUN_IRAM
 		This loads all of NuttX inside IRAM.  Used to test somewhat small
 		images that can fit entirely in IRAM.
 
-config ESP32_RTC_HEAP
-	bool "Use the RTC memory as a separate heap"
-	select ARCH_HAVE_EXTRA_HEAPS
-	default n
-
-config ESP32_IRAM_HEAP
-	bool "Use the rest of IRAM as a separate heap"
-	select ARCH_HAVE_EXTRA_HEAPS
-	default n
-
 menu "ESP32 Peripheral Selection"
 
 config ESP32_UART
@@ -579,10 +569,9 @@ config ESP32_SPI3
 	select SPI
 
 config ESP32_SPIRAM
-	bool "SPI RAM Support"
+	bool "SPI RAM"
 	default n
-	select ARCH_HAVE_HEAP2 if !ESP32_USER_DATA_EXTMEM
-	select XTENSA_IMEM_USE_SEPARATE_HEAP
+	select ARCH_HAVE_HEAP2
 
 if ESP32_SPIRAM && SMP
 
@@ -764,6 +753,41 @@ config ESP32_ULP_COPROC_RESERVE_MEM
 	int "Reserved ULP co-processor DRAM"
 	default 0
 
+comment "Additional Heaps"
+
+choice ESP32_SPIRAM_HEAP
+	prompt "SPI RAM heap function"
+	default ESP32_SPIRAM_COMMON_HEAP if BUILD_FLAT
+	default ESP32_SPIRAM_USER_HEAP if BUILD_PROTECTED
+	depends on ESP32_SPIRAM
+	---help---
+		Select how the SPI RAM will be used as heap.
+
+	config ESP32_SPIRAM_COMMON_HEAP
+		bool "Additional region to kernel heap"
+
+	config ESP32_SPIRAM_USER_HEAP
+		bool "Separated userspace heap"
+		select MM_KERNEL_HEAP
+		select ESP32_USER_DATA_EXTMEM if BUILD_PROTECTED
+
+endchoice
+
+config ESP32_IMM_HEAP
+	bool "Reserve part of DRAM as a separate heap"
+	select XTENSA_IMEM_USE_SEPARATE_HEAP
+	default n
+
+config ESP32_RTC_HEAP
+	bool "Use the RTC memory as a separate heap"
+	select ARCH_HAVE_EXTRA_HEAPS
+	default n
+
+config ESP32_IRAM_HEAP
+	bool "Use the rest of IRAM as a separate heap"
+	select ARCH_HAVE_EXTRA_HEAPS
+	default n
+
 endmenu # Memory Configuration
 
 config ESP32_GPIO_IRQ
@@ -772,7 +796,7 @@ config ESP32_GPIO_IRQ
 	---help---
 		Enable support for interrupting GPIO pins
 
-menu "UART configuration"
+menu "UART Configuration"
 	depends on ESP32_UART
 
 if ESP32_UART0
@@ -829,6 +853,7 @@ config ESP32_UART0_TXDMA
 	bool "Enable UART0 TX DMA"
 	select ARCH_DMA
 	select UART0_TXDMA
+	select ESP32_IMM_HEAP if ESP32_SPIRAM
 	depends on EXPERIMENTAL
 	---help---
 		Due to a hardware bug on the DMA used by the UART
@@ -895,6 +920,7 @@ config ESP32_UART1_TXDMA
 	bool "Enable UART1 TX DMA"
 	select ARCH_DMA
 	select UART1_TXDMA
+	select ESP32_IMM_HEAP if ESP32_SPIRAM
 	depends on EXPERIMENTAL
 	---help---
 		Due to a hardware bug on the DMA used by the UART
@@ -961,6 +987,7 @@ config ESP32_UART2_TXDMA
 	bool "Enable UART2 TX DMA"
 	select ARCH_DMA
 	select UART2_TXDMA
+	select ESP32_IMM_HEAP if ESP32_SPIRAM
 	depends on EXPERIMENTAL
 	---help---
 		Due to a hardware bug on the DMA used by the UART
@@ -1000,7 +1027,7 @@ config UART_DMADESC_NUM
 
 endmenu # UART configuration
 
-menu "I2C configuration"
+menu "I2C Configuration"
 	depends on ESP32_I2C
 
 if ESP32_I2C0
@@ -1093,7 +1120,7 @@ config ESP32_TWAI_REGDEBUG
 
 endmenu #ESP32_TWAI
 
-menu "SPI configuration"
+menu "SPI Configuration"
 	depends on ESP32_SPI
 
 config ESP32_SPI_SWCS
@@ -1112,11 +1139,15 @@ config ESP32_SPI_UDCS
 config ESP32_SPI2_DMA
 	bool "SPI2 use DMA"
 	default y
+	select ARCH_DMA
+	select ESP32_IMM_HEAP if ESP32_SPIRAM
 	depends on ESP32_SPI2
 
 config ESP32_SPI3_DMA
 	bool "SPI3 use DMA"
 	default y
+	select ARCH_DMA
+	select ESP32_IMM_HEAP if ESP32_SPIRAM
 	depends on ESP32_SPI3
 
 config SPI_DMADESC_NUM
@@ -1657,7 +1688,7 @@ endif # ESP32_PCNT_U7
 
 endmenu # ESP32_PCNT
 
-menu "SPI Flash configuration"
+menu "SPI Flash Configuration"
 
 choice ESP32_FLASH_MODE
 	prompt "SPI Flash mode"
@@ -1745,7 +1776,7 @@ endif
 
 if ESP32_SPIFLASH
 
-comment "General storage MTD configuration"
+comment "General storage MTD Configuration"
 
 config ESP32_STORAGE_MTD_ENCRYPT
 	bool "Encrypt Storage MTD partition"
@@ -1775,7 +1806,7 @@ config ESP32_SPIFLASH_DEBUG
 
 if ESP32_APP_FORMAT_LEGACY
 
-comment "Partition Table configuration"
+comment "Partition Table Configuration"
 
 config ESP32_PARTITION_TABLE
 	bool "Create MTD partitions from Partition Table"
@@ -1794,7 +1825,7 @@ endif # ESP32_SPIFLASH
 
 endmenu # SPI Flash configuration
 
-menu "SPI RAM Config"
+menu "SPI RAM Configuration"
 	depends on ESP32_SPIRAM
 
 choice ESP32_SPIRAM_TYPE
@@ -1899,7 +1930,7 @@ config SPIRAM_BANKSWITCH_RESERVE
 
 endmenu #SPI RAM Config
 
-menu "Ethernet configuration"
+menu "Ethernet Configuration"
 	depends on ESP32_EMAC
 
 config ESP32_ETH_NRXDESC
@@ -1938,7 +1969,7 @@ config ESP32_ETH_PHY_ADDR
 
 endmenu # ESP32_EMAC
 
-menu "Wi-Fi configuration"
+menu "Wi-Fi Configuration"
 	depends on ESP32_WIFI
 
 choice
@@ -2192,7 +2223,7 @@ config ESP32_RTC_CLK_SRC_INT_8MD256
 endchoice
 endmenu # "RTC Configuration"
 
-menu "LEDC configuration"
+menu "LEDC Configuration"
 	depends on ESP32_LEDC
 
 menuconfig ESP32_LEDC_TIM0
diff --git a/arch/xtensa/src/esp32/esp32_allocateheap.c b/arch/xtensa/src/esp32/esp32_allocateheap.c
index b37ed374d6..7386a94f75 100644
--- a/arch/xtensa/src/esp32/esp32_allocateheap.c
+++ b/arch/xtensa/src/esp32/esp32_allocateheap.c
@@ -38,18 +38,22 @@
 #endif
 #include <arch/esp32/memory_layout.h>
 
-#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE
-#include <nuttx/himem/himem.h>
+#include "xtensa.h"
+#ifdef CONFIG_ESP32_SPIRAM
 #include "esp32_himem.h"
 #endif
 
-#include "xtensa.h"
-
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-#ifdef CONFIG_BUILD_PROTECTED
+#ifdef CONFIG_MM_KERNEL_HEAP
+#  if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2)
+#    define MM_USER_HEAP_EXTRAM
+#  else
+#    define MM_USER_HEAP_IRAM
+#  endif
+
 #  define MM_ADDREGION kmm_addregion
 #else
 #  define MM_ADDREGION umm_addregion
@@ -76,32 +80,56 @@
 
 void up_allocate_heap(void **heap_start, size_t *heap_size)
 {
-#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
-  uintptr_t ubase = USERSPACE->us_dataend;
-  uintptr_t utop  = USERSPACE->us_heapend;
-  size_t    usize = utop - ubase;
+  uintptr_t ubase;
+  uintptr_t utop;
+  size_t    usize;
 
-#if defined(CONFIG_ESP32_USER_DATA_EXTMEM) && \
-    defined(CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE)
+#ifdef CONFIG_MM_KERNEL_HEAP
+#  ifdef CONFIG_BUILD_PROTECTED
+  ubase = USERSPACE->us_dataend;
+  utop  = USERSPACE->us_heapend;
+  usize = utop - ubase;
+#    ifdef CONFIG_ESP32_USER_DATA_EXTMEM
   usize -= esp_himem_reserved_area_size();
-#endif
+#    endif
+
+#  elif defined(CONFIG_BUILD_FLAT)
+#    ifdef MM_USER_HEAP_EXTRAM
+#      ifdef CONFIG_XTENSA_EXTMEM_BSS
+  ubase = (uintptr_t)_ebss_extmem;
+  usize = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem);
+#      else
+  ubase = CONFIG_HEAP2_BASE;
+  usize = CONFIG_HEAP2_SIZE;
+#      endif
+  usize -= esp_himem_reserved_area_size();
+  utop  = ubase + usize;
+
+#    elif defined(MM_USER_HEAP_IRAM)
+  ubase = ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE;
+  utop  = (uintptr_t)_eheap;
+  usize = utop - ubase;
+#    endif /* MM_USER_HEAP_EXTRAM */
+
+#  endif /* CONFIG_BUILD_PROTECTED */
+
+#else /* !CONFIG_MM_KERNEL_HEAP */
+  ubase = (uintptr_t)_sheap;
+  utop  = HEAP_REGION1_END;
+  usize = utop - ubase;
+#endif /* CONFIG_MM_KERNEL_HEAP */
 
   minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
         ubase, utop, usize);
 
+  DEBUGASSERT(utop > ubase);
+
   board_autoled_on(LED_HEAPALLOCATE);
 
   /* Return the userspace heap settings */
 
   *heap_start = (void *)ubase;
   *heap_size  = usize;
-#else
-  board_autoled_on(LED_HEAPALLOCATE);
-
-  *heap_start = (void *)_sheap;
-  DEBUGASSERT(HEAP_REGION1_END > (uintptr_t)*heap_start);
-  *heap_size = (size_t)(HEAP_REGION1_END - (uintptr_t)*heap_start);
-#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */
 }
 
 /****************************************************************************
@@ -114,30 +142,44 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
  *   userspace heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
  *   (and protects) the kernel space heap.
  *
+ *   For Flat build (CONFIG_BUILD_FLAT=y), this function enables a separate
+ *   (although unprotected) heap for the kernel.
+ *
  ****************************************************************************/
 
-#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) && \
-    defined(__KERNEL__)
+#ifdef CONFIG_MM_KERNEL_HEAP
 void up_allocate_kheap(void **heap_start, size_t *heap_size)
 {
+  uintptr_t kbase;
+  uintptr_t ktop;
+  size_t    ksize;
+
+#ifdef CONFIG_BUILD_PROTECTED
   /* These values come from the linker scripts (kernel-space.ld and
    * protected_memory.ld).
    * Check boards/xtensa/esp32.
    */
 
-  uintptr_t kbase = (uintptr_t)_sheap;
-  uintptr_t ktop  = KDRAM_0_END;
-  size_t    ksize = ktop - kbase;
+  kbase = (uintptr_t)_sheap;
+  ktop  = KDRAM_0_END;
+  ksize = ktop - kbase;
+#elif defined(CONFIG_BUILD_FLAT)
+  kbase = (uintptr_t)_sheap;
+  ktop  = HEAP_REGION1_END;
+  ksize = ktop - kbase;
+#endif
 
   minfo("Heap: start=%" PRIxPTR " end=%" PRIxPTR " size=%zu\n",
         kbase, ktop, ksize);
 
+  DEBUGASSERT(ktop > kbase);
+
   board_autoled_on(LED_HEAPALLOCATE);
 
   *heap_start = (void *)kbase;
   *heap_size  = ksize;
 }
-#endif /* CONFIG_BUILD_PROTECTED && CONFIG_MM_KERNEL_HEAP */
+#endif /* CONFIG_MM_KERNEL_HEAP */
 
 /****************************************************************************
  * Name: xtensa_add_region
@@ -168,7 +210,7 @@ void xtensa_add_region(void)
   availregions = 2;
 #endif
 
-#if defined(CONFIG_ESP32_SPIRAM) && !defined(CONFIG_BUILD_PROTECTED)
+#ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP
   availregions++;
 #endif
 
@@ -184,6 +226,7 @@ void xtensa_add_region(void)
   MM_ADDREGION(start, size);
 #endif
 
+#ifndef MM_USER_HEAP_IRAM
   /* Skip internal heap region if CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP is
    * enabled.
    */
@@ -191,6 +234,7 @@ void xtensa_add_region(void)
   start = (void *)ESP32_IMEM_START + XTENSA_IMEM_REGION_SIZE;
   size  = (size_t)(uintptr_t)_eheap - (size_t)start;
   MM_ADDREGION(start, size);
+#endif
 
 #ifndef CONFIG_ESP32_BLE
   start = (void *)HEAP_REGION0_START;
@@ -198,17 +242,16 @@ void xtensa_add_region(void)
   MM_ADDREGION(start, size);
 #endif
 
-#if defined(CONFIG_ESP32_SPIRAM) && defined(CONFIG_ARCH_HAVE_HEAP2)
+#ifdef CONFIG_ESP32_SPIRAM_COMMON_HEAP
 #ifdef CONFIG_XTENSA_EXTMEM_BSS
   start = (void *)(_ebss_extmem);
-  size = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem);
+  size  = CONFIG_HEAP2_SIZE - (size_t)(_ebss_extmem - _sbss_extmem);
 #else
   start = (void *)CONFIG_HEAP2_BASE;
-  size = CONFIG_HEAP2_SIZE;
+  size  = CONFIG_HEAP2_SIZE;
 #endif
-#ifdef CONFIG_ESP32_SPIRAM_BANKSWITCH_ENABLE
   size -= esp_himem_reserved_area_size();
-#endif
+
   MM_ADDREGION(start, size);
 #endif
 }
diff --git a/arch/xtensa/src/esp32/esp32_himem.h b/arch/xtensa/src/esp32/esp32_himem.h
index 1f29c51154..d2da026372 100644
--- a/arch/xtensa/src/esp32/esp32_himem.h
+++ b/arch/xtensa/src/esp32/esp32_himem.h
@@ -27,6 +27,8 @@
 
 #include <stddef.h>
 
+#include <nuttx/himem/himem.h>
+
 #ifdef __cplusplus
 extern "C"
 {
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig
index 83fc9f0158..6782e9f08d 100644
--- a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig
@@ -21,12 +21,13 @@ CONFIG_ARCH_XTENSA=y
 CONFIG_BOARD_LOOPSPERMSEC=16717
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
+CONFIG_ESP32_IMM_HEAP=y
 CONFIG_ESP32_SPIRAM=y
 CONFIG_ESP32_UART0=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
 CONFIG_HAVE_CXXINITIALIZE=y
-CONFIG_HEAP2_BASE=0x3F800000
+CONFIG_HEAP2_BASE=0x3f800000
 CONFIG_HEAP2_SIZE=4194304
 CONFIG_IDLETHREAD_STACKSIZE=3072
 CONFIG_INIT_ENTRYPOINT="nsh_main"
@@ -47,7 +48,6 @@ CONFIG_RAM_START=0x20000000
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_HPWORK=y
 CONFIG_SCHED_WAITPID=y
-CONFIG_SPI=y
 CONFIG_START_DAY=6
 CONFIG_START_MONTH=12
 CONFIG_START_YEAR=2011
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig
similarity index 91%
copy from boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig
copy to boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig
index 83fc9f0158..65f23cad03 100644
--- a/boards/xtensa/esp32/esp32-devkitc/configs/psram/defconfig
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/psram_usrheap/defconfig
@@ -22,11 +22,12 @@ CONFIG_BOARD_LOOPSPERMSEC=16717
 CONFIG_BUILTIN=y
 CONFIG_DEV_ZERO=y
 CONFIG_ESP32_SPIRAM=y
+CONFIG_ESP32_SPIRAM_USER_HEAP=y
 CONFIG_ESP32_UART0=y
 CONFIG_FS_PROCFS=y
 CONFIG_HAVE_CXX=y
 CONFIG_HAVE_CXXINITIALIZE=y
-CONFIG_HEAP2_BASE=0x3F800000
+CONFIG_HEAP2_BASE=0x3f800000
 CONFIG_HEAP2_SIZE=4194304
 CONFIG_IDLETHREAD_STACKSIZE=3072
 CONFIG_INIT_ENTRYPOINT="nsh_main"
@@ -35,7 +36,7 @@ CONFIG_IOB_NBUFFERS=36
 CONFIG_IOB_NCHAINS=36
 CONFIG_IOB_THROTTLE=8
 CONFIG_MM_IOB=y
-CONFIG_MM_REGIONS=4
+CONFIG_MM_REGIONS=3
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_FILEIOSIZE=512
@@ -47,10 +48,11 @@ CONFIG_RAM_START=0x20000000
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_HPWORK=y
 CONFIG_SCHED_WAITPID=y
-CONFIG_SPI=y
 CONFIG_START_DAY=6
 CONFIG_START_MONTH=12
 CONFIG_START_YEAR=2011
 CONFIG_SYSTEM_NSH=y
 CONFIG_SYSTEM_RAMTEST=y
+CONFIG_TESTING_GETPRIME=y
+CONFIG_TESTING_OSTEST=y
 CONFIG_UART0_SERIAL_CONSOLE=y