cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429-Disco - RAM Extension with SDRAM Linker Skript wrong?

uli stone
Associate II

Hi,

I'm trying to use the SDRAM from my STM32F429-Disco Board. I have created a function to initialize the SDRAM which is executed in the main-function. The SDRAM implementation was done with the following instruction: http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html and should work since I'm able to write to the SDRAM. THe SDRAM Initialization function is executed in the main function.

I'm not sure but I think the problem is with my linker skript or syscall.c

I changed the following things in files, syscall.c -The following code:

caddr_t _sbrk(int incr)
{
        extern char end asm("end"); 
	static char *heap_end;
	char *prev_heap_end;
 
	if (heap_end == 0)
		heap_end = &end;
 
	prev_heap_end = heap_end;
	if (heap_end + incr > stack_ptr)
	{
//		write(1, "Heap and stack collision\n", 25);
//		abort();
		errno = ENOMEM;
		return (caddr_t) -1;
	}
 
	heap_end += incr;
 
	return (caddr_t) prev_heap_end;
}

to the following syscall.c:

caddr_t _sbrk(int incr)
{
//	extern char end asm("end"); // June 2019 - US
 
	extern char __heap_start asm ("__heap_start");
	extern char __heap_limit asm ("__heap_limit");
 
	static char *heap_end;
    static char *heap_limit = &__heap_limit;
	char *prev_heap_end;
 
	if (heap_end == 0)
		heap_end = &__heap_start;
 
	prev_heap_end = heap_end;
	if (heap_end + incr > heap_limit)
	{
//		write(1, "Heap and stack collision\n", 25);
//		abort();
		errno = ENOMEM;
		return (caddr_t) -1;
	}
 
	heap_end += incr;
 
	return (caddr_t) prev_heap_end;
}

And for the linker skript, I changed:

  •    heap was commented out
  •    heap_start and heap_limit was added
  •    SDRAM was added to the memory areas
  •    user_stack was altered
/*_Min_Heap_Size = 0x200;      /* required amount of heap   commented out*/
 
__heap_start = 0xD0000000; /*Was added*/
__heap_limit = 0xD0800000; /*Was added*/
 
/* Specify the memory areas - SDRAM was added */
MEMORY
{
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
SDRAM (xrw)     : ORIGIN = 0xD000000, LENGTH = 8M
}
 
/* User_stack section, used to check that there is enough RAM left was altered */
  ._user_stack :
  {
    . = ALIGN(8);
    PROVIDE ( end = . );
    PROVIDE ( _end = . );
    . = . + _Min_Stack_Size;
    . = ALIGN(8);
  } >RAM

But I have the problem, when I create a big array - globally - with:

volatile uint16_t test[76800];

I still get an RAM overflow, which should not happen since the SDRAM should be used.

How can I fix this, to use the SDRAM as extension of the RAM?

Thank you

2 REPLIES 2
Alex R
Senior

You need to check your linker to determine the method used to place data at an specific address.

An alternative would be to use a pointer to the SDRAM, and not define statically the big buffer.

You might need to keep track of the buffer size to prevent overflows.

Alex R
Senior

From this post:

https://community.st.com/s/question/0D50X0000AurKVsSQM/declaring-variables-in-sram13-areas-of-h7-devices-in-stm32cubeide

STM32CubeIDE uses gcc, so you should read the relevant gcc docs: __attribute__ ((section("my_ram")) will place the corresponding variable in elf section "my_ram". Then add the appropriate section(s) to your linker script. For an example see e. g.

STM32Cube_FW_F7_V1.15.0/Projects/STM32746G-Discovery/Demonstrations/STemWin/SW4STM32/STM32F7-DISCO/STM32F746NGHx_FLASH.ld