Hallo Leute, ich zerbreche mir jetzt schon seit Stunden den Kopf, wie man folgenden Sachverhalt bewerkstelligen könnte : Ich programmiere einen ARM in C (++). Weil ich am setting des Programmspeichers, in dem das Programm läuft, herumfeilen möchte, muss ich die entsprechenden Befehle ins RAM umkopieren, und dort ausführen. Anschließend soll das Programm wieder zurück in den ursprünglichen Speicher zurückhüpfen und normal weitermachen. Ich wollte die kritischen Befehle in eine Funktion packen, und mit memcpy ins SRAM schieben. Anschließend den Programmcounter umstellen und gut ist. Nun aber die Probleme dieser herangehensweise : 1. Wieviel muss ich umkopieren, bzw. wie groß ist diese Funktion. Gibt es vielleicht etwas wie sizeof() für Funktionen ? 2. Wie springe ich wieder zurück ins RAM ? Wo ist die Rücksprungadresse ? Wie komme ich wieder dahin ? Oder fällt euch da spontan was wesentlich besseres ein ? Bin für alles offen !
Welchen Prozessor und welche Entwicklungsumgebung setzt Du ein? Karsten
Ich benutze einen ATMEL AT91RM9200 und benutze das ARM-elf-GCC Paket. Aber wieso sollte das relevant sein ?
Du solltest Dich - mit Linker-Scripten (->GNU ld doc) - evtl mit PIC (position-independent code) beschaeftigen. Sprung ins RAM per Funktionsaufruf? Zurueck per return? h.
Hallo Heinz, danke für die Antwort. Ich werde mich mal in diese Richtung schlau machen. Über das LinkerScript habe ich bereits nachgedacht. Wenn ich die Funktion in den RAM linke habe ich jedoch Probleme sie im BootROM mit dem Funktionspointer für das Umkopieren zu finden, oder ? Schließlich sollte der ja dann auf das RAM zeigen. Wie der Sprung ausgeführt werden soll ist eigentlich egal. Wichtig ist nur, dass ein gewisses Codestück nicht aus dem BootROM läuft.
http://www.google.de/search?hl=de&q=arm7+ram+functions&meta= => http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#gcc_ramfunc http://www.mikrocontroller.net/forum/read-1-337246.html
@ Stefan Klasse, genau was ich suche ! Manchmal fehlt einem einfach nur das richtige Schlagwort. @ all Tausend dank euch allen :)
So, habe das Teil entsprechend eingebunden. Funktioniert insoweit einwandfrei :)) Nun möchte ich die Umkopierfunktion in C bewältigen, was ja auch weiter nicht sonderlich schwer ist. Was mir aber leider nach ein einigem Rumprobieren nicht gelungen ist, ist die Adresse des in den RAM gelinken Teils herauszufinden. Wie kann ich denn generell aus C die Adressen der im Linkerscript definierten Speicherbereiche herausbekommen ? bzw. auf die dort definierten Labels zugreifen ?
Es ist moeglich, auf im Linkerscript definierte Symbole zuzugreifen, wie auf in anderen C Modulen definierte Variablen. Wie das geht, sollte z.B. in http://sourceware.org/binutils/docs-2.16/ld/index.html zu finden sein... Du interessierst Dich fuer "LMA" (nicht LMAA!;-) und "VMA". h.
Im Moment werden DATA und Ramfunktionen komplett kopiert, da im angegebenen Beispiel keine Unterteilung Data<->Funktionen vorhanden ist. Die betreffenden globalen Symbole (_etext, _data und _edata) aus dem ASM Startup-Code könnte man durchaus als externe Adressen in eine lowlevel C-Kopierfunktion übernehmen. Du könntest über _my_own_symbol = .; bestimmt auch eigene Symbole vor/nach deinen Funktionen initialisieren... Die Startadresse der Ramfunktionen nach dem Umkopieren kannst du über den Adressoperator & herausfinden herausfinden. Du machst quasi einen Funktionspointer. Mit der Endadresse der Funktion ist es kitzliger. Mir fällt als Endadresse auf die Schnelle nur eine Dummyfunktion nach dem Ende der Nutzfunktion(en) ein. Aber ehrlich gesagt, ich verstehe allerdings den Sinn der angefragten Aktion nicht.
@Heinz Genau das wars :)) Es läuft ! 2^10 Dank ! Wäre natürlich schön, wenn man direkt die LMA herausbekäme und nicht die Krücke mit den Symbolen anderer Bereiche benutzen müßte. Aber wenns läuft, läuft es ! @Stefan >Die Startadresse der Ramfunktionen nach dem Umkopieren kannst du über >den Adressoperator & herausfinden herausfinden. Du machst quasi einen >Funktionspointer. Mit der Endadresse der Funktion ist es kitzliger. >Mir >fällt als Endadresse auf die Schnelle nur eine Dummyfunktion nach dem >Ende der Nutzfunktion(en) ein. Genau das waren auch meine ersten Ansätze. Ist alles zu kompliziert. Die Funktion wird mit _attribute_ ((long_call, section (".ramcopy")) einem selbstdefinierten Speicherbereich ramcopy zugeordnet. Dieser wird im Linkerscript virtuell in den RAM gemappt. Mit Hilfe eines Symboles am Ende des Bereichs davor, kann in C mit extern variablen auf diese Bereiche bzw. Adressen zugegriffen werden. Das Umkopieren geht damit super einfach. Der Rücksprung geschieht dann einfach beim beenden der Funktion automatisch. Ist ja auch ne ganz normale Funktion, die nur in einem speziellen Speicherbereich liegt. Ein entsprechendes C-Beispiel ist in dem Link von Heinz.
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.