2024-09-02 09:24 AM
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
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) }
}
Solved! Go to Solution.
2024-10-01 01:09 AM
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":
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,
2024-10-01 01:51 AM
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.
2024-10-01 02:56 AM
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!
2024-10-01 03:12 AM
@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.
2024-10-01 04:18 AM - edited 2024-10-01 04:18 AM
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,
2024-10-01 08:36 AM
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.
2024-10-20 11:57 PM
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.