cancel
Showing results for 
Search instead for 
Did you mean: 

Copy data to SDRAM at startup

43102399
Associate II
Posted on October 03, 2016 at 12:39

Hello,

I am using the STM32F746 Discovery Board with STM32 System Workbench IDE. I know SDRAM is a volatile memory but I want copy a picture to the external SDRAM at startup because it's too big for the internal Flash.

What I did fist is to initialize the SystemClock and the SDRAM in the SystemInit(). I checked it an it's working fine because I can use it without any more initialisation in the main().

My next step was to define an additional memory block in the LinkerScript.

MEMORY

{

FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 1024K

RAM (xrw)        : ORIGIN = 0x20000000, LENGTH = 320K

SDRAM (xrw)        : ORIGIN = 0xC0000000, LENGTH = 8M

}

after this I added a section as followed. I copied that idea from the .data section which is copied from the Flash in the internal RAM.

SECTIONS

{

...

/* used by the startup to initialize data */

  _sidata_sdram = LOADADDR(.sdram_data);

 

  /* Initialized data sections goes into RAM, load LMA copy after code */

  .sdram_data :

  {

    . = ALIGN(4);

    _sdata_sdram = .;  /* create a global symbol at data start */

    *(.sdram_data)     /* .sdram_data sections */

    *(.sdram_data*)    /* .sdram_data* sections */

    . = ALIGN(4);

    _edata_sdram = .;  /* define a global symbol at data end */

  } >SDRAM AT> FLASH

...

}

In the assembly written startup file I added .words for the defined addresses in the LinkerScript and a copy routine like for the .data. The routine I added after the SystemInit() that the SysClk and SDRAM are already initialized.

/* Call the clock system initialization function.*/

  bl  SystemInit

/* Copy the data segment initializers from flash to SRAM */

  movs  r1, #0

  b  LoopCopyDataSdram

CopyDataSdram:

  ldr  r3, =_sidata_sdram

  ldr  r3, [r3, r1]

  str  r3, [r0, r1]

  adds  r1, r1, #4

LoopCopyDataSdram:

  ldr  r0, =_sdata_sdram

  ldr  r3, =_edata_sdram

  adds  r2, r0, r1

  cmp  r2, r3

  bcc  CopyDataSdram

If I now define a global variable as followed I can't see that it's working.

__attribute__((__section__(''.sdram_data''))) uint8_t picture1[] = {

       ...

        0x00, 0xFF, 0xFF,

       ...

};

Does anybody know what I am making wrong? I try to find a solution since a week but nothing is working. :( Or does anyboy have a small programm wich is doing that correctly?
12 REPLIES 12
Posted on October 03, 2016 at 17:41

Looks a reasonable enough approach. You could confirm the symbols addresses via the .MAP file.

Have you used a debugger and stepped the code to understand what is happening there, and confirmed the initialization pattern data matches you expectations.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
43102399
Associate II
Posted on October 04, 2016 at 13:31

Hey clive1, with some trouble finally it's working. I was very happy about that. In the memory map I could see that my declared variable is located at the address where the SDRAM starts.

But now if I want store more pictures to the SDRAM which are in total bigger size than the internal flash I get the error while compiling:

test_sdram_lcd2.elf section `.sdram_data' will not fit in region `FLASH'

region `FLASH' overflowed by 160908 bytes

Now I am confused because what I wanted is that the data is stored in the SDRAM at startup not in the flash fist.

Is the reason in the definition of the SECTION in the linker script?

  .sdram_data :

  {

    . = ALIGN(4);

    _sdata_sdram = .;          /* create a global symbol at data start */

    KEEP(*(.sdram_data))    /* .sdram_data sections */

    KEEP(*(.sdram_data*))    /* .sdram_data* sections */

    . = ALIGN(4);

    _edata_sdram = .;        /* define a global symbol at data end */

  } >SDRAM AT> FLASH

but if I change it to only ''>SDRAM'' nothing is working.

Do you know any possibility how I can make this without using any flash memory?
Kraal
Senior III
Posted on October 04, 2016 at 15:30

Hi !

Your thread title is quite explicit: you initialize SDRAM data with something stored in flash, because the SDRAM is a volatile memory and thus its content is lost when the power is OFF. So you can not have data bigger than the available flash memory (at initialization). Usually people use a SD card to store their images.

Posted on October 04, 2016 at 19:54

The data has to come from somewhere. When the board powers only what is in FLASH is valid. If you want to store large images you'd want to look into some external storage, either in a SPI Flash device, or via a MicroSD card, or whatever.

The Load Region could pull data from QSPI instead of Internal Flash. The F746G has an

https://www.micron.com/parts/nor-flash/serial-nor-flash/n25q128a13ese40f

device for this purpose, and the ST-LINK Utilities has an External Loader so it can write this memory. Notionally at 0x90000000 (128Mb/16MB) as I recall.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
43102399
Associate II
Posted on October 05, 2016 at 09:58

Ok yes it's true. I made what the title of the thread says. But my goal was that the pictures are stored directly in the SDRAM at startup. Not in the flash first and then copied into the SDRAM. I know it's a volatile memory and that the data is lost after power off. But I saw the example program in the ST firmware where they stored pictures directly into the QSPI Flash and I thought it must be possible to do the same with the SDRAM. Isn't it?

AvaTar
Lead
Posted on October 05, 2016 at 14:29

> But I saw the example program in the ST firmware where they stored pictures directly into the QSPI Flash and I thought it must be possible to do the same with the SDRAM. Isn't it?

 

Yes - but with the small, but significant difference that the SDRAM contents are lost at power-down. Thus, it would not really make sense.

Posted on October 05, 2016 at 20:33

If you want to debug directly into SDRAM, and need the debugger to copy the data directly there, you will need to use a Debugger Initialization file that does the equivalent to the code in SystemInit() to bring up the chip, the pins, controller, and SDRAM. It would do this by poking the specific chip registers. In Keil you'd specify these in a .INI file associated with the debugger, for GNU/GCC you'd need to review the documentation for your tools.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
43102399
Associate II
Posted on October 06, 2016 at 09:13

Ok one last question for that. Is there a difference between the SDRAM and the QSPI? Because when I look at the demo program for the home_alarm of the st firmware I can see that they initialize the qspi chip in the SystemInit() like me with the sdram. They create a section in the linker script also like me but with the difference that they don't use KEEP(*...) and only wrote >QSPI instead of >SDRAM >AT FLASH like I did. Also they don't wrote a copy routine in the assembly startup file. But with this demo program they are able to store many pictures in the qspi directly at startup.

Posted on October 06, 2016 at 12:53

The QSPI memory is non-volatile so retains what's put in it at each power cycle and doesn't contain random junk like SDRAM.

Think of FLASH like a car with RAM and SDRAM as passengers, and QSPI as a trailer. The passengers need to get out when you get to the final destination.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..