cancel
Showing results for 
Search instead for 
Did you mean: 

how to load touchgfx images on fmc_nor flash where external loader is created

jr_engr_mbed
Senior

Hi Team,

After assigning NOR Flash space in the linker, I created an external loader, tested it, and debugged it in CubeProgrammer. @SofLit  suggested to seek help regarding my TouchGFX-related query in a new thread.

Is there any reference or guide available for implementing FMC NOR Flash in a TouchGFX project within CubeIDE? I added my own loader in the debug configuration and debugged it, but no data is shown on the display, nor is anything visible at 0x60000000 in the memory browser.

Please guide me on how to achieve full access via Flash memory.

Regards,

jr_mbed_engr

Screenshot (1339).png

Screenshot (1337).png

Screenshot (1338).png

   my linker file:

 

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 = 0x2000;      /* required amount of heap  */
_Min_Stack_Size = 0x4000; /* 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
  EXT_FLASH (r)  : ORIGIN = 0x60000000, LENGTH = 128M
}

/* 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 (READONLY) : 
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } >FLASH
  .ARM (READONLY) : 
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } >FLASH

  .preinit_array (READONLY) : 
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } >FLASH

  .init_array (READONLY) : 
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } >FLASH

  .fini_array (READONLY) : 
  {
    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

  /* Place IntFlashSection in external flash */
  IntFlashSection :
  {
    . = ALIGN(4);
    *(IntFlashSection)
    . = ALIGN(4);
  } >EXT_FLASH  /* Modified to use external flash */

  ExtFlashSection :
  {
    . = ALIGN(4);
    *(ExtFlashSection*)    /* .ext_flash* sections */
    . = ALIGN(4);
  } >EXT_FLASH
  
  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

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

 

 

16 REPLIES 16

Hello @jr_engr_mbed ,

 

I think the answer is this other thread of yours is also the right answer to your last message here : https://community.st.com/t5/stm32-mcus-embedded-software/how-to-build-right-loader-for-fmc-norflash/td-p/718234

 

The main difference between FMC and SPI for external loader is that you need to do your initialization for FMC, not SPI and then you will get the files.
When he say "add files":

GaetanGodart_0-1727770065688.png

 

Add the FMC files that you will get.

 

Also, in his example, he uses a discovery board so he know what the memory is connected to.
If you also use a discovery board, you should check the hardware file available on the product's page.
If you made a custom board, you should know what you connected your memory to.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

NOR Flash should be able to directly memory map, the content should be visible to the MCU

It's NAND flash that's more complicated and blocked.

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

@Tesla DeLorean @GaetanGodart 

Thank you for providing the solution. I need to create a loader specifically for my custom board. I was able to initialize FMC_NOR and successfully read device codes, perform read/write operations, and toggle the LED as mentioned here.

After this,The next step is creating the loader. In the IAR Workbench, as you suggested, I added HAL_NOR instead of the SPI files and perviously used the H743-EVAL since the NOR flash is adapted from its design. So, from your reply to adding files section, should i avoid adding these files when generating the ST-LDR file, correct?

I attached main.c file which is able to read,write,and led blinks... so, where should i use main.c tested program in loader creation..?

Let me know if you'd like any further changes!

Screenshot (1550).png

pic_loader.PNG

@GaetanGodart here, i get confusion.,  i got solution that fmc_nor even though it is directly able to access memory to mcu, so, it behaves like memory mapped without any config.. where, you told my nor is in  block mode.. which is used for nand type.. right? 

i have to just follow like doing for qspi type.. which i run image from .ld space using right loader.! where, i can load img in touchgfx... that's all.?right

 

thank you for your respond. 

Yes, I don't know why I said that sorry.
Usually it is NAND that is in block mode, the rest can usually be memory mapped using FMC or QSPI.

Here is the guide on interfacing memory in memory mapped mode : https://support.touchgfx.com/docs/development/board-bring-up/how-to/06-flash-external-addressable

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Coding in application space should permit you to fully test and evaluate the code, as this is very difficult to do from the External Loader directly.

You'll need to implement your External Loader, or adjust an existing one, so that it's an exact match for the board/hardware you have created. The NOR via FMC should be relatively consistent between parts as the options for the address, data and control pins is relatively finite.

Your Init() function needs to bring up the hardware, so clocks, peripheral, pins, etc.

The SectorErase() and MassErase() should match the FLASH device in use. And the Write() should perform in a manner consistent with how you tested in the Application.

You can use a serial port to get additional diagnostic data from the STM32 side code, and use the verbose logging in STM32 Cube Programmer to see the PC side interaction, and Pass/Fail performance.

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

Hi @GaetanGodart @Tesla DeLorean @SofLit  , Here's an update regarding FMC NOR flash: I was successfully able to run NOR flash after changing the NOR flash IC from 1 Gbit to 128 Mbit. I replaced it with the same 56-TSOP package. Now, I can load TouchGFX data into my NOR flash. Thank you for guiding me for such a long time. i found data mismatch error in 01 gbit norflash, where full data is not loaded properly, after changing 128mbits  flash, i can get full data exactly.