Skip to main content
Associate II
February 13, 2025
Solved

TouchGFX Custom Application FLASH Overflow Issue & QSPI Memory Setup

  • February 13, 2025
  • 4 replies
  • 1718 views

 

 

Subject: TouchGFX Custom Application FLASH Overflow Issue & QSPI Memory Setup

Greetings Team,

I’m new to STM32 TouchGFX and trying to create a custom TouchGFX application following How to integrate TouchGFX in a custom board (The long way round) - YouTube

After setting everything up, I encountered the following error during the build:

`.text' will not fit in region `FLASH' region `FLASH' overflowed by 296512 bytes 

 

I understand that my MCU has only 128KB of Flash, which is insufficient for TouchGFX. I want to configure TouchGFX to use only SDRAM instead of Flash. How does TouchGFX utilize SDRAM, and how can I correctly set it up for this purpose?

Additionally, when comparing my custom application to the STM32H7 Dev Board example, I noticed different memory configurations in the Cortex-M7 section under System Core. Specifically, I don’t fully understand how QSPI Flash is mapped as two memory regions starting from 0x90000000.

I've attached a screenshot for reference. Kindly guide me on resolving the FLASH overflow issue and understanding the QSPI memory setup.

Thanks in advance!

Screenshot 2025-02-13 164135.png

This topic has been closed for replies.
Best answer by Osman SOYKURT

Hello @naveen ,

I don't really understand why you want TouchGFX to use only SDRAM instead of Flash? You said you have external QSPI Flash right? I would recommend to use RAM for framebuffers and assets in external flash as we do in our STM32H750-DK TBS.
@Tesla DeLorean is right, in our TBS, the 128KB of internal FLASH is used as boot loader: as we write in our readme file :

The STM32H750xx value line come with only 128KB internal flash.
These value line devices are intended for code execution from external memories.
This example shows how to boot from internal flash, configure external memories
then jump to user application located on external memory.


I invite you to check our TBS that we provide in TouchGFX Designer if you want to see how it is done.

OsmanSOYKURT_0-1739797101036.png

4 replies

Tesla DeLorean
Guru
February 13, 2025

Which MCU do you have? The STM32H750?

The 128KB of internal FLASH would likely need to act as a boot loader, bringing up clocks, pins, QSPI (0x90000000) and SDRAM (0xC0000000) and then moving your TouchGFX app into memory and executing it there, ie transfer control to image in SDRAM if that's what you want to do.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
February 13, 2025

Part of bring up the QSPI interface is that you initialize the memory IC, and then provide a read command template to access it via the 0x90000000 address decode window, this is defined as this per Reference Manual.

The compiler and Linker use the Linker Script to describe the areas the build should be placing code and data items within the address space.

If the code is going to run in the SDRAM you should build for 0xC0000000. You might need to store or stage it elsewhere as the memory is volatile, so needs the image copied at startup.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
naveenAuthor
Associate II
February 14, 2025

can you please share the resource for how to achieve this. anything like document or video reference. it would really help me a lot.

thanking you in advance.

Osman SOYKURT
Osman SOYKURTBest answer
Technical Moderator
February 17, 2025

Hello @naveen ,

I don't really understand why you want TouchGFX to use only SDRAM instead of Flash? You said you have external QSPI Flash right? I would recommend to use RAM for framebuffers and assets in external flash as we do in our STM32H750-DK TBS.
@Tesla DeLorean is right, in our TBS, the 128KB of internal FLASH is used as boot loader: as we write in our readme file :

The STM32H750xx value line come with only 128KB internal flash.
These value line devices are intended for code execution from external memories.
This example shows how to boot from internal flash, configure external memories
then jump to user application located on external memory.


I invite you to check our TBS that we provide in TouchGFX Designer if you want to see how it is done.

OsmanSOYKURT_0-1739797101036.png

Osman SOYKURTST Software Developer | TouchGFX
Associate II
November 13, 2025

Hello !

This looks like a promising solution, I am also on this STM32H750b - DK , however, I am using a custom display via the LTDC /1024x600, 24bit and Touch GFX  ...

The memory is enabled, namely "External memory" QUADSPI 256MB, I can see this memory starting at the 0x90000000 in the Cube IDE, namely 'Build analyzer' and its 'Memory Regions'

my_memory.png

So far so good, however, when compiling, I am getting the following error when the Touch GFX is enabled : 

