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

0

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

linker
ld
ram
stm32f4discovery
stm32f4
asked on Stack Overflow Jun 5, 2019 by ulix • edited Jun 5, 2019 by berendi - protesting

1 Answer

0

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

There is nothing in your code telling the linker to put the big array in the SDRAM area, so it'd still try to allocate it in RAM. Create a section for it in the linker file

.bigdata :
{
  . = ALIGN(4);
  *(.bigdata)
  *(.bigdata*)
  . = ALIGN(4);
} >SDRAM

and tell the compiler to put the array there

volatile uint16_t test[76800] __attribute__((section(".bigdata")));

Likewise you should create a proper section for the heap to be allocated in SDRAM

._user_heap :
{
  . = ALIGN(64);
  PROVIDE ( __heap_start = . );
  . = . + Heap_Size;
  PROVIDE ( __heap_limit = . );
  . = ALIGN(4);
} >SDRAM

Otherwise they would overlap.

Keep in mind that variables outside the regular data area won't be initialized by the startup code, so they'd contain whatever junk there was in the SDRAM at powerup.

Also note that your definition of ORIGIN = 0xD000000 contains one too few zeroes.


User contributions licensed under CC BY-SA 3.0