Guten Abend liebe Community, Ich habe vor kurzen eine neue Platine anfertigen lassen um mein bestehendes Projekt auszuweiten wechsele ich vom ATMega1284P auf den ATMega2560. Der ATMega2560 ist auch auf der neuen Platine verbaut. Da der ATMega2560 nur über 8K SRAM anstatt wie sein kleiner Bruder über 16K und ich jetzt bei knapp 6,3 kB SRAM verbrauch bin. Habe ich ein Externen SRAM auf der Platine mit verbaut. Der SRAM ist vom Hersteller ISSI und trägt die Bezeichnung IS61C5128AL-10TL, hab damals von irgendwelchen Geräten 3 Stück von den ausgelötet. Der SRAM ist natürlich absoluter Overkill mit seinen 4Mb (512kB) und ich kann ihn auch nicht voll adressieren da AVRs ja nur max. 64kB direkt können. Habe die überschüssigen Adresspins A16 bis A18 auf normale I/O Pins des Mikrocontrollers gelegt. Könnte in der Theorie glaubig Bank Switching machen und so denn gesamten Adressraum des SRAM bekommen aber erstmal nicht und ich weiß auch nicht ob der AVR so programmierbar ist das er von sich aus dieses Bank Switching macht, glaube ja nicht. Im Datenblatt zum Prozessor steht ja unter "External Memory Interface" für das Register XMCRB die XMM Bits um Pins freizugeben. Ich habe dort keins dieser XMMn Bits gesetzt so das ich alle Address High Pins nutze. Jetzt steht in Klammern als vermerk dort "(Full 56Kbytes space)" desweitern steht dort mit drin weiter oben "Using all 64Kbytes Locations of External Memory" das man diese bekommt wenn man alle Pins an PortC freigibt für den XMEM Bus. Aber das habe ich dort getan wenn ich keins der XMMn Bits setzte oder? Also kann ich doch jetzt die vollen 64kB ansteuern oder nicht? Im Linker habe ich eingestellt das die .data Sektion bei 0x802200 beginnt, also nach dem internen SRAM. Nix desto trotz habe ich den SRAM schon mal getestet. Denn Linker habe ich so konfiguriert das die .data und .bss sowie der Heap im Externen RAM liegen und der Stack im interen. Als erstes habe ich mal 50.000 bytes mit malloc belegt mit Werten zuweisen und wieder ausgelesen dieses funktionierte ohne Fehler. Danach wollte ich das ganze nochmal mit normalen Variablen testen da ich nicht so viel gebrauch von malloc mache. Also habe ich 3 uint16_t Arrays jeweils mit einer Größe von 4000 anlegt. Auch wieder werte zugeweisen und ausgelesen tat alles wenn ich zwischen zwei Arrays mal eins der anderen Highbits(A16-A18) auf HIGH sitze kommt für das Array nur Müll raus. Ist ja klar die Adresse stimmt dann ja nicht mehr. Also der SRAM tut schon mal so wie er soll. Nur bekomme ich beim Kompilieren ein Speicherüberlauf in meinen Fall 300 %. 25kB benutzt von 8kB. In Atmel Studio gibt es ja unter "Project -> Properties" unter "Toolchain -> General" die Möglichkeit ein Externen RAM Check einzuschalten(External ram check for memory overflow (only if device supports this)). Aber wenn ich danach nochmal kompiliere(External Ram Check eingeschaltet) bekomme ich immer noch den gleichen Fehler. Nur wenn ich in der Compilier Datei im Ordner "Vs" den Punkt "RunOutputFileVerifyTask" rauslösche klappt es Problemlos da dieser Task ja gar nicht mehr ausgeführt wird. Aber genau dafür gibt es doch diese Option im AS7 oder nicht? Muss man da noch etwas einschalten oder eintragen damit es funktioniert? Mfg
> Könnte in der Theorie glaubig Bank Switching machen und so denn gesamten > Adressraum des SRAM bekommen Ja, kann man. > aber erstmal nicht und ich weiß auch nicht > ob der AVR so programmierbar ist das er von sich aus dieses Bank > Switching macht, glaube ja nicht. Nö, geht nicht, ist "Handarbeit". > Im Datenblatt zum Prozessor steht ja unter "External Memory Interface" > für das Register XMCRB die XMM Bits um Pins freizugeben. Ich habe dort > keins dieser XMMn Bits gesetzt so das ich alle Address High Pins nutze. > Jetzt steht in Klammern als vermerk dort "(Full 56Kbytes space)" > desweitern steht dort mit drin weiter oben "Using all 64Kbytes Locations > of External Memory" das man diese bekommt wenn man alle Pins an PortC > freigibt für den XMEM Bus. Aber das habe ich dort getan wenn ich keins > der XMMn Bits setzte oder? Also kann ich doch jetzt die vollen 64kB > ansteuern oder nicht? Nicht ganz, denn der externe SRAM teilt sich den Adressraum mit dem internen SRAM und den IO-Registern. > Im Linker habe ich eingestellt das die .data > Sektion bei 0x802200 beginnt, also nach dem internen SRAM. Kann man machen. https://scienceprog.com/adding-external-memory-to-atmega128/#more-2513 http://www.nongnu.org/avr-libc/user-manual/mem_sections.html www.nongnu.org/avr-libc/user-manual/malloc.html
Felix N. schrieb: > Könnte in der Theorie glaubig Bank Switching machen und so denn gesamten > Adressraum des SRAM bekommen Um den gesamten externen RAM nutzen zu können, musst du auf jeden Fall Bank-Switching betreiben. Ohne Bank-Switching kannst du maximal knapp 56kByte davon benutzen. > Im Datenblatt zum Prozessor steht ja unter "External Memory Interface" > für das Register XMCRB die XMM Bits um Pins freizugeben. Ich habe dort > keins dieser XMMn Bits gesetzt so das ich alle Address High Pins nutze. > Jetzt steht in Klammern als vermerk dort "(Full 56Kbytes space)" Genau. Der Adressbereich von 0..0x21ff bleibt dem internen "Speicher" (also nicht nur RAM, sondern auch Registerfile und MMIO) zugeordnet. Von der aktuell ausgewählten 64k-Bank des externen RAM kannst du deshalb auf eben jenen Bereich nicht zugreifen. Die übliche Lösung ist, PC7 nicht in das XMEM-Interface einzubeziehen, sondern ebenfalls zum Bank-Switching zu benutzen. Der Vorteil ist, dass man Zugriff auf den gesamten externen RAM bekommt, der Nachteil ist, dass eine Bank halt nur noch 32kB groß ist. Muss man halt abwägen, was einem für die Anwendung wichtiger ist, ein möglichst großes Stück "Speicher am Stück" oder möglichst viel Speicher.
Falk B. schrieb: > Nö, geht nicht, ist "Handarbeit". Hallo Falk. Ah ja habe ich mir schon irgendwie gedacht. Falk B. schrieb: > Nicht ganz, denn der externe SRAM teilt sich den Adressraum mit dem > internen SRAM und den IO-Registern. Ja das ist mir bekannt. Im Datenblatt findet sich ja Figure 9-1 "Memory Configuration A" dort steht ja drin das alles von 0x0000 bis 0x21FF zum Internen Speicher gehörten. Meine auch im Datenblatt gelesen zu haben was genau alles dazu gehört. Der eigentliche RAM startet glaubig bei 0x1000 dazwischen müssten die I/O Registers sein. Aber das ist doch für mich eigentlich egal oder? Denn schließlich darf ich ja erst ab 0x2200 arbeiten bis maximal 0xFFFF. Dann habe ich ja für das Externe RAM 56.831 mögliche Adressen bzw. 56kB an Speicher das ist klar. c-hater schrieb: > Die übliche Lösung ist, PC7 nicht in das XMEM-Interface einzubeziehen, > sondern ebenfalls zum Bank-Switching zu benutzen. Der Vorteil ist, dass > man Zugriff auf den gesamten externen RAM bekommt, der Nachteil ist, > dass eine Bank halt nur noch 32kB groß ist. Ach so. Ja aber wenn ich doch die XMMn Bits setzte und somit PC7 freigebe. Wer schaltet das denn dann letztendlich wieder um? Ich oder die Compiler selbst wenn er es für nötig hält? Falk B. schrieb: > Kann man machen. Ja die Seiten kenne ich schon und habe mich zum großen Teil dort schon reingelesen. So wie ich das jetzt verstanden habe gibt es zwei "Hauptmöglichkeiten" ein Externen SRAM zu verwenden. Option 1 ist das man die .data und .bss sowie den Heap der von malloc benutzt wird in den Externen RAM auslagert oder Option 2 das man nur den Heap auslagert in den Externen RAM aber die .data und .bss Daten im Internen RAM lässt genau so wie den Stack, wobei der Stack wohl immer im Internen RAM bleiben soll habe ich mal gelesen. Ich habe meinem Linker jetzt folgende Anweisung gegebenen:
1 | -Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x80ffff |
Also .data und .bss sowie Heap in den Externen RAM. Anderes macht es für mich kein wirklichen Sinn nur den Heap auszulagern da ich malloc so gut wie nie benutzte, und der Heap wird glaubig zum großen Teil nur von malloc verwendet. Desweitern initialisiere ich direkt nach den includes in der main den xram mit dem verweis auf .init3 so dass der Externe RAM vor den initialisieren von .init4 und somit den Kopieren der Daten in den RAM bereits vorhanden ist.
1 | ... F_CPU define und includes etc... |
2 | |
3 | //External Memory needs to be available before Data is copied to the RAM (.init4) |
4 | void xram (void) __attribute__ ((naked)) __attribute__ ((section (".init3"))); |
5 | void xram(void) { |
6 | XMCRA = 0; //Reset XMEM |
7 | XMCRA |= (1<<SRE); //Enable XMEM, No Wait Time, No Sector Limit |
8 | XMCRB = 0; //No Released Port Pins. Full 56kB Space |
9 | } |
10 | |
11 | ... Variables, Subroutinen, main(void) etc... |
c-hater schrieb: > Muss man halt abwägen, was einem für die Anwendung wichtiger ist, ein > möglichst großes Stück "Speicher am Stück" oder möglichst viel Speicher. c-hater schrieb: > Um den gesamten externen RAM nutzen zu können, musst du auf jeden Fall > Bank-Switching betreiben. Ohne Bank-Switching kannst du maximal knapp > 56kByte davon benutzen. Ja wie gesagt der RAM ist eh absoluter Overkill für das System ein 62256 hätte eigentlich auch locker gereicht, nur hatte ich diese hier noch rumfliegen daher hatte ich diesen genommen. In meinen Fall würde ich mir für das größere Stück Kuchen entscheiden anstatt mehrere Stücke, ich werde eh niemals, glaubig ich zu mindestens bis jetzt, die vollen 56kB SRAM voll bekommen. Das ganze ist für mein Aquarium Steuergerät. Hatte ja schonmal ein Thead wo es bei mir um den Programmspeicher ging. Durch neu schreiben des Codes und optimieren konnte ich nochmal einiges an Speicher freigeben so das die 128K vom 1284P eig. nicht voll waren, wahr irgendwo jetzt bei 85kB oder so. Nur sind mir die Pins ausgegangen bei dem 40-Pinningen PDIP Prozessor. Daher jetzt der Wechsel auf den größeren Bruder nur mit 8K SRAM wäre ich ganz sicher nicht ausgekommen. Habt ihr eventuell auch Ahnung von Atmel Studio was das sein könnte? Kompilieren scheint trotzdem zu funktionieren. Bzw. geänderte Sachen im Code sind nachdem Hochladen auch vorhanden trotz Memory Overflow Fehler macht aber kein Unterschied ob ich "External Memory Check" an habe oder nicht. Mfg
Felix N. schrieb: > So wie ich das jetzt verstanden habe gibt es zwei "Hauptmöglichkeiten" > ein Externen SRAM zu verwenden. Option 1 ist das man die .data und .bss > sowie den Heap der von malloc benutzt wird in den Externen RAM auslagert > oder Option 2 das man nur den Heap auslagert in den Externen RAM aber > die .data und .bss Daten im Internen RAM lässt genau so wie den Stack, > wobei der Stack wohl immer im Internen RAM bleiben soll habe ich mal > gelesen. Ja. > Also .data und .bss sowie Heap in den Externen RAM. Anderes macht es für > mich kein wirklichen Sinn nur den Heap auszulagern da ich malloc so gut > wie nie benutzte, und der Heap wird glaubig zum großen Teil nur von > malloc verwendet. Ja. > Das ganze ist für mein Aquarium Steuergerät. Und dafür reichen 8kB SRAM nicht aus? Was machst du damit? Mit 8kB sind die Amis der Legende nach auf dem Mond gelandet.
Falk B. schrieb: > Und dafür reichen 8kB SRAM nicht aus? Was machst du damit? Vielleicht ist noch nicht bis zu jedem AVR-User vorgedrungen dass man mit Strings nur im Flash eine Menge RAM sparen kann. Und plötzlich passt der ganze Code sogar in den kleinen 328P!
Falk B. schrieb: > Ja. Falk B. schrieb: > Ja. Alles klar! Danke Falk B. schrieb: > Und dafür reichen 8kB SRAM nicht aus? Was machst du damit? Mit 8kB sind > die Amis der Legende nach auf dem Mond gelandet. Naja wenn man sich mal wie größten Fresser anschaut ENC28J60, ILI9341 Display und SD-Karte und halt die Variablen. Vor der Optimierung war der RAM Verbrauch deutlich höher so um die 12 bis 13kB meine ich. Ein sehr sehr großer Teil ist durch das verwenden von PROGMEM bzw. allgemein der pgmspace.h frei geworden indem ich die Strings nur im Flash habe. Und die GUI zum Bedienen wird mit Sicherheit auch ein bisschen RAM belegen. Bin im Moment bei 6450 Bytes, hab gerade mal geschaut. Alleine bei dem ENC28J60 nutze ich halt den WWW-Server sowie den NTP-Client wenn ich das beides deaktivieren würde bekam ich schon wieder ein Stück frei aber die beiden Funktionen brauche ich. au weia schrieb: > Vielleicht ist noch nicht bis zu jedem AVR-User vorgedrungen > dass man mit Strings nur im Flash eine Menge RAM sparen kann. > > Und plötzlich passt der ganze Code sogar in den kleinen 328P! Weiß ich, bei mir gibt es mittlerweile fast keine Strings mehr die im RAM so direkt liegen sofern sie nicht zu Debugging Zwecken dienen, dann lasse ich sie für die Fehlersuche oder what ever im RAM liegen da sie eh daraus später wieder gelöscht werden. Lg
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.