www.mikrocontroller.net

Forum: Compiler & IDEs Befehle in anderen Speicher umkopieren und ausführen


Autor: Wazaaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 !

Autor: Karsten Brandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen Prozessor und welche Entwicklungsumgebung setzt Du ein?

Karsten

Autor: Wazaaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze einen ATMEL AT91RM9200 und benutze das ARM-elf-GCC Paket.
Aber wieso sollte das relevant sein ?

Autor: Heinz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Wazaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Wazaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan

Klasse, genau was ich suche ! Manchmal fehlt einem einfach nur das
richtige Schlagwort.

@ all

Tausend dank euch allen :)

Autor: Wazaaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Heinz M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Wazaaab (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.