cancel
Showing results for 
Search instead for 
Did you mean: 

stm32h735 HyperRAM extern memory

HispaEmo
Associate II

Hello friends at ST,

I'm trying to configure the external memory on an STM32H375 board using CubeIDE, but I'm not achieving success.

Let me explain how I'm doing it: I enable OCTOSPI2, set it to HyperBus mode, choose port 2, and configure the corresponding pins.

HispaEmo_0-1708693942809.png

 

Regarding these options, I'm not quite sure which ones to choose:

 

HispaEmo_1-1708693999704.png

This is my linker file:

HispaEmo_2-1708694143799.png

 



If I put ">RAM_D1 AT> RAM_D4," the data is not assigned. If I put "RAM_D4," the data is assigned, but when I load it onto the board, it doesn't work.

new some help

thank U

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
LCE
Principal

I just use the HyperRAM (on H735 discovery kit) for some special variables / buffers, which are placed there with the <attribute> thingy.

Linker script:

OSPI2_D1(xrw)	: ORIGIN = 0x70000000, LENGTH = 0x1000000	/* OCTOSPI 2 */

later on in SECTIONS:

/* external A2IP buffer section */
.A2IpBufExtSection (NOLOAD):
{
	. = ALIGN(8);
	*(.A2IpBufExtSection)
	*(.A2IpBufExtSection*)
	. = ALIGN(8);
} >OSPI2_D1

Variable declaration in *.c / *.h:

*.c:
/* sA2IpBuf: A2IP packet buffers in EXTernal OCTOSPI SRAM */
/* memory: OCTOSPI 2 */
__ALIGN_BEGIN sA2IpBuf_t sA2IpBuf[A2IP_BUF_NUM] __attribute__((section(".A2IpBufExtSection"))) __attribute__((aligned(8))) __ALIGN_END;

*.h:
/* memory: OCTOSPI 2 */
extern __ALIGN_BEGIN sA2IpBuf_t sA2IpBuf[A2IP_BUF_NUM] __attribute__((section(".A2IpBufExtSection"))) __attribute__((aligned(8))) __ALIGN_END;

 

Setup is done without HAL, clocked with 100 MHz.

Works like a charm!

 

 

View solution in original post

4 REPLIES 4
FBL
ST Employee

Hello @HispaEmo 

 

Would you share your schematics? datasheet of your memory? In linker script, are you sure about memory size? 128000 KB?


@HispaEmo wrote:

Regarding these options, I'm not quite sure which ones to choose:



About options, you need to refer the specifications in the reference manual to learn about them. These modes are fundamental to make it work.

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.

LCE
Principal

I just use the HyperRAM (on H735 discovery kit) for some special variables / buffers, which are placed there with the <attribute> thingy.

Linker script:

OSPI2_D1(xrw)	: ORIGIN = 0x70000000, LENGTH = 0x1000000	/* OCTOSPI 2 */

later on in SECTIONS:

/* external A2IP buffer section */
.A2IpBufExtSection (NOLOAD):
{
	. = ALIGN(8);
	*(.A2IpBufExtSection)
	*(.A2IpBufExtSection*)
	. = ALIGN(8);
} >OSPI2_D1

Variable declaration in *.c / *.h:

*.c:
/* sA2IpBuf: A2IP packet buffers in EXTernal OCTOSPI SRAM */
/* memory: OCTOSPI 2 */
__ALIGN_BEGIN sA2IpBuf_t sA2IpBuf[A2IP_BUF_NUM] __attribute__((section(".A2IpBufExtSection"))) __attribute__((aligned(8))) __ALIGN_END;

*.h:
/* memory: OCTOSPI 2 */
extern __ALIGN_BEGIN sA2IpBuf_t sA2IpBuf[A2IP_BUF_NUM] __attribute__((section(".A2IpBufExtSection"))) __attribute__((aligned(8))) __ALIGN_END;

 

Setup is done without HAL, clocked with 100 MHz.

Works like a charm!

 

 

 

Hello @LCE and @FBL 

Thank you very much for your response.

I have been implementing your solution, and I can't get it to work.

I have some questions for you:

1- When you mention activating the clock, are you referring to the clock of RAM_D1 or OCTOSPI2, or both?

Do I activate them in the system_stm32h7xx.c file?

In the void SystemInit(void):

(...)
_HAL_RCC_D2SRAM1_CLK_ENABLE();
__HAL_RCC_OSPI2_CLK_ENABLE();

 

2- How can I configure the frequency of these clocks?

3- In the .ld file, what I want to relocate is the .bss and ethernet_data from RAM_D1 to OSPI2_D1. Is this possible?

 

 

/* Specify the memory areas */
MEMORY
{
  ITCMRAM (xrw)    : ORIGIN = 0x00000000,   LENGTH = 64K
  DTCMRAM (xrw)    : ORIGIN = 0x20000000,   LENGTH = 128K
  FLASH    (rx)    : ORIGIN = 0x08000000,   LENGTH = 1024K
  RAM_D1  (xrw)    : ORIGIN = 0x24000000,   LENGTH = 320K
  RAM_D2  (xrw)    : ORIGIN = 0x30000000,   LENGTH = 32K
  RAM_D3  (xrw)    : ORIGIN = 0x38000000,   LENGTH = 16K

}

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

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

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

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


  

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
  }

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

 

Thank you in advance.
need your help.

LCE
Principal

> 1- When you mention activating the clock, are you referring to the clock of RAM_D1 or OCTOSPI2, or both?

The OSPI clock is activated in my source code in the function void PeriphCommonClock_Config(void) in the main file:

 

/* OSPI = D1HCLK = HCLK3 = 1/2 CPU */
PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_OSPI;
PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_D1HCLK;

 

So check your main file 

Probably there's something in the CubeMX clock config tree?

 

2- How can I configure the frequency of these clocks?

I think you do NOT want to play with changing internal RAM clocks.
For OSPI clock, check Cube?

There is also a clock prescaler in the OSPI peripheral in DCR2:

 

/* DCR2:
 *	WRAPSIZE 	= 0 	wrapped read OFF
 *	PRESCALER 	= 1 	divide by 2 -> 100 MHz = max at 3.3V
 */
OCTOSPI2->DCR2 = 	(OSPI_HYPERRAM_WRAP_ZERO << OCTOSPI_DCR2_WRAPSIZE_Pos) |
						((OSPI_HYPERRAM_CLK_DIV - 1) << OCTOSPI_DCR2_PRESCALER_Pos);

 

 

3- In the .ld file, what I want to relocate is the .bss and ethernet_data from RAM_D1 to OSPI2_D1. Is this possible?

I don't know. I just use the HyperRam as described above, with the "attributed" buffers.

Anyway, moving everything from AXI RAM to external RAM sounds "dangerous" to me.

Ethernet:

I think the descriptors should stay in RAM_D2.