PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Externes Speicherinterface Hintergrundwissen



Beholder321
11.07.2006, 14:57
Hi Leute,
habe vorhin schom im mikrocontroller.net Forum gepostet, vielleicht kann mir hier jemand eine Antwort geben?

Ich verwende einen ATmega128, der mit dem externen Speicherinterface
zwei SRAM-Bausteine a 512kB anspricht. Dazu verwende ich drei weitere
Port Pins als Adressleitungen und zwei Port Pins um die SRAM-Bausteine
mittels Chip Enable zu de- / aktivieren.

Um den Speicher zu testen, habe ich ein kleines Testprogramm
geschrieben, das unten dargestellt ist. Das ganze klappt auch
wunderbar
und ist soweit alles in Ordnung, ich habe nun eine Frage zu der
Initialisierung des externen Speicherinterface.

Im speziellen habe habe ich ne Frage zu dieser Codezeile


void xram(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));


So wie ich es verstanden habe sorgt man somit dafür, dass das
Speicherinterface frühzeitig initialisiert wird. Wobei die Funktion void xram(void) die jeweiligen Register setzt. Somit wird dem
Compiler? oder Linker? mitgeteilt, das er den externen Speicher nutzen
kann.

Oder sehe ich das falsch?

Ich habe das ganze auch mal ohne diese vorzeitige Initialisierung
gemacht, sondern die Funktion void xram(void) ganz normal in der
main()aufgerufen. Das Ergebnis war, dass es auch so funktionierte.

Deshalb meine weitere Frage, wozu macht man es dann und was kann
passieren, wenn mann es nicht macht?

Mir geht es darum, den Hintergrund zu verstehen, da ich es für eine
Ausarbeitung gebrauche und den Quellcode begründen soll.

Vielleicht hat der werte Herr Jörg Wunsch Zeit und Möglichkeit mir
darauf zu antworten, da ich diesen Code bzw. diese Befehlszeile in
einen Beitrag von ihn gefunden habe.

Mein kleines nicht sehr anspruchvolles, aber funktionierendes
Testprogramm ist als Dateianhang beigefügt.

Gruß und Freude
Thomas

SprinterSB
11.07.2006, 15:16
Das da oben ist ja "nur" eine Deklaration. Je nachdem, was die Funktion implementiert, erlegigt sie verschiedenes Zeut vor dem Betreten von main().

Schau doch mal im avr-gcc-Artikel im RN-Wissen in Codeausführung vor main (https://www.roboternetz.de/wissen/index.php/Avr-gcc#Fr.C3.BChe_Codeausf.C3.BChrung_vor_main.28.29) .

Beholder321
11.07.2006, 15:24
Ja das ist klar, deshalb habe ich den kompletten Quellcode ja mit drangehängt.

Meine Frage ist nur, wann muss ich die Anweisung machen, da es wie beschrieben auch ohne ging.

Oder was könnte passieren wenn ich sie nicht ausführe??

SprinterSB
11.07.2006, 15:28
Die Funktion muss nur in einer init-Section liegen. Dadurch wird sie vor main durchlaufen. Sie darf NICHT von der Applikation aufgerufen werden, da sie naked ist!

Beholder321
11.07.2006, 15:36
Leider bin ich nicht so in der Materie drin, um zu sagen was naked bedeutet. Ich bin leider kein Informatiker, deshalb kenne ich noch einige Sachen nicht. In meinem Studium als Nachrichtentechniker waren solche sachen garnicht als Stoff in der Vorlesung.

Schade eigentlich!!

SprinterSB
12.07.2006, 08:26
Das ist auch recht speziell und avr-gcc-spezifisch.

Jede Funktion in C hat einen Prolog und einen Epilog. Diese Codestückchen werden nicht durch den C-Code des Programmierers erzeugt, sondern sie bereiten die eigentliche Funktionsausführung vor bzw. nach. Im Prolog wird z.B. ein Frame angelegt (falls benötigt) Register gesichert, etc. Im Epilog werden diese Register wieder hergestellt und zum Aufrufer zurückgesprungen (ret bzw. reti).

Der in den init-Sections befindliche Code wird von init0...init9 sequenziell durchlaufen, bevor main betreten wird. Legt man eine Funktion in eine dieser Sections, dann darf sie keine ret-Anweisung enthalten (wo sollte sie auch hin zurück??? sie wird ja nicht aufgerufen!). Dies erreicht man, indem man die Funktion naked macht.

Deshalb darf eine solche Funktion auch nicht auferufen weden: Sie hat kein ret und würde nicht wiederkehren, sondern irgendwo im Startup-Code loslegen und dann wieder in main landen...

Schau einfach mal ins list-File, dann wird's vielleicht klarer.

Beholder321
12.07.2006, 10:07
Deine Antwort bringt Licht ins Dunkle!!

Also so wie der Quellcode im Dazeianhang vorhanden ist, funktioniert er auch.
Aber auch nachdem ich die (.init) Anweisung auskommentiert hatte und die Funktion xram() in der Aplikation aufgerufen hatte.

Deshalb war meine Frage auch, wann die (.init) Anweisung unbedingt gemacht werden muss.

Habe dazu auch schon ein paar Antworten im mikrocontroller.net Forum erhalten

http://www.mikrocontroller.net/forum/read-2-380653.html

SprinterSB
12.07.2006, 10:26
Wenn du den Code von xram() nicht in die init-Section legst sondern selber aufrufst (dann natürlich auch nicht als naked) dürfte es auch funktionieren, solange xram() aufgerufen wird bevor du den XRAM anfasst.
Wann denau der xram-init gemacht wird ist wohl unwesentlich, entscheidend ist, daß er gemacht wird, bevor darauf zugegriffen wird.

*grübel*

in den init-Sections steht auch Startup-Code, der den RAM initialisert, also globale Variablen mit Werten vorbesetzt. Falls globale Variablen im XRAM leben, muss der xram-init vor dem StartUp gemacht werden. Sonst werden die XRAM-Variablen nicht (richtig) initialisiert oder es gibt ne Trap oder sowas...

Beholder321
12.07.2006, 11:58
Ok, dann habe ich es nun verstanden.

Danke für die Hilfe!