Forum: Mikrocontroller und Digitale Elektronik STM32F429 Dev Board Sdram benutzen mit System Workbench


von Uli S. (uli_stone)


Lesenswert?

Hallo,

ich benutze das STM32F429 Disco Dev Board und habe jetzt Probleme mit 
einem RAM Overflow. Das Problem liegt daran, das ich große Arrays in 
meinem Source-Code benutze um Bilder zu speichern. Leider habe ich mit 
zusätzlichen Speicher noch nicht gearbeitet und bin mir nicht sicher wo 
ich anfangen soll und was nötig ist.

Könnt ihr mir erklären was alles nötig ist den Sdram zu nutzen? Ist es 
richtig das der Speicher initialisiert werden muss 
(http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html) und der Linker 
angepasst.

Danke

von Jim M. (turboj)


Lesenswert?

Uli S. schrieb:
> Könnt ihr mir erklären was alles nötig ist den Sdram zu nutzen? I

Man saugt sich den Beispielcode aus der entsprechenden Appnote des 
Herstellers.

von Uli S. (uli_stone)


Lesenswert?

Mhh... das war nicht was ich lese wollte.

ich habe hier auch noch was gefunden 
(http://www.openstm32.org/forumthread2017), leider weiß ich nicht recht 
ob das für mich ist und wie oben geschrieben ob ich den Sdram 
initilaizieren muss. und wie wird in den speicher geschrieben...?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn du für die AppNotes zu faul bist, kannst du dir mal die Libraries 
von Uwe anschauen:
http://mikrocontroller.bplaced.net/wordpress/?page_id=160

Uli S. schrieb:
> ob ich den Sdram
> initilaizieren muss

Ja, musst du initialisieren, nämlich den FMC Controller.

Uli S. schrieb:
> und wie wird in den speicher geschrieben...?

Z.B. mit den Routinen in der o. a. Library.
Deine lustige Workbench kenne ich nicht, klingt aber toll :-P

: Bearbeitet durch User
von Uli S. (uli_stone)


Lesenswert?

Danke Matthias für deine Antwort. AppNotes habe ich nicht gefunden...

Ich hätte mir gewünscht dass Varaibelen in den Sdram abgelegt werden und 
ich nicht direkt in den Speicher schreiben muss... ISt das möglich?

von Harry L. (mysth)


Lesenswert?

Die FMC-Configuration kannst du dir von CubeMX generieren lassen,
Am einfachsten geht das, wenn du direkt über den Board-Selector dein 
Board auswählst.

von Dumm User (Gast)


Lesenswert?

Matthias S. schrieb:
> Z.B. mit den Routinen in der o. a. Library.

... und ich dachte immer man mapped mit einem Linker Description
Eintrag den SD-RAM Speicher in den "normalen" Arbeitssspeicher-Bereich.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Dumm User schrieb:
> Linker Description
> Eintrag den SD-RAM Speicher in den "normalen" Arbeitssspeicher-Bereich.

Sollte auch klappen. Mit dem SDRAM habe ich das noch nicht probiert, 
aber mit dem CoreCoupled RAM geht das auf jeden Fall - der liegt ja 
meistens auch brach und ist zwar nicht groß, aber schnell.

von Dr. Sommer (Gast)


Lesenswert?

Uli S. schrieb:
> Ich hätte mir gewünscht dass Varaibelen in den Sdram abgelegt werden und
> ich nicht direkt in den Speicher schreiben muss... ISt das möglich?

Ja, schließlich wird der RAM in den Adressraum eingeblendet. Bevor man 
den RAM aber nutzen kann, muss man dem via FMC eine Reihe an Befehlen 
zur Initialisierung schicken. Wenn man die nicht selbst austüfteln 
möchte, kopiert man die aus dem Beispielcode von ST.

von Uli S. (uli_stone)


Lesenswert?

Danke für die Antworten.

Verstehe ich es richtig, das die auf folgender Seite die Initializierung 
vorgenommen wird: http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html 
?

Wie kann ich den Linker Datei so konfigurieren das der Sdram aufgenommen 
wird?

von Dumm User (Gast)


Lesenswert?

Matthias S. schrieb:
> Mit dem SDRAM habe ich das noch nicht probiert,

Dafür ist ein xy-RAM Controller in einem uC unter anderem
da: Dass er unabhängig von irgendwelchen überkünstelten
Pointer-Zugriffen das Schreiben und Lesen auf diesen er-
weiterten Speicherbereich ermöglicht.

Uli S. schrieb:
> Wie kann ich den Linker Datei so konfigurieren das der Sdram aufgenommen
> wird?

Schau dir ein Linker-Description File an und lerne daraus. Es
gibt auch genügend Beispiele im Internet dazu.

von Uli S. (uli_stone)


Lesenswert?

Hi,

ich habe eine Funktion generiert, bei der der SDRAM initializiert wird, 
welche am Anfang der main-Funktion ausgeführt wird. (Nach folgender 
Anleitung http://en.radzio.dxp.pl/stm32f429idiscovery/sdram.html und 
sollte funktinieren, da ich in den SDRAM schreiben kann.

Ich bin mir nicht sicher wo das Problem liegt, im Linker Skript oder in 
der Syscall.c Datei.

Die syscall.c wurde von:
1
    caddr_t _sbrk(int incr)
2
    {
3
            extern char end asm("end"); 
4
      static char *heap_end;
5
      char *prev_heap_end;
6
     
7
      if (heap_end == 0)
8
        heap_end = &end;
9
     
10
      prev_heap_end = heap_end;
11
      if (heap_end + incr > stack_ptr)
12
      {
13
    //    write(1, "Heap and stack collision\n", 25);
14
    //    abort();
15
        errno = ENOMEM;
16
        return (caddr_t) -1;
17
      }
18
     
19
      heap_end += incr;
20
     
21
      return (caddr_t) prev_heap_end;
22
    }

zu nachfolgender geändert:
1
    caddr_t _sbrk(int incr)
2
    {
3
    //  extern char end asm("end"); // June 2019 - US
4
     
5
      extern char __heap_start asm ("__heap_start");
6
      extern char __heap_limit asm ("__heap_limit");
7
     
8
      static char *heap_end;
9
        static char *heap_limit = &__heap_limit;
10
      char *prev_heap_end;
11
     
12
      if (heap_end == 0)
13
        heap_end = &__heap_start;
14
     
15
      prev_heap_end = heap_end;
16
      if (heap_end + incr > heap_limit)
17
      {
18
    //    write(1, "Heap and stack collision\n", 25);
19
    //    abort();
20
        errno = ENOMEM;
21
        return (caddr_t) -1;
22
      }
23
     
24
      heap_end += incr;
25
     
26
      return (caddr_t) prev_heap_end;
27
    }

Und das Linker-Skript habe ich zu an folgenden Stellen geändert:
      - heap wurde auskommentiert
      - heap_start and heap_limit hinzugefügt
      - SDRAM wurde zu den memory areas hinzugefügt
      - user_stack wurde verändert
1
    /*_Min_Heap_Size = 0x200;      /* required amount of heap   commented out*/
2
     
3
    __heap_start = 0xD0000000; /*Was added*/
4
    __heap_limit = 0xD0800000; /*Was added*/
5
     
6
    /* Specify the memory areas - SDRAM was added */
7
    MEMORY
8
    {
9
    FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
10
    RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 192K
11
    CCMRAM (rw)      : ORIGIN = 0x10000000, LENGTH = 64K
12
    SDRAM (xrw)     : ORIGIN = 0xD000000, LENGTH = 8M
13
    }
14
     
15
    /* User_stack section, used to check that there is enough RAM left was altered */
16
      ._user_stack :
17
      {
18
        . = ALIGN(8);
19
        PROVIDE ( end = . );
20
        PROVIDE ( _end = . );
21
        . = . + _Min_Stack_Size;
22
        . = ALIGN(8);
23
      } >RAM

Aber wenn ich versuche ein großes Array zu deklarieren bekomme ich 
(immernoch) ein RAM overflow (global deklariert):
1
    volatile uint16_t test[76800];

Wie kann ich mein Problem beheben, so das der SDRAM als RAm Erweiterung 
genutzt wird?

Danke

von Dr. Sommer (Gast)


Lesenswert?

Füge zwei Sections für den SDRAM hinzu:
1
.SdRamData : {
2
  . = ALIGN(4);
3
  _SdRamDataBegin = .;
4
  *(.SdRamData);
5
  *(.SdRamData*);
6
  . = ALIGN(4);
7
  _SdRamDataEnd = .;
8
} >SDRAM AT> FLASH
9
10
_SdRamLoadData = LOADADDR(.SdRamData);
11
12
.SdRamBss (NOLOAD) : {
13
  . = ALIGN(4);
14
  _SdRamBssBegin = .;
15
  *(.SdRamBss);
16
  *(.SdRamBss*);
17
  . = ALIGN(4);
18
  _SdRamBssEnd = .;
19
} >SDRAM

Dann im Startup-Code nach Initialisierung des SDRAM den Bereich 
_SdRamBssBegin-_SdRamBssEnd auf 0 setzen, und den Bereich ab 
_SdRamLoadData nach _SdRamDataBegin - _SdRamDataEnd kopieren.

Dann im C-Code Variablen welche initialisiert werden müssen so 
definieren:
1
volatile uint16_t test[76800] __attribute__ ((section (".SdRamData"))) = { 1, 2, 3 };

Und Variablen welche 0 sind so:
1
volatile uint16_t test[76800] __attribute__ ((section (".SdRamBss")));

Wenn du kein malloc verwendest, kannst du die ganze Angelegenheit mit 
Heap und sbrk weglassen. Für globale / statische Variablen ist das 
unnötig.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.