14:13:25 **** Incremental Build of configuration Debug for project My_LCD_Touch ****
make -j4 all 
arm-none-eabi-g++ -o "My_LCD_Touch.elf" @"objects.list" -l:libtouchgfx-float-abi-hard.a -mcpu=cortex-m7 -T"C:\Users\Administrator\STM32CubeIDE\LCD_SCT\My_LCD_Touch\STM32H750XBHX_FLASH_MMT_TEMPLATE.ld" --specs=nosys.specs -Wl,-Map="My_LCD_Touch.map" -Wl,--gc-sections -static -L"C:\Users\Administrator\STM32CubeIDE\LCD_SCT\My_LCD_Touch\Middlewares\ST\touchgfx\lib\core\cortex_m7\gcc" --specs=nano.specs -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
C:/ST/STM32CubeIDE_1.13.2/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: My_LCD_Touch.elf section `.text' will not fit in region `FLASH'
C:/ST/STM32CubeIDE_1.13.2/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: region `FLASH' overflowed by 192116 bytes
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:106: My_LCD_Touch.elf] Error 1
"make -j4 all" terminated with exit code 2. Build might be incomplete.

14:13:27 Build Failed. 3 errors, 0 warnings. (took 2s.121ms)

I am very optimistic about it; I got down from 9 to 3 errors :) learning curve!

As far as I have understood the 'Memory Management Tool' this is my 'Default Data Region'? My memory setup so far:

my_MMT.png

So, this is what I know so far about how to go around this... indeed, the Linker has not been addressed, I guess the Linker does not know about the available memory, wondering, if that is an issue or is something else? 

Any comments, ideas, solutions how to get around this problem are more than welcome and of course appreciated!

Best.

 

Osman SOYKURT
Technical Moderator
February 25, 2025

Hello @naveen ,

Have you been able to move on with your issue?

Osman SOYKURTST Software Developer | TouchGFX
naveenAuthor
Associate II
March 4, 2025

Hello @Osman SOYKURT 
sorry for the delay in replay. I been trying to solve another problem. 
and for your question my answer is No.
Can you guide me how to create a custom Touch-GFX frame Application for my custom board like how designer is generating respective Application when we selected dev-kit from it. 

I Am using stm32h750xbh6 MCU and 12.1 Inch Color TFT-LCD display in this project. 
I have attached datasheet of my display for your reference.


Osman SOYKURT
Technical Moderator
December 4, 2025

Hello @total_and_STM32 ,

Sorry for the late reply but we missed your message (I recommend you to open a new forum post in future if you need help for your own application). It would be interesting to see your linker script because right now it seems like you're trying to fill your internal flash section (128 KB) and not the external QSPI.

Osman SOYKURTST Software Developer | TouchGFX
Associate II
December 4, 2025

Hello @Osman SOYKURT 

Thank you for your reply.

Indeed, the linked script is something I am still not sure how exactly it works.

Anyway, what I have done is to use the "TBS"  in the Designer and open it in the CubeIDE, where the LTDC was updated for the custom LCD.  Indeed, the GPIOs are the same as for the original LCD that comes with the STM32H750B-DK. For example, I can use and preview the primitive graphics, like circles, etc. via the original LTDC util functions in Keil just fine. However, I do not have much luck with setting up the TouchGFX in CubeIDE. 

Anyway, I have managed the compilation, and I get "some graphics" on my display.

Creating a new forum post.

Best.

/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author		: Auto-generated by STM32CubeIDE
**
** Abstract : Linker script for STM32H750XBHx Device from STM32H7 series
** 128Kbytes FLASH
** 128Kbytes DTCMRAM
** 64Kbytes ITCMRAM
** 512Kbytes RAM_D1
** 288Kbytes RAM_D2
** 64Kbytes RAM_D3
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of STMicroelectronics nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*/

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1);	/* end of "RAM_D1" Ram type memory */

_Min_Heap_Size = 0x1000;	/* required amount of heap */
_Min_Stack_Size = 0x1000;	/* required amount of stack */

/* Memories definition */
MEMORY
{
 DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
 ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
 RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
 RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
 RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
 SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 8M
 FLASH	 (xrw) : ORIGIN = 0x90000000, LENGTH = 2048K
 ASSETS_FLASH (r) : ORIGIN = 0x90200000, LENGTH = 126M
 BOOTLOADER (xrw) : ORIGIN = 0x08000000, LENGTH = 128k
}

TARGET(binary) /* specify the file format of binary file */
INPUT (../../ExtMem_Boot/bootloader.bin) /* bootloader bin file path (relative to the output folder)*/
OUTPUT_FORMAT(default) /* restore the out file format */

/* Sections */
SECTIONS
{
 .bootloader :
 {
 . = ALIGN(4);
 KEEP(../../ExtMem_Boot/bootloader.bin)
 } > BOOTLOADER

 /* The startup code into "FLASH" Rom type memory */
 .isr_vector :
 {
 __ICFEDIT_intvec_start__ = .;
 . = ALIGN(4);
 KEEP(*(.isr_vector)) /* Startup code */
 . = ALIGN(4);
 } >FLASH

 /* The program code and other data into "FLASH" Rom type memory */
 .text :
 {
 . = ALIGN(4);
 *(.text) /* .text sections (code) */
 *(.text*) /* .text* sections (code) */
 *(.glue_7) /* glue arm to thumb code */
 *(.glue_7t) /* glue thumb to arm code */
 *(.eh_frame)

 KEEP (*(.init))
 KEEP (*(.fini))

 . = ALIGN(4);
 _etext = .; /* define a global symbols at end of code */
 } >FLASH

 /* Constant data into "FLASH" Rom type memory */
 .rodata :
 {
 . = ALIGN(4);
 *(.rodata) /* .rodata sections (constants, strings, etc.) */
 *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
 . = ALIGN(4);
 } >FLASH

 .ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ 
 {
 . = ALIGN(4);
 *(.ARM.extab* .gnu.linkonce.armextab.*)
 . = ALIGN(4);
 } >FLASH

 .ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */ 
 {
 . = ALIGN(4);
 __exidx_start = .;
 *(.ARM.exidx*)
 __exidx_end = .;
 . = ALIGN(4);
 } >FLASH

 .preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__preinit_array_start = .);
 KEEP (*(.preinit_array*))
 PROVIDE_HIDDEN (__preinit_array_end = .);
 . = ALIGN(4);
 } >FLASH

 .init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__init_array_start = .);
 KEEP (*(SORT(.init_array.*)))
 KEEP (*(.init_array*))
 PROVIDE_HIDDEN (__init_array_end = .);
 . = ALIGN(4);
 } >FLASH

 .fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
 {
 . = ALIGN(4);
 PROVIDE_HIDDEN (__fini_array_start = .);
 KEEP (*(SORT(.fini_array.*)))
 KEEP (*(.fini_array*))
 PROVIDE_HIDDEN (__fini_array_end = .);
 . = ALIGN(4);
 } >FLASH

 /* Used by the startup to initialize data */
 _sidata = LOADADDR(.data);

 /* Initialized data sections into "RAM_D1" Ram type memory */
 .data :
 {
 . = ALIGN(4);
 _sdata = .; /* create a global symbol at data start */
 *(.data) /* .data sections */
 *(.data*) /* .data* sections */

 . = ALIGN(4);
 _edata = .; /* define a global symbol at data end */

 } >RAM_D1 AT> FLASH

 /* Uninitialized data section into "RAM_D1" Ram type memory */
 . = ALIGN(4);
 .bss :
 {
 /* This is used by the startup in order to initialize the .bss section */
 _sbss = .; /* define a global symbol at bss start */
 __bss_start__ = _sbss;
 *(.bss)
 *(.bss*)
 *(COMMON)

 . = ALIGN(4);
 _ebss = .; /* define a global symbol at bss end */
 __bss_end__ = _ebss;
 } >RAM_D1

 /* User_heap_stack section, used to check that there is enough "RAM_D1" Ram type memory left */
 ._user_heap_stack :
 {
 . = ALIGN(8);
 PROVIDE ( end = . );
 PROVIDE ( _end = . );
 . = . + _Min_Heap_Size;
 . = . + _Min_Stack_Size;
 . = ALIGN(8);
 } >RAM_D1

 /* Remove information from the compiler libraries */
 /DISCARD/ :
 {
 libc.a ( * )
 libm.a ( * )
 libgcc.a ( * )
 }

 .ARM.attributes 0 : { *(.ARM.attributes) }



 FontFlashSection :
 {
 *(FontFlashSection FontFlashSection.*)
 *(.gnu.linkonce.r.*)
 . = ALIGN(0x4);
 } >ASSETS_FLASH

 TextFlashSection :
 {
 *(TextFlashSection TextFlashSection.*)
 *(.gnu.linkonce.r.*)
 . = ALIGN(0x4);
 } >ASSETS_FLASH

 ExtFlashSection :
 {
 *(ExtFlashSection ExtFlashSection.*)
 *(.gnu.linkonce.r.*)
 . = ALIGN(0x4);
 } >ASSETS_FLASH

 BmpCacheSection (NOLOAD) : { *(BmpCacheSection) } >SDRAM
 TouchGFX_Framebuffer (NOLOAD) : { *(TouchGFX_Framebuffer) } >SDRAM
 TouchGFX_Framebuffer1 (NOLOAD) : { *(TouchGFX_Framebuffer1) } >SDRAM
 TouchGFX_Framebuffer2 (NOLOAD) : { *(TouchGFX_Framebuffer2) } >SDRAM
 Video_RGB_Buffer (NOLOAD) : { *(Video_RGB_Buffer) } >SDRAM

}