STM32F429-Disco-带SDRAM链接器Skript的RAM扩展错误吗?

时间:2019-06-05 10:23:24

标签: linker ld ram stm32f4discovery stm32f4

我正在尝试使用STM32F429-Disco开发板中的SDRAM。我创建了一个函数来初始化在main函数中执行的SDRAM。 SDRAM实现是通过以下指令完成的:http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html,并且由于我能够写入SDRAM而应该可以工作。在主功能中执行SDRAM初始化功能。

我不确定,但是我认为问题出在我的链接程序skript或syscall.c

我在文件syscall.c中更改了以下内容-以下代码:

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;
    }

到以下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;
    }

对于链接器skript,我进行了更改:

   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

但是当我在全局范围内创建一个大数组时,我遇到了问题:

    volatile uint16_t test[76800];

我仍然遇到RAM溢出的情况,因为应该使用SDRAM,所以这不会发生。

如何解决此问题,以将SDRAM用作RAM的扩展?

谢谢

1 个答案:

答案 0 :(得分:0)

  

我仍然遇到RAM溢出的情况,因为应该使用SDRAM,所以这不会发生。

您的代码中没有任何内容告诉链接器将大数组放在SDRAM区域中,因此它仍然会尝试在RAM中进行分配。在链接器文件中为其创建一个部分

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

并告诉编译器将数组放在那里

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

同样,您应该为要在SDRAM中分配的堆创建一个适当的段

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

否则它们将重叠。

请记住,常规数据区域之外的变量不会被启动代码初始化,因此它们将包含加电时SDRAM中存在的所有垃圾。

还要注意,您对ORIGIN = 0xD000000的定义包含一个太少的零。