cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX + TouchGFX + Atollic: how to setup the QSPI external flash ?

iw2lsi
Associate III

Hi all,

I'm in trouble trying to setup the 16MByte external flash (aka Micron N25Q128) using STM32CubeMX( w/ SW4STM32) + TouchGFX + Atollic... I've setup my system as described here:

https://touchgfx.zendesk.com/hc/en-us/articles/205886201-Placing-Assets-in-Flash-Memory

and here:

https://touchgfx.zendesk.com/hc/en-us/articles/360019884752-Configuring-STM32F746G-DISCO

but the discovery board just crash.

Anyone has succesfully done this task ?

thanks,

Giampaolo

6 REPLIES 6
iw2lsi
Associate III

solved...

the main issue was in the QSPI flash memory not being programmed by Atollic.

Giampaolo

Hi Giampaolo

I am intereseted in your solution, how to setup and use the external QSPI flash.

Can you share some of your informations with me.

Thanks,

Dejan

Hello Dejan,

if I'm not wrong... the problem in my case was in the linker file... see the bold sections below...

Best Regards,

Giampaolo

/* Entry Point */

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */

_estack = 0x20050000;  /* end of RAM */

/* Generate a link error if heap and stack don't fit into RAM */

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

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

/* Specify the memory areas */

MEMORY

{

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

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

QUADSPI (rx)  : ORIGIN = 0x90000000, LENGTH = 16M

}

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

ExtFlashSection :

{

*(ExtFlashSection ExtFlashSection.*)

*(.gnu.linkonce.r.*)

    . = ALIGN(0x4);

} >QUADSPI

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

  . = ALIGN(4);

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

 } >RAM AT> FLASH

  

 /* Uninitialized data section */

 . = ALIGN(4);

 .bss :

 {

  /* This is used by the startup in order to initialize the .bss secion */

  _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

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

  

 /* Remove information from the standard libraries */

 /DISCARD/ :

 {

  libc.a ( * )

  libm.a ( * )

  libgcc.a ( * )

 }

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

}

@iw2lsi​ Hi, You solved the issue just by adding QUADSPI session in linker script or did anything else. I am also facing similar issue.

The linker script/scatter file determines where the linker places sections.

For the debugger/ide to be able to program external memory it has to be aware of the hardware implementation, and have a custom loader. ST historically has provided loaders for their own boards, but not those built/designed by third parties.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Yes we can put linker script with section as QSPI but suppose we are not usng IDE, so Do we need to make 2 hex file from one project, One with application code and another with QSPI data? Later using external loader to program with 2nd hex file? Sorry I am not able to make logic with this info. Can you suggestion how it should be implemented ?