2023-06-27 11:36 PM
Hi, still can't to upload frontend heap to my 8MB external SDRAM.
My linker script:
/*
******************************************************************************
**
** File : LinkerScript.ld
**
** Author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7 series
** 2048Kbytes FLASH and 1056Kbytes 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) 2022 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_D1) + LENGTH(RAM_D1); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 16M
SDRAM (xrw) : ORIGIN = 0xC0000000, LENGTH = 8M
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.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 goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
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 goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM_D1 AT> FLASH
/* Uninitialized data section */
. = 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 left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM_D1
.sdram_section (NOLOAD) : { *(.sdram_section) }> SDRAM
TouchGFX_Framebuffer (NOLOAD) : { *(TouchGFX_Framebuffer) } >SDRAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
FontFlashSection(NOLOAD) : /*DELETE (NOLOAD) IF U WANT TO UPDATE QSPI FLASH*/
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
TextFlashSection(NOLOAD) :/*DELETE (NOLOAD) IF U WANT TO UPDATE QSPI FLASH*/
{
*(TextFlashSection TextFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
ExtFlashSection(NOLOAD) :/*DELETE (NOLOAD) IF U WANT TO UPDATE QSPI FLASH*/
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >QUADSPI
}
I placed my double framebuffer to other address:
Set framebuffer in LTDC start:
And add line to FrontendHeap.hpp:
And I always get hardfault at : (__attribute__ ((section (".sdram_section")))) .Maybe someone see the mistake and can help? Thank you.
2023-06-29 11:09 PM
Now it crashes here :
2023-06-30 01:24 AM
The framebuffer is not initialized by C++.
Could you provide a stack trace when you get the fault? and also disassembly of the code.
In some cases it is a wrong configuration of SDRAM. The DMA2D and LTDC performs block access to the frame buffer, but the code may use byte access to the heap.
Can you test that byte access is working. Try reading and writing all 4 bytes in a word in SDRAM.
2023-06-30 01:25 AM
BTW, what is the reason to move the heap to SDRAM? How big is your heap?
Maybe you can move just one big element to SDRAM. E.g. if you have a big array in Model.
2023-06-30 01:42 AM - edited 2023-06-30 02:18 AM
It looks like my SDRAM is working correctly:
I have a lot of arrays in model.hpp. It would be great to store frontend heap to my external SDRAM cause in RAM_D1 left only 100KB
Now I get MemManage_Handler:
2023-07-05 03:06 AM
How to config MPU if I want to store FrontendHeap to my external SDRAM?
2023-10-29 12:09 PM
were you able to solve the problem? I am having a similar problem. I have a section defined in my linker for SDRAM that is used to store large amounts of data. I also have touchGFX configured—my system hard-fault when I try to access the data in SDRAM.
2023-10-30 02:10 AM
Hello Cleonb322
You should start by testing your SDRAM. Write a program that write bytes, shorts, and words to different addresses in the SDRAM. Then read the values to check that it is correct.
It is important that you can write bytes in all addresses, without modifying the nearby bytes.
2023-10-30 06:28 AM
I'm using the SDRAM for TouchGFX. It crashes only when I try to define a struct in SDRAM.
2023-10-30 06:31 AM
Do you mean that you have your framebuffers in SDRAM and that works?
Then this is only using 16bit access (assuming you have 16 bit colors) and maybe only is large chunks.
Try to see if you can read and write chars in the first addresses of the framebuffer.
2023-10-30 09:18 AM
yes, my framebuffer works just fine. I was able to get my struct variable working (it no longer crashes) by forcing my struct alignment with "__attribute__((aligned(4)))". I guess I do not have access to individual bytes that are not aligned by 4. I will have to do some more research and testing. or maybe the issue is with the way I cast my variable.
See the attached file for an example of my variable usage: