2024-02-23 05:17 AM
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.
Regarding these options, I'm not quite sure which ones to choose:
This is my linker file:
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
Solved! Go to Solution.
2024-02-23 06:36 AM
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!
2024-02-23 05:35 AM
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.
2024-02-23 06:36 AM
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!
2024-02-26 02:32 AM
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):
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.
2024-02-26 04:00 AM
> 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.