Mega128 + gcc + 32k externes SRAM --> läuft nicht

Gast #284627
Lesenswert?

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
Angehängte Dateien:
Gast #284629
Lesenswert?

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
Gast #284632
Lesenswert?

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
Angehängte Dateien:
Gast #284633
Lesenswert?

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.
Gast #284634
Lesenswert?

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
Angehängte Dateien:
Gast #284635
Lesenswert?

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
Moderator Persönliche Seite #284636
Lesenswert?

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.
Gast #284637
Lesenswert?

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.
Angehängte Dateien:
#284638
Lesenswert?

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.
Gast #284639
Lesenswert?

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 :(

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren