cancel
Showing results for 
Search instead for 
Did you mean: 

Need to use SDRAM for heap and stack and for that it needs to be up before main function

I am working on SDRAM execution using FMC on STM32H563ZI (NUCLEO-H563ZI board) with external SDRAM connected through FMC interface.

Our target is:

  1. Execute application sections from SDRAM
  2. Place heap and stack in SDRAM
  3. Enable automatic scatter-loading/copy from internal flash to SDRAM during startup

We are facing an issue where:

  • SDRAM initialization appears successful
  • Manual SDRAM read/write access works in application runtime
  • But automatic copy/scatter-loading from Flash to SDRAM during startup is failing
  • Application execution from SDRAM is unstable and leads to HardFault/reset handler

Below are the detailed steps and observations.


  1. CURRENT STARTUP FLOW

Reset_Handler
→ SystemInit()
→ PLL/System clock configuration
→ FMC GPIO configuration
→ FMC SDRAM initialization
→ SDRAM command sequence
→ __main()
→ scatter loading
→ main()

We intentionally moved FMC/SDRAM initialization into SystemInit() so that SDRAM becomes available before scatter loading.


  1. CLOCK CONFIGURATION

We configured PLL through direct register-level programming.

Configuration:

  • HSE used as PLL source
  • HSE = 25 MHz
  • PLLM = 5
  • PLLN = 36
  • PLLR = 2
  • SYSCLK = 90 MHz

PLL configuration registers used:

  • RCC->PLL1CFGR
  • RCC->PLL1DIVR
  • RCC->CFGR1

We observed:

  • System boots successfully
  • main() is reached correctly
  • FMC clock is enabled
  • SDRAM initialization sequence executes

However, execution from SDRAM still fails.

We suspect there may be an FMC kernel clock stabilization issue immediately after SYSCLK switching from HSE/HSI to PLL.


  1. FMC GPIO CONFIGURATION

All FMC pins are configured through direct register-level configuration (without HAL).

Configured pins include:

  • Address lines A0-A11
  • Data lines D0-D15
  • BA0/BA1
  • SDCLK
  • SDCKE0
  • SDNE0
  • SDNRAS
  • SDNCAS
  • SDNWE
  • NBL0/NBL1

GPIO configuration:

  • Alternate Function AF12
  • Push-pull
  • Very high speed
  • No pull-up/pull-down

GPIO clocks enabled:

  • GPIOA
  • GPIOC
  • GPIOD
  • GPIOE
  • GPIOF
  • GPIOG

FMC clock enabled through RCC->AHB4ENR.


  1. SDRAM CONFIGURATION

SDRAM configuration:

  • SDRAM Bank 1
  • 16-bit data width
  • 4 internal banks
  • 8-bit column address
  • 12-bit row address
  • CAS latency = 3
  • SDRAM clock period = 2 HCLK cycles
  • Read pipe delay = 1

Timing configuration used:

  • TMRD = 2
  • TXSR = 3
  • TRAS = 2
  • TRC = 3
  • TWR = 2
  • TRP = 1
  • TRCD = 3

These values are based on CubeMX-generated settings.


  1. SDRAM COMMAND SEQUENCE

The following sequence is executed:

  1. Clock enable command
  2. Delay
  3. Precharge all command
  4. Auto-refresh command
  5. Load mode register command
  6. Refresh rate programming

Refresh rate currently configured approximately around:
683 (based on 90 MHz FMC clock)


  1. MPU CONFIGURATION

MPU region configured for SDRAM:

  • Base address = 0xC0000000
  • Size = 8MB
  • Full access
  • Non-cacheable configuration currently used for initial bring-up

  1. OBSERVED BEHAVIOR

Observed results:

  • SDRAM initialization completes
  • Manual SDRAM write/read test works after main()
  • Direct pointer-based SDRAM access also works
  • FMC registers appear correctly configured

