Tell the STM32 model to help you better.
The HAL will only initializes the FMC peripheral, but not the SDRAM itself, you must still manually initialize the sdram with the proper commands.
Use the SDRAM initialization sequence from here:
https://www.eevblog.com/forum/microcontrollers/stm32h7-sdram/https://community.st.com/s/question/0D50X0000BVo0k6SQB/cannot-get-fmc-sdram-driver-to-work-on-stm32f429-discovery-boardAfter generating the HAL code, you'll see the peripheral initializations in main.c
Search for:
static void MX_FMC_Init(void)
And insert the SRAM init sequence at the end, like this:
/* USER CODE BEGIN FMC_Init 2 */
SDRAM_InitSequence();
/* USER CODE END FMC_Init 2 */
After this, the SDRAM will be ready.
The FMC controller maps the SDRAM to the address 0xD0000000
You can add the sdram section to the linker script like this (This example uses 8MB):
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
SDRAM (rwx) : ORIGIN = 0xD0000000, LENGTH = 8192K
}
/* Sections */
SECTIONS
{
/* external SDRAM */
.sdram (NOLOAD) :
{
. = ALIGN(4);
*(.sdram .sdram.*)
} > SDRAM
...
The C initialization routine (which sets all your variables to the default values) runs before the user main.
So you have a problem: at that early stage, only internal ram and flash are available.
The peripherals are yet to be configured, so there's no SDRAM area to access.
Thus, you must use NOLOAD, to tell the linker that the SDRAM area shouldn't be initialized.
Then, in your code, declare the sdram variables like this:
__attribute__((section(".sdram"))) char data[128];
But remember, you can't initialize it:
__attribute__((section(".sdram"))) char data[128] = "This is a test";
This is not for HAL, but gives some hints.
Check how it wipes the SDRAM (Fill with with 0s) after initialization. That way you'll only have to initialize those variables not being 0.
https://github.com/floppes/stm32doom/blob/master/src/sdram.c