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
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.
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...?
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
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?
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.
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.
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.
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.
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?
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.