However:

  • Scatter loading to SDRAM during startup fails
  • Application execution from SDRAM fails
  • Heap/stack placement in SDRAM causes instability
  • LED task execution eventually enters HardFault/reset handler

This suggests SDRAM works during later runtime but may not be stable during early startup/scatter loading.


  1. CURRENT SUSPICIONS

We suspect one or more of the following:

  1. FMC kernel clock stabilization issue after SYSCLK switch
  2. SDRAM clock enable timing requirement not met during early startup
  3. SDRAM stabilization delay insufficient before scatter loading
  4. Additional startup sequencing requirement on STM32H563 FMC/SDRAM
  5. Scatter-loading/runtime startup dependency before SDRAM becomes fully stable
  6. Missing FMC/AXI/cache synchronization requirement
  7. Requirement to keep stack/heap internal during scatter loading stage

  1. REQUEST FOR GUIDANCE

We request support regarding:

  1. Correct recommended startup sequence for SDRAM execution on STM32H563
  2. Whether SDRAM initialization inside SystemInit() is officially supported
  3. Any required stabilization delays before __main()/scatter loading
  4. Any FMC clock synchronization requirements after PLL switch
  5. Recommended MPU/cache settings for SDRAM execution
  6. Recommended scatter file configuration for SDRAM execution
  7. Whether any additional FMC initialization steps are required on STM32H5 series

Please let us know if you need:

  • Full source code
  • Scatter file
  • SDRAM datasheet
  • FMC register dump
  • CubeMX project
  • Debug screenshots
 
 

Thanks & Regards,

Shashank Khandve
4 REPLIES 4
mƎALLEm
ST Employee

Hello @shashank78Khandve and welcome to the ST community,

I cannot help you in the SDRAM calculation timings and parameter, meanwhile you can refer to this article / example: How to set up the FMC peripheral to interface with the SDRAM IS42S16800F-6BLI from ISSI

Also, I'm wondering how are you connecting an SDRAM to the NUCLEO. You need to take care about the signal integrity aspects as high frequencies are involved. Refer to this article: How to avoid signal integrity issues on the STM32H7R7/S7  and  AN4803 "High-speed SI simulations using IBIS and board-level simulations using HyperLynx® SI on STM32 MCUs and MPUs".

For scatter loading, your process seems to be correct. SDRAM and its respective GPIOs need to be initialized before main(), i.e. in SystemInit(). Unfortunately there is no example available on STM32H5 for this scenario but STM32H743, has such implementation in the HAL, especially in system_stm32h7xx.c

You need to look at blocks where DATA_IN_ExtSDRAM is defined.

Meanwhile, the SDRAM region in STM32H5 is in the range of 0xC000 0000 to 0xDFFF FFFF, according the reference manual RM0481

mALLEm_0-1778490497268.png

While, by default, the region is in execute never configuration (XN), according to the programming manual PM0264:

mALLEm_1-1778490665030.png

So most probably that's why you are facing a hard fault while executing from SDRAM. You should configure that region to make it executable using the MPU before jumping to the main.

Hope that helps.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hi ST Community, @mƎALLEm ,

I really can’t thank you enough for the help. I was honestly struggling to figure this out on my own, and it was stressing me out. Having you step in and guide me through it means a lot. I’m so glad you’re part of this community I really needed this.

Actually I need some more help on the same topic as I am working on executing code from external SDRAM on STM32H563 using FMC + SDRAM Bank1.

Currently, SDRAM initialization works correctly when everything is initialized from main() using CubeMX generated HAL functions:

- MX_FMC_Init()
- HAL_SDRAM_Init()
- DrvSDRAM_Init()

In this case:
- SDRAM read/write works correctly
- code can be copied to SDRAM using memcpy()
- functions placed in SDRAM section can execute successfully

I am using a scatter file section similar to below:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x000A0000  {  ; RW data
   .ANY (+RW +ZI)
  }
