Skip to main content
iw2lsi
Associate III
February 7, 2019
Question

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

  • February 7, 2019
  • 2 replies
  • 1608 views

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

    This topic has been closed for replies.

    2 replies

    iw2lsi
    iw2lsiAuthor
    Associate III
    February 8, 2019

    solved...

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

    Giampaolo

    Chandan Bhatia1
    Associate III
    August 3, 2020

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

    Tesla DeLorean
    Guru
    August 3, 2020

    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Dejan Nedeljkovic
    Associate III
    May 9, 2019

    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

    iw2lsi
    iw2lsiAuthor
    Associate III
    May 9, 2019

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

    }