From 9cf38e7fbeb054aecd21086cfb673361589bb72f Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 29 Sep 2026 14:53:52 +0300 Subject: [PATCH] arch/arm/imxrt: Make performance optimized memory configuration for M7 NSH Change the imxrt1180-evk M7 NSH configuration to use the SoC memories more efficiently: - Place .data, .bss, idle stack and primary heap into DTCM - Allocate available OCRAM as a secondary heap - Add a separate .dmamemory section in OCRAM for USB device DMA allocations - Place .ramfunc into ITCM, together with hand-picked "hot" functions. The section is copied to ITCM at boot by the ramfunc copy. The eDMA accesses DTCM through the SoC's dedicated bus window. This configuration acts as an example of performance optimization for imxrt1180 based boards. Signed-off-by: Jukka Laitinen --- arch/arm/src/imxrt/imxrt_allocateheap.c | 14 ++++- arch/arm/src/imxrt/imxrt_start.c | 4 +- .../imxrt/imxrt1180-evk/configs/nsh/defconfig | 9 ++- .../arm/imxrt/imxrt1180-evk/scripts/flash.ld | 60 +++++++++++++------ 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/arch/arm/src/imxrt/imxrt_allocateheap.c b/arch/arm/src/imxrt/imxrt_allocateheap.c index b6a040cfaf5..2fca4332358 100644 --- a/arch/arm/src/imxrt/imxrt_allocateheap.c +++ b/arch/arm/src/imxrt/imxrt_allocateheap.c @@ -204,7 +204,19 @@ extern const uint32_t _ram_size[]; /* See linker script */ * already been assigned as the primary RAM. */ -#if defined(CONFIG_IMXRT_OCRAM_HEAP) && !defined(IMXRT_OCRAM_ASSIGNED) +#if defined(CONFIG_IMXRT_TCM_PRIMARY) && \ + defined(CONFIG_IMXRT_OCRAM_HEAP) +/* With TCM as primary RAM, the linker defines the usable OCRAM range so + * that board-reserved and DMA-only storage is excluded. + */ + +extern const uint8_t _socramheap[]; +extern const uint8_t _eocramheap[]; +# define REGION1_RAM_START ((uintptr_t)_socramheap) +# define REGION1_RAM_SIZE ((uintptr_t)_eocramheap - \ + (uintptr_t)_socramheap) +# define IMXRT_OCRAM_ASSIGNED 1 +#elif defined(CONFIG_IMXRT_OCRAM_HEAP) && !defined(IMXRT_OCRAM_ASSIGNED) # define REGION1_RAM_START IMXRT_OCRAM_START # define REGION1_RAM_SIZE IMXRT_OCRAM_SIZE # define IMXRT_OCRAM_ASSIGNED 1 diff --git a/arch/arm/src/imxrt/imxrt_start.c b/arch/arm/src/imxrt/imxrt_start.c index 5fcf30cb8ff..02b807aa7ad 100644 --- a/arch/arm/src/imxrt/imxrt_start.c +++ b/arch/arm/src/imxrt/imxrt_start.c @@ -135,7 +135,7 @@ static inline void imxrt_tcmenable(void) UP_MB(); -#ifdef CONFIG_ARMV7M_ITCM +#if defined(CONFIG_ARMV7M_ITCM) && !defined(CONFIG_ARCH_FAMILY_IMXRT118x) /* Copy TCM code from flash to ITCM */ #warning Missing logic @@ -212,7 +212,7 @@ void __start(void) } /* Copy any necessary code sections from FLASH to RAM. The correct - * destination in OCRAM is given by _sramfuncs and _eramfuncs. The + * destination in RAM is given by _sramfuncs and _eramfuncs. The * temporary location is in flash after the data initialization code * at _framfuncs. This should be done before imxrt_clockconfig() is * called (in case it has some dependency on initialized C variables). diff --git a/boards/arm/imxrt/imxrt1180-evk/configs/nsh/defconfig b/boards/arm/imxrt/imxrt1180-evk/configs/nsh/defconfig index 0511631a8c5..2306538993b 100644 --- a/boards/arm/imxrt/imxrt1180-evk/configs/nsh/defconfig +++ b/boards/arm/imxrt/imxrt1180-evk/configs/nsh/defconfig @@ -41,10 +41,13 @@ CONFIG_EXAMPLES_BUTTONS_NAMES=y CONFIG_EXAMPLES_BUTTONS_QTD=1 CONFIG_FS_NAMED_SEMAPHORES=y CONFIG_FS_PROCFS=y +CONFIG_GRAN=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_IMXRT_EDMA=y CONFIG_IMXRT_GPIO_IRQ=y CONFIG_IMXRT_LPUART1=y +CONFIG_IMXRT_OCRAM_HEAP=y +CONFIG_IMXRT_TCM_PRIMARY=y CONFIG_IMXRT_USBDEV=y CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INIT_STACKSIZE=8192 @@ -57,14 +60,15 @@ CONFIG_LINE_MAX=64 CONFIG_LPUART1_RXDMA=y CONFIG_LPUART1_SERIAL_CONSOLE=y CONFIG_LPUART1_TXDMA=y +CONFIG_MM_REGIONS=2 CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_DISABLE_IFUPDOWN=y CONFIG_NSH_FILEIOSIZE=512 CONFIG_NSH_READLINE=y CONFIG_PTHREAD_MUTEX_TYPES=y CONFIG_PTHREAD_STACK_DEFAULT=8192 -CONFIG_RAM_SIZE=491520 -CONFIG_RAM_START=0x20484000 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x20000000 CONFIG_RAW_BINARY=y CONFIG_RR_INTERVAL=200 CONFIG_SCHED_BACKTRACE=y @@ -83,4 +87,5 @@ CONFIG_TLS_NCLEANUP=4 CONFIG_TLS_NELEM=4 CONFIG_USBDEV=y CONFIG_USBDEV_DMA=y +CONFIG_USBDEV_DMAMEMORY=y CONFIG_USBDEV_DUALSPEED=y diff --git a/boards/arm/imxrt/imxrt1180-evk/scripts/flash.ld b/boards/arm/imxrt/imxrt1180-evk/scripts/flash.ld index 09e23a86f36..17d098c3869 100644 --- a/boards/arm/imxrt/imxrt1180-evk/scripts/flash.ld +++ b/boards/arm/imxrt/imxrt1180-evk/scripts/flash.ld @@ -30,18 +30,17 @@ * 0x2800_0000 .. 0x2807_FFFF M33 image (512 KB reserved) * 0x2808_0000 .. 0x287F_FFFF M7 image (this script, 7.5 MB window) * - * NuttX's stack, .data, .ramfunc and .bss live in OCRAM1, which the M33 - * grants the M7 R/W/X through TRDC2 MRC_W3 before releasing it. DTCM and - * ITCM are declared above but are not used by any section; they are - * tightly-coupled to the M7 core and have no TRDC in the access path, so - * they remain available for opt-in placement. + * NuttX's .data, .bss, idle stack and primary heap live in DTCM. OCRAM1, + * which the M33 grants the M7 R/W/X through TRDC2 MRC_W3 before releasing + * it, holds USB DMA storage and the secondary heap. ITCM holds the + * .ramfunc section, including selected hot code. */ MEMORY { flash (rx) : ORIGIN = 0x28080000, LENGTH = 4M /* Cortex-M7 XIP window (after the 512K M33/bl reserve) */ ocram (rwx) : ORIGIN = 0x20484000, LENGTH = 480K /* OCRAM1 minus ROM patch (0x20480000..0x20483fff) and M33 reserve (0x204fc000..0x204fffff) */ - dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K /* M7 DTCM (opt-in) */ + dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 256K /* M7 DTCM primary RAM */ itcm (rwx) : ORIGIN = 0x00000000, LENGTH = 256K /* M7 ITCM (opt-in) */ } @@ -51,10 +50,34 @@ ENTRY(_stext) SECTIONS { - .text : ALIGN(4) + .vectors : { _stext = ABSOLUTE(.); - *(.vectors) + KEEP(*(.vectors)) + } > flash + + .ramfunc : + { + . = ALIGN(8); + _sramfuncs = ABSOLUTE(.); + FILL(0xff) + . = 0x40; + *(.text.exception_common) + *(.text.arm_doirq) + *(.text.arm_ack_irq) + *(.text.irq_dispatch) + *(.text.imxrt_gpio_interrupt) + *(.text.memcpy) + *(.text.memset) + *(.ramfunc .ramfunc.*) + . = ALIGN(8); + _eramfuncs = ABSOLUTE(.); + } > itcm AT > flash + + _framfuncs = LOADADDR(.ramfunc); + + .text : ALIGN(4) + { *(.text .text.*) *(.fixup) *(.gnu.warning) @@ -111,16 +134,19 @@ SECTIONS CONSTRUCTORS . = ALIGN(4); _edata = ABSOLUTE(.); - } > ocram AT > flash + } > dtcm AT > flash - .ramfunc ALIGN(4): + .dmamemory (NOLOAD) : { - _sramfuncs = ABSOLUTE(.); - *(.ramfunc .ramfunc.*) - _eramfuncs = ABSOLUTE(.); - } > ocram AT > flash + . = ALIGN(2048); + _sdmamemory = ABSOLUTE(.); + *(.dmamemory .dmamemory.*) + . = ALIGN(32); + _edmamemory = ABSOLUTE(.); + } > ocram - _framfuncs = LOADADDR(.ramfunc); + _socramheap = ALIGN(8); + _eocramheap = ORIGIN(ocram) + LENGTH(ocram); .bss : { @@ -130,7 +156,7 @@ SECTIONS *(COMMON) . = ALIGN(8); _ebss = ABSOLUTE(.); - } > ocram + } > dtcm /* Stabs debugging sections. */ @@ -149,5 +175,5 @@ SECTIONS _boot_loadaddr = ORIGIN(flash); _boot_size = LENGTH(flash); - _ram_size = LENGTH(ocram); + _ram_size = LENGTH(dtcm); }