Hallo Leute, ich versuche seit zweieinhalb Tagen relativ vergeblich meinen Mega128 mit 32K externes SRAM zu verbinden und in C zu verwenden. Ziel der Übung ist es, eine GameBoy Camera auszulesen, das Bild zu verarbeiten und anschließend erst über den rs232 Port zu jagen. Das ist zum einen strukturierter und zum anderen deutlich weniger Fehleranfällig, weil man sich sogar auf die Timings der Camera konzentrieren kann und nicht auf die rs232 Übertragung warten muss. So weit die Theorie, jetzt die Praxis: Ich habe die Register gesetzt: MCUCR = 0x80; XMCRA = 0x00; XMCRB = 0x81; Ich habe das Makefile geändert: EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff Das Problem ist nun, dass der AVR seit der änderung im Makefile kein Lebenszeichen mehr von sich gibt. Ich kann ihn allerdings mit was anderem Programmieren, dann läuft er wieder. Weil mich genau das sehr stutzig gemacht hat, bin ich mal auf die andere Seite gegangen und habe mit Bascom die Funktion meines mehrfach durchgemessenen RAMmoduls geprüft. Mit dem Ergebnis, dass das SRAM tadellos funktioniert und mein Latch sogar ohne zusätzliche wait-statements einwandfrei läuft. Schreibe ich nun wieder mein C-Programm in den avr, regt sich wieder nichts mehr. Ich weiß das, weil ich per RS232 debug-Messages ausgebe, die nicht mehr erscheinen. Nichtmal die erste. Vielleicht hat jemand von euch Zeit und Lust mir dabei zu helfen und schaut sich mal meinen Quellcode an. Ich bin wirklich mit meinem Latein am Ende, da ich schon seit über zwei Tagen nur an dem RAMmodul sitze und es offenkundig hardwareseitig funktioniert. Mein Programm sollte übersichtlich genug sein. Es gibt ein paar .h Dateien die nicht mehr verwendet werden, aber das betrifft nicht den compilierenden Teil. Vielen Dank im Vorraus! Gruß Timo
Benutzt du die binutils 2.16? Die haben einen Bug drin. Ändere mal: EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff in EXTMEMOPTS=-Wl,--section-start=.data=0x801100,--defsym=__heap_end=0x8090 ff
ohaha, vielen Dank für die promte Antwort und dann auch noch von der Sorte "geil es läuft"! :D Also mit sowas habe ich natürlich nicht gerechnet. Die Version von binutils kann ich dir nicht sagen. Ich habe mit die aktuelle Version vom ProgrammersNotepad2 runtergeladen. Da war gcc bei. Das makefile habe ich mir irgendwo aus einem example geholt und modiziert. Jetzt wo du es sagst merke ich, dass das Makefile evtl noch von einer erheblich älteren Version der Beispiele vom ProgrammersNotepad kommt. Daran hatte ich garnicht gedacht! Ich werde das morgen prüfen, heute ist mir leider die Luft aus. Also ein neues Problem: Ich möchte ein array deklarieren (das ist auch jetzt schon immer mein Speichertestarray und das soll 16768 einträge lang sein. Da sagt der compiler schonmal, dass der Speicher dazu nicht ausreicht. Wenn ich das ding kleiner mache, also z.B. 4096, dann läuft der compiler durch, allerdings kommt es beim durchlaufen der SpeicherCheck-Funktion zu einem Pointerfehler. Das sollte natürlich nicht passieren, denn ich hab ja nun 32kb Speicher... normalerweise. Evtl noch einen hint? Danke schonmal, das hat mit schon sehr geholfen! Timo
Hier ist der Sourcecode. Ich geh da nach dem Frühstück dran, aber vielleicht bist du ja zufällig online und findest da direkt den fehler.
ok, vergessen wir den pointerfehler. Das war ein konstrukt der finsteren Nacht. Das Problem ist jetzt vielmehr, dass der µC wieder nicht läuft. Was also gehstern mit den gleichen einstellungen noch ging, geht heute nicht mehr. Ich verstehe das ehrlich gesagt nicht. Ich habe deine Zeile im Makefile geändert, habe sogar ein makefile eines aktuellen Beispiels genommen und modifiziert, aber mit den gleichen Ergebnis. Ich stelle hier nochmal den aktuellen, nicht startenden code online. Wenn du da einen Blick reinwerfen könntest, wäre das super! Gruß Timo
hm, also da muss immernoch ein fehler mit dem Makefile sein. Und dass es gestern lief, muss leider auch ein Fehler gewesen sein, denn heute macht der einfach garnichts mit den Einstellungen... Der Cloue: Mit der Einstellung, dass nur der Heap im ext. Speicher liegt (EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8090ff ) startet der Prozessor. Der externe Speicher ist für mich allerdings nur sinnvoll, wenn ich mein Bild-Array[128][123] da auslagern kann.
Hallo Jörg, fröhliche Weihnachten gehabt zu haben! Hast du evtl die Zeit gefunden dir das mal anzusehen? Im Augenblick Programmiere ich das ganze mit Bascom, weil ich endlich mal was sehen musste. Im Anhang befindet sich ein Screenshot von den bisherigen Ergebnissen. Ich bin an einem Punkt angelangt, an dem ich für die Camera eine Belichtungsautomatik schreiben wollte. Dazu brauche ich weitere Basic-Subroutienen. Leider hat Bascom scheinbar einen Bug, der verhindert, dass man vernünftig funktionierende Stack-Größen definieren kann, ohne dass sich die Stacks überschreiben... Deswegen bin ich zu dem Schluss gekommen, dass um C kein Weg drum herum geht. Der Compiler ist schlicht besser und vor allem deutlich intelligenter als der Bascom-Compiler. Leider geht das ohne das externe SRAM eben unter keinen Umständen, da selbst die einfachste Bildbearbeitung auf dem AVR selbst unmöglich wird, wenn kein Ram vorhanden ist, der wenigstens ein Bild speichern kann. Von daher wäre ich wirklich sehr glücklich darüber, wenn mir noch weiter jemand hilft. Vielleicht gibt es ja eine triviale Lösung zu dem Problem.... Vielen Dank fürs Lesen! Timo
hallo, ich übertrage die daten von der gameboycam gleich zum pc über funk. dort werte ich die hindernisse aus mit purebasic und gebe dann den robby ein steuersignal zum verhalten. die auswertung der daten ist noch am anfang, gibt aber schon ergebnisse. der nachteil der gameboycam ist, das der robby bei einer aufnahme anhalten muss, ist ein mangel der gameboycam, das bild ist kein standbild. ansonsten ein interessantes projekt mit dem avr16. bei der cmucam2 klappt es besser, da wird die auswertung von der camplatine durchgeführt und der avr bekommt daten (strings), die dann sofort der avr16 bearbeiten kann, da ist mein erfolg schon bestens. kostet 129 euro, lohnt sich wirklich. die 3. möglichkeit bei mir läuft mit videocapture und einer cmoscam. ein videobild vom robby wird zum pc gefunkt. dort lese ich ein bild aus der zwischenablage mit purebasic aus und werte es in einer picturebox aus. gibt auch schon ergebnisse. castle
Tja, über Weihnachten war genügend anderes zu tun. Jetzt habe ich mir das mal angeguckt. Nachdem ich den Include von <avr/timer.h> entfernt habe (die gibt's schon lange nicht mehr) und im Makefile noch -D__STDIO_FDEVOPEN_COMPAT_12 mit angegeben habe, compiliert das Ganze auch gegen meine avr-libc 1.4. Es gibt eine Warnung (außer den "this file has moved"-Warnungen infolge der neueren avr-libc-Version), ansonsten compiliert es. Ja, eine Variable muss beim AVR-GCC wohl kleiner als 32 KiByte sein, ich denke, das hängt damit zusammen, dass die Indizierung des Speichers über einen `int' erfolgt, also eine vorzeichenbehaftete 16-bit-Zahl. Damit geht testVar[16384] als maximale Größe. Andererseits sollte deine gewünschte 128*123-Dimension da noch hereinpassen. malloc() müsste auch größere Blöcke ausfassen können, aber ich habe die Befürchtung, dass die Indexrechnererei des Compilers dir dennoch in die Suppe spucken könnte. Andererseits hast du, wenn ich deine extmem-Einstellungen richtig deute, ja sowieso nur 32 KiB externen Speicher dran, damit sollte das ja genügen.
Hallo Jörg, ja, ich habe mir schon gedacht, dass du wohl an Weihnachten was anderes zu tun hast :) Noch ein Versuch mit einer kleinen Frage vorweg: An welcher Stelle hast du die Kompatibilität zu 1.2 im Makefile angegeben? Ich kann das leider nicht finden, nachdem ich alles durchgeschaut habe. Allerdings geht bei mir die fdevopen Routine. Mit einer kleinen Warnung, aber sie läuft. Zum Thema: Ich habe heute das "How to use external RAM?" der AVR-libc Homepage durchgelesen und die entsprechende Assemblerdatei geschrieben und eingelinkt. Das läuft auch durch und sieht folgendermaßen aus: ;; begin xram.S #include <avr/io.h> .section .init1,"ax",@progbits ldi r16,_BV(SRE) out _SFR_IO_ADDR(MCUCR),r16 //ldi r16, _BV(XMBK) | _BV(XMM0) //out _SFR_IO_ADDR(XMCRB),r16 // warum das nicht geht, entzieht sich meiner Kenntnis... ;; end xram.S Um gleich an dieser Stelle zu definieren, dass ich nur 32KB SRAM angebunden habe, wollte ich das Register XMCRB entsprechend schon hier setzen. Leider bekam ich eine Fehlermeldung, mit der ich als Assembler-Laie nicht viel anfangen kann, weswegen die entsprechenden zwei Zeilen auskommentiert sind. xram.S: Assembler messages: xram.S:10: Error: number must be less than 64 Außerdem habe ich mit mfile ein neues Makefile erstellt, was jetzt den Anforderungen entsprechen sollte. Also SRAM-Größe, Adressraum ect. Um auch den Bug aus zu schließen, den du angesprochen hast, habe ich das Makefile nochmal mit deiner geänderten Zeile modifiziert. Auch weiterhin weigert sich mein Programm Arrays deutlich größer als testVar[1024] an zu sprechen. Wenn ich z.B. testVar[2048] probiere, startet der code laufend neu. Meine Hoffnung ist, dass es nurnoch einer Änderung im Assemblerfile bedarf, die entsprechend dem Compiler klar macht, dass es nur 32 KB und nicht 64KB sind. Sorry, dass ich so viel dazu schreibe, aber der Fehler ist, wenn man es nicht auf einem Prozessor testen kann, sehr komplex zu beschreiben! Der Code compiliert ja einwandfrei, nur die Ausführung haakt gewaltig. Kennst du evtl ein gutes Beispiel, wo ich mir das nochmal Schritt für Schritt abschauen kann? Ich konnte selbst nach langem suchen kein wirklich anschauliches Beispiel finden. Vielen Dank nochmal! Timo ps. ich habe nochmal den aktuellen Code mit angehängt.
Ich hab auf einem Mega64 extern 32kB RAM, das einzige was ich gemacht habe war im Makefile: EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x8090ff und bei Programstart: MCUCR = _BV (SRE) | _BV (SRW10); // externes RAM enablen, 1 Waitstate XMCRB = _BV (XMM0); allerdings mit der Einschränkung dass normale Variablen ins interne SRAM kommen, und nur der Speicher, der über malloc() angefordert wird, im externen SRAM liegt. Geht ohne Probleme.
Vielen Dank! Jetzt weiß ich, dass das wirklich geht. Das komische ist nämlich, dass mein Prozzi sich "normal" verhällt, wenn ich nur den heap in den Ext.SRAM lege. Das habe ich mal versucht. Mir war allerdings der Weg über Malloc() bislang zu komplex, weil ich damit noch nie gearbeitet habe. Du brauchtest auch keine Assemblerdatei zu schreiben, eben weil der Compiler eh keine Laufvariablen automatisch in das Ext.SRAM schmeißt. Es ist also der einfachere Weg, aber offenbar auch der bessere. Ich werde das heute nachmittag testen! Kannst du mir evtl noch posten, wie du mit Malloc() Speicher reservierst? Ich habe mir das gestern angeschaut, bin allerdings aus dem Void-Pointer nicht so richtig schlau geworden :(
uint16_t *feld; // Zeiger auf Integer // 1000 Zahlen feld=malloc(2000); oder besser: feld=malloc(1000*sizeof(uint16_t); *feld=1; // 1 in den ersten Speicherort *(feld+10)=5; // Zahl in die 10. Speicherstelle, aber 20. Byte!
Ja, genau das beispiel habe ich gesucht :) Damit wird es sicher gehen! Vielen Dank für deine Hilfe!
Guess what? Es geht! Nach Wochen des Suchens und der Undurchsicht endlich die Lösung! Vielen Dank nochmals! Timo
Achja, richtig wärs natürlich immer so zu schreiben: feld=malloc(1000*sizeof(uint16_t)); if (feld==NULL) printf("Scheisse"); Grad bei MCs hat man nicht unbegrenzt RAM :-)
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.