RW_IRAM3 0xC0000000 0x002C0000  {  ; SDRAM 3MB RAM is used as HEAP area
    startup_stm32h563xx.o (HEAP) 
}
ER_IRAM5 0xC0200000 0x00000200  {  ; SDRAM: User Application Code (2 MB)
     ;.ANY0 (+RW +ZI)
  *(.user_app_code)
  }

}

And code section example:

void SDRAM_LED_Task(void) {
while (count<=10) {
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
count++;
}
count=0;
}

The problem starts when I try to initialize FMC + SDRAM before main() from SystemInit().

My actual requirement is:
- initialize SDRAM before main()
- move heap/stack into SDRAM
- support scatter loading/runtime sections in SDRAM
- eventually execute application code directly from SDRAM

I tried two approaches inside SystemInit():

1. Calling HAL-based initialization
- HAL_Init()
- SystemClock_Config()
- MX_FMC_Init()

2. Pure register-level initialization
- RCC configuration
- FMC clock enable
- GPIO AF12 configuration
- SDCR/SDTR setup
- SDRAM command sequence
- refresh programming
- MPU configuration

In both cases I am not able to achieve stable SDRAM execution before main().

I already verified that:
- SDRAM command sequence works correctly
- SDRAM works correctly from main()
- MPU executable region configuration is added
- ICACHE invalidation is also attempted

I also replicated the same initialization sequence used internally by HAL for:
- FMC_SDRAM_Init()
- FMC_SDRAM_Timing_Init()
- FMC enable sequence
- SDRAM mode register sequence

But execution from SDRAM before main() is still failing.

I referred to STM32H7 examples and ST forum discussions mentioning that SDRAM should be initialized before main() for scatter loading use-cases, but I could not find any official STM32H5 example demonstrating:
- SDRAM initialization in SystemInit()
- heap/stack relocation to SDRAM
- executing code from SDRAM before main()

Could someone please clarify:

1. What is the correct initialization order on STM32H5 for:
- clocks
- FMC
- GPIO
- MPU
- ICACHE/DCACHE

when SDRAM must be usable before main()?

2. Is it officially supported/recommended to call HAL initialization functions from SystemInit()?

3. Are there any HAL/FMC dependencies on:
- SysTick
- interrupts
- HAL internal state
- cache state

which prevent SDRAM initialization before main()?

4. Is there any official STM32H5 example available for:
- scatter loading to SDRAM
- heap/stack in SDRAM
- executing code from SDRAM

Any guidance would be very helpful.

Also i have attached some files for your reference ..
Again Thank you for the help!!!

Regards,
Shashank k.

HI @mƎALLEm ,

I forget to tell the clock configuration i did for this setup, it is as per the below  

shashank78Khandve_0-1778508197987.png

also i an running the SDRAM on the 45 Mhz and did the confuguration as per below in mxcube ide 

shashank78Khandve_1-1778508326872.png



please let me know if i am doing it in wrong way or anything more required for the analysis..

Regars,
Shashank K. 

I've already provided some hints previously and as said I can't really help you in the SDRAM configuration. You need to follow the article I have shared previously.

Meanwhile, you need to disable the eXecute Never (XN) from that region using MPU.

You can inspire from the implementation provided in the X-CUBE-PERF-H7 cube package especially the configuration 10 - D1_SDRAM_Swapped - D1_DTCM : execution from SDRAM and data on DTCM RAM.

The target is STM32H7 but the principle is the same.

Attached the files (the linker file which I change the extension to .txt and the system_stm32h7xx.c) where to look at. The associated application note to that CubePackage is the AN4891 "STM32H72x, STM32H73x, and single-core STM32H74x/75x system architecture and performance".

What I suggest is to start by validating the read/write to the full range of your SDRAM. If all is OK translate that as direct access to the registers in the SystemInit() and don't forget to configure the MPU to disable the XN. Don't use HAL in the SystemInit(). You need just to program in bareMetal there...

Good luck.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.