cancel
Showing results for 
Search instead for 
Did you mean: 

Why the touchgfx framebuffer goes into flash?

amb
Associate III

I made a touchgfx project by CubeIDE,when I choose touchgfx framebuffer by allocation,after build ,the framebuffer is placed into flash,then ram.I wonder why.

1 ACCEPTED SOLUTION

Accepted Solutions

Hi @amb ,

It seems to be located at RAM 0x2001b0 right ? I guess the issue is that it is initialized by C++ RTE. The frame buffers needs to be marked by some gcc speciofic __attribute__, hm is it 'noinit' ?

[Edit]

https://www.nongnu.org/avr-libc/user-manual/mem_sections.html

The .noinit Section

This sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such:

int foo __attribute__ ((section (".noinit")));

will not be initialized to zero during startup as would normal .bss data.

 

[Edit 2]

I see file

\ST\touchgfx\framework\include\touchgfx\hal\Config.hpp

has many defines dealing with that sort of problems. It is a jungle and I run simulation so cant check with embedded toolchain.

View solution in original post

9 REPLIES 9
SofLit
ST Employee

Hello,

The framebuffer needs to be in the RAM (either internal or external). But how you did conclude that the frame buffer is located in the Flash? Which board are you using? ST or custom board? which MCU?

Need to provide more details, so TouchGFX expert(s) could help you.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
amb
Associate III

this is the memory details form CubeIDE.

20240618224152.jpg

this is touchgfx settings

微信截图_20240618224550.jpg

Osman SOYKURT
ST Employee

Hello @amb,

Could you share with us your linker script? 

Osman SOYKURT
ST Software Developer | TouchGFX

Hi @amb ,

It seems to be located at RAM 0x2001b0 right ? I guess the issue is that it is initialized by C++ RTE. The frame buffers needs to be marked by some gcc speciofic __attribute__, hm is it 'noinit' ?

[Edit]

https://www.nongnu.org/avr-libc/user-manual/mem_sections.html

The .noinit Section

This sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such:

int foo __attribute__ ((section (".noinit")));

will not be initialized to zero during startup as would normal .bss data.

 

[Edit 2]

I see file

\ST\touchgfx\framework\include\touchgfx\hal\Config.hpp

has many defines dealing with that sort of problems. It is a jungle and I run simulation so cant check with embedded toolchain.

amb
Associate III

I found the framebuf[] in TouchGFXGeneratedHAL.cpp file.It says this:

 

// Use the section "TouchGFX_Framebuffer" in the linker script to specify the placement of the buffer

LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer")

uint32_t frameBuf[(480 * 480 * 2 + 3) / 4] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer");

static uint16_t lcd_int_active_line;

static uint16_t lcd_int_porch_line;

 

this file is auto generated,I didnt change it.

/*

******************************************************************************

**

** File : LinkerScript.ld

**

** Author : STM32CubeIDE

**

** Abstract : Linker script for STM32U599xJ Device from STM32U5 series

** 4096Kbytes FLASH

** 2512Kbytes RAM

**

** 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

**

** Copyright (c) 2024 STMicroelectronics.

** All rights reserved.

**

** This software is licensed under terms that can be found in the LICENSE file

** in the root directory of this software component.

** If no LICENSE file comes with this software, it is provided AS-IS.

**

*****************************************************************************

*/

 

/* Entry Point */

ENTRY(Reset_Handler)

 

/* Highest address of the user mode stack */

_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */

 

_Min_Heap_Size = 0x200; /* required amount of heap */

_Min_Stack_Size = 0x400; /* required amount of stack */

 

/* Memories definition */

MEMORY

{

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2496K

SRAM4 (xrw) : ORIGIN = 0x28000000, LENGTH = 16K

FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 4096K

}

 

/* Sections */

SECTIONS

{

/* The startup code into "FLASH" Rom type memory */

.isr_vector :

{

KEEP(*(.isr_vector)) /* Startup code */

} >FLASH

 

/* The program code and other data into "FLASH" Rom type memory */

.text :

{

*(.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))

 

_etext = .; /* define a global symbols at end of code */

} >FLASH

 

/* Constant data into "FLASH" Rom type memory */

.rodata :

