Hall, ich kriege hier die Krise. Mein Speichertest auf meinem ARM9
(AT91RM9200) funktioniert wunderbar. Und zwar so wunderbar, dass er
überall - selbst dort, wo gar kein SDRAM gemappt ist, alles als in
Ordnung erkennt. Jetzt ist das Programm relativ trivial - einfach einen
Wert an eine Stelle schreiben und zurücklesen. Was kann hier schon
falsch sein? Ich komme einfach nicht mehr weiter. Lässt man die Adresse
allerdings in einen "undefinierten" Bereich laufen, kommt die
entsprechende Exception. Das zumindest funktioniert also.
Wer kann sich das mal ansehen:
Wegen:
addr = addr + 1;
müsste es nich so heisen:
addr = addr + sizeof(unsigned long);
oder:
addr++;
Müsste man im Debugger anschauen, welche wie er die Adresse
incrementiert.
Ich weiß jetzt nicht wie der CS für den externen RAM parametriert wurde,
aber kann es sein, dass der für den gesammten vom Prozessor vorgesehenen
RAM Bereich auf L geht?
Dann wird ist der RAM nämlich gespiegelt auf vielen Adressen.
Rudolf M. schrieb:> Jetzt ist das Programm relativ trivial - einfach einen> Wert an eine Stelle schreiben und zurücklesen. Was kann hier schon> falsch sein?
Das Prinzip.
Die Kapazität der offenen Pins wirkt quasi als Wort-DRAM.
Dein "dummy" wird warscheinlich nicht auf den DRAM zeigen, also erfolgt
auch kein DRAM-Zugriff.
Ist es überhaupt erlaubt, eine Zeiger auf 0 zu setzen und damit auf die
Adresse 0 zu schreiben?
Die Adreßvergabe sollte man besser dem Linker überlassen.
Peter
> müsste es nich so heisen:>> addr = addr + sizeof(unsigned long);
Nein. addr ist ein Zeiger auf unsigned long. Ein Inkrement lässt den
Zeiger auf das nächste Element zeigen.
Ändere mal dein Programm dahin, dass du zwei for-Schleifen hast.
In der ersten Schleife schreibst du deine 4 Worte und in der zweiten
Schleife liest du deine 4 Worte.
Hi,
Haette auch mal auf Mirroring (Spiegelung) getippt. Das kann vorkommen,
wenn die SDRAM-Bankgroesse nicht richtig konfiguriert ist. Dann
funktioniert der "lokale" Memorytest prima auch auf den ansich
ungemappten Adressen. Kann auch vorkommen, dass die Speichergroesse
richtig detektiert wird, aber deine Programme (die mehrere Baenke
benutzen) fiese Effekte zeigen.
Bei manchen Architekturen koennte es auch ohne Fehlkonfiguration
vorkommen.
Deswegen solltest du vielleicht deinen Test etwas umstricken:
- Erst den Speicher in logischen Page-Grössen (1024 * n) aufteilen und
am Anfang in jede Page eine eindeutige Page-Magic (oder einfach einen
Zaehler) schreiben
- Im zweiten Durchlauf die Nummern checken. So detektierst du die
effektive Speichergroesse.
Gruss,
- Strubi
Hallo,
bei einem SDRAM test macht es wenig Sinn die eben geschriebene Stelle
wieder zu prüfen. Du willst ja auch feststellen das die Refresh Zyklen
richtig funktionieren.
Besser ist es den Bereich mit einem Muster zu bespielen und dann
mehrmals wieder auszulesen. Vor dem Auslesen würde ich auch kurz warten
so das der Refresh auch zuschlägt. Denn wenn du eine Zelle liest machst
du automatisch einen refresh.
Das ganze machst du dann mit verschiedenen Mustern und
Umgebungstemperaturen.
Peter Dannegger schrieb:> Rudolf M. schrieb:>> Jetzt ist das Programm relativ trivial - einfach einen>> Wert an eine Stelle schreiben und zurücklesen. Was kann hier schon>> falsch sein?>> Das Prinzip.> Die Kapazität der offenen Pins wirkt quasi als Wort-DRAM.
Ich stimme der Aussage von Peter zu.
Du kannst das überprüfen indem du mal probehalber Pullups oder Pulldowns
an die Datenleitungen hängst. Dann wird dir dein Programm in den nicht
belegten Bereichen auch Fehler melden.
Gruß,
Magnetus
weissnix schrieb:> Ohne mich weiter mit ARM9 auszukennen, aber kann es sein, dass du in den> Cache schreibst und auch gleich wieder aus dem Cache liest?
Da möchte ich noch eine Frage anschließen.
Wie kann man im C-Programm den Cache abschalten?
Helmut S. schrieb:> Da möchte ich noch eine Frage anschließen.> Wie kann man im C-Programm den Cache abschalten?
Gute Frage!
Aus dem Buch Linux-Gerätetreiber: "Die [...] MIPS-Prozessoren machen
dies auf sehr interessante Weise. Zwei Adressbereiche mit je 512 MByte
werden direkt auf physikalische Adressen abgebildet. Jeder
Speicherzugriff auf einen dieser Adreßbereiche geht an der MMU wie auch
am Cache vorbei.
Ups, zu schnell gesendet.
Wie das bei ARM9 funktioniert weiß ich nicht. Ich nehme aber mal an,
dass man das ohne Plattform Kenntnisse gar nicht in einem Plattform
unabhängigen C Programm lösen kann.
Moin.
der Cach controller über ASM befehle configuriert. Näheres dazu findet
sich im Handbuch zum Core. Link müsste sich aufs attmels seite finden
lassen.
Der Cach Controler oder MPU oder MPC wird bei arm wie ein Co Processor
angesprochen.
Data cache war aus, der Bootloader schaltet den noch nicht ein. Die
Speicherkonfiguration war auch ok. Das Kapazitätsproblem auf dem Bus
wollte ich mit dem Dummy-Zugriff auf die Adresse 0 umgehen.
Normalerweise sollte das funktionieren.
Ich habe jetzt einfach alle
1
1024*1024/sizeof(addr)
Adressen die Adresse selbst in den Speicher geschrieben. Beim Auslesen
konnte ich dann feststellen, dass der Speicher vom SDRAM Controller
tatsächlich mehrfach hintereinander auf einen großen Adressbereich
abgebildet wird, so dass man eine Speicherzelle nach dem Ende wieder am
Anfang landet. Das Datenblatt schweigt sich zu diesem Thema leider aus.
Indem ich in einer ersten Schleife in Megabyte-Abständen die jeweilige
Adresse in die Speicherzelle schreibe und in einer zweiten Schleife die
beiden Werte wieder vergleiche, kann ich den tatsächlich vorhandenen
Speicher feststellen.
Das Ergebnis sind die erwarteten 32 MB, damit ist alles in Butter. Danke
für die Tips!
Rodolfs Problem ist gelöst, trotzdem mal noch ein Tip.
Generell macht man einen Speichertest in dem man einen String in das RAM
schreibt und diesen wieder ausliest. Dabei sollte der String aus
zufälligen Werten bestehen, die alle Datenleitungen benötigen, also
nicht nur ein lustiger Text, sondern ein lustiger Text mit Sonderzeichen
> ASCII 128.
Außerdem sollte der String eine ungerade länge relativ zum
Speicheraufbau (Pages/Rows/Columns) haben.
Nur damit kann man erkennen, ob Bits vertauscht und Seiten oder
komplette RAMs vollständig durch adressiert werden können. Damit kann
man auch erkennen, wann man, wie Rudolfs Aufbau, im Shadow gelandet ist.
Man kann den String übrigens auch absichtlich länger als den Cache einer
CPU machen, so dass das 'durchschreiben' ins physikalische RAM auch dann
garantiert ist, wenn man sich über die Verwendung von *(volatile void*)
nicht im klaren ist oder man die Konfiguration des Cache-Controllers
noch nicht völlig implementiert hat.
Gruß, Ulrich