mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Uli S. (uli_stone)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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:
    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;
    }

zu nachfolgender geändert:
    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;
    }

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
    /*_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

Aber wenn ich versuche ein großes Array zu deklarieren bekomme ich 
(immernoch) ein RAM overflow (global deklariert):
    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)


Bewertung
0 lesenswert
nicht lesenswert
Füge zwei Sections für den SDRAM hinzu:
.SdRamData : {
  . = ALIGN(4);
  _SdRamDataBegin = .;
  *(.SdRamData);
  *(.SdRamData*);
  . = ALIGN(4);
  _SdRamDataEnd = .;
} >SDRAM AT> FLASH

_SdRamLoadData = LOADADDR(.SdRamData);

.SdRamBss (NOLOAD) : {
  . = ALIGN(4);
  _SdRamBssBegin = .;
  *(.SdRamBss);
  *(.SdRamBss*);
  . = ALIGN(4);
  _SdRamBssEnd = .;
} >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:
volatile uint16_t test[76800] __attribute__ ((section (".SdRamData"))) = { 1, 2, 3 };

Und Variablen welche 0 sind so:
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.