{

*(.rodata) /* .rodata sections (constants, strings, etc.) */

*(.rodata*) /* .rodata* sections (constants, strings, etc.) */

} >FLASH

 

.ARM.extab (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */

{

*(.ARM.extab* .gnu.linkonce.armextab.*)

} >FLASH

.ARM (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */

{

__exidx_start = .;

*(.ARM.exidx*)

__exidx_end = .;

} >FLASH

 

.preinit_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */

{

PROVIDE_HIDDEN (__preinit_array_start = .);

KEEP (*(.preinit_array*))

PROVIDE_HIDDEN (__preinit_array_end = .);

} >FLASH

 

.init_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */

{

PROVIDE_HIDDEN (__init_array_start = .);

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array*))

PROVIDE_HIDDEN (__init_array_end = .);

} >FLASH

 

.fini_array (READONLY) : /* The READONLY keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */

{

PROVIDE_HIDDEN (__fini_array_start = .);

KEEP (*(SORT(.fini_array.*)))

KEEP (*(.fini_array*))

PROVIDE_HIDDEN (__fini_array_end = .);

} >FLASH

 

/* Used by the startup to initialize data */

_sidata = LOADADDR(.data);

 

/* Initialized data sections into "RAM" Ram type memory */

.data :

{

_sdata = .; /* create a global symbol at data start */

*(.data) /* .data sections */

*(.data*) /* .data* sections */

*(.RamFunc) /* .RamFunc sections */

*(.RamFunc*) /* .RamFunc* sections */

 

_edata = .; /* define a global symbol at data end */

} >RAM AT> FLASH

 

/* Uninitialized data section into "RAM" Ram type memory */

.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)

 

_ebss = .; /* define a global symbol at bss end */

__bss_end__ = _ebss;

} >RAM

 

/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */

._user_heap_stack :

{

. = ALIGN(8);

PROVIDE ( end = . );

PROVIDE ( _end = . );

. = . + _Min_Heap_Size;

. = . + _Min_Stack_Size;

. = ALIGN(8);

} >RAM

 

/* Remove information from the compiler libraries */

/DISCARD/ :

{

libc.a ( * )

libm.a ( * )

libgcc.a ( * )

}

 

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

}

 

amb
Associate III

hello @ferro 

I tried change like this:

uint32_t frameBuf[(480 * 480 * 2 + 3) / 4] __attribute__ ((section (".noinit")));

this frameBuf array is indeed only in ram now.and the program still works fine.

微信截图_20240620222003.png

thanks for your advice.

Hi @amb 

>"frameBuf array is indeed only in ram now"

Splendid. But still, it is strange that the frameBuf with all the ornamentation

 

LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer")
uint32_t frameBuf[(480 * 480 * 2 + 3) / 4] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer");

 

 was initialised. Could you please try again the old version and see if the flashing of the FW is noticably longer compared to correct version ? To flash 0.5 MB (framebuffer initialisation) seems like a lot. Maybe other people waste lot of FLASH and time waiting to flash this as well. Might require Gfx fix; maybe add some warning or even throw a compiler error.

amb
Associate III

hello @ferro 

The answer is affirmtive. this is log output using (noinit):

Memory Programming ...

Opening and parsing file: ST-LINK_GDB_server_a18780.srec

File : ST-LINK_GDB_server_a18780.srec

Size : 442.54 KB

Address : 0x08000000

 

 

Erasing memory corresponding to segment 0:

Erasing internal memory sectors [0 55]

Download in Progress:

 

 

File download complete

Time elapsed during download operation: 00:00:05.514

 

and this is log output using(LOCATION_PRAGMA_NOLOAD:(

Memory Programming ...

Opening and parsing file: ST-LINK_GDB_server_a19312.srec

File : ST-LINK_GDB_server_a19312.srec

Size : 892.54 KB

Address : 0x08000000

 

 

Erasing memory corresponding to segment 0:

Erasing internal memory sectors [0 111]

Download in Progress:

 

 

File download complete

Time elapsed during download operation: 00:00:10.102

 

So,the flash occupied 55 sectors VS 111 sectors,and the flashing time is 5.5s VS 10.1s,

significantly longer.

download size have 450kb difference, that is exactly my framebuffer size:480*480*2.