2020-12-28 12:53 AM
In the last weeks, I was working on running W25Q256 nor flash chip from vendor Winbond with STM32F746 MCU on a custom board. My guideline in this road is ST's how to run QSPI flash video tutorial (5-part video) and of course some genius guys in the community who's helped me a lot to rewrite the functions of QSPI flash (Init, Erase, Write, Memory-mapped). So far functions tested in the Main.c and I can read the pre-written data on the memory. The next step is to generate (.stldr) external loader file and modify Flash.ld file.
according to the video tutorial, I added Loader_Src.c, dev_inf.c, and dev_inf.h files to the workspace but there is a little confusion about flash.ld file that contains memory definitions and all other data and text stuff to assign to specific memory (>FLASH, >RAM, >QUADSPI).
for the point of concern, I use STM32F746 with IS42S32400F SD-RAM connected with 2-banks to MCU and of-course W25Q256 NOR-FLASH.
here I uploaded relevant files for check
STM32F746BGTX_FLASH.ld
/**
******************************************************************************
* @file LinkerScript.ld
* @author Auto-generated by STM32CubeIDE
* @brief Linker script for STM32F746BGTx Device from STM32F7 series
* 1024Kbytes FLASH
* 320Kbytes RAM
*
* Set heap size, stack size and stack location according
* to application requirements.
*
* Set memory bank area and size if external memory is used
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data into "FLASH" Rom type memory */
.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 into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.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 into "RAM" Ram type memory */
. = 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
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Dev_inf.c
/*
* Dev_Inf.c
*
*/
#include "Dev_Inf.h"
#include "quadspi.h"
/* This structure contains information used by ST-LINK Utility to program and erase the device */
#if defined (__ICCARM__)
__root struct StorageInfo const StorageInfo = {
#else
struct StorageInfo const StorageInfo = {
#endif
"QSPI_flashloader_CSP", // Device Name + version number
NOR_FLASH, // Device Type
0x90000000, // Device Start Address
MEMORY_FLASH_SIZE, // Device Size in Bytes
MEMORY_PAGE_SIZE, // Programming Page Size
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
{ {
(MEMORY_FLASH_SIZE / MEMORY_SECTOR_SIZE), // Sector Numbers,
(uint32_t) MEMORY_SECTOR_SIZE
}, //Sector Size
{ 0x00000000, 0x00000000 }
}
};
Solved! Go to Solution.
2021-08-17 05:21 AM
@Community member Please take these messages into consideration. And your help would be greatly appreciated. I need some free space and I don't know anything about it (I don't know how my Board will recognize Flash).
2021-08-17 09:44 AM
Should probably have started a new thread for this
Perhaps check out embryonic.dk he has a number of related videos
https://www.youtube.com/watch?v=237lPdMsDZs
2021-09-28 08:53 PM
hi Tesla Delorean
i need w25q256fv stldr for h743i.
the loader that you upload for this, erased successfully, but not validate erase...
can you help me and share the source of the w25q source project or generate
CLIVEONE-W25Q256FV_STM32FHXX-PB2-PB6-PF8-PF9-PF7-PF6
for me.
thank
2022-11-16 09:53 PM
Hi, Can you please share QSPI flash driver, with the updated Memory read/write/erase functions?
Please help, thankyou.
2023-06-24 01:04 PM - edited 2023-06-24 01:07 PM
Hello.
thanks for your responses.
I'm trying to create a .stldr file for stm32h7b0vbt6 and W25Q64.
at first I wrote all needed OSPI (QSPI) functions and I tested all of them. everything is ok. then according to ST tutorials (5 videos on youtube) I started to create stldr file. I added files to my project (in CubeIDE). then I write appropriate functions in CSP_QSPI_... functions.
I realized an important different between N25Q series (that are used on those videos) with W25Q series. in N25Q, we have sectors, sub-sectors and pages. but in W25Q we have blocks, sectors and pages. so in W25Q, blocks are equivalent to sectors in N25Q and so we should notice that.
I did all of that. at last I tested functionalities with sample test (in github repo of that tutorial). every thing was good. then I used linker.ld to create stldr file. I generated it and copied it into external loaders directory of CubeProgrammer. I used it to write my app to external flash. and this was the result:
mass storage function: it works very good
sector erase: that is ok
write: when sector erase ends and CubeProgrammer wants to write my hex file, after writing 428KB of data, it give me an error and stops. and then when I compare the memory data with main hex file I see exactly from this address everything is clear (0xFF) in external flash.
I'm working on it for about 1 week and I can not realize what is the problem.
do you have any help for me?
I attached the code of Core directory of CubeIDE project + the linker.ld file (in that tutorial github repo we have two directories: one for H7 series and one for another according to SRAM addresses)
thanks
2023-06-26 06:57 PM
Rebuilt my earlier OCTOSPI loader with the pin configuration