Gast
#3551923
Hallo zusammen, weiß jemand, wie man auf weinem AVR32 eine C-Funktion in den RAM kopiert, und von da ausführt? Grüße M.
|
Anzeige
|
C-Funktionen vom RAM ausführen?
Gast
#3551923
Hallo zusammen, weiß jemand, wie man auf weinem AVR32 eine C-Funktion in den RAM kopiert, und von da ausführt? Grüße M. Meinst Du das hier? AVR32825: Executing code from external SDRAM http://www.atmel.com/Images/doc32160.pdf
Gast
#3551957
Also ich bin nicht wirklich fit was so Speicher angeht aber.... Das geflashte Programm liegt ja im ROM. Zur Laufzeit wird das doch in einen RAM geladen und dort ausgeführt. Odr meinst du einen externen RAM? Mike schrieb: > Zur Laufzeit wird das doch in > einen RAM geladen und dort ausgeführt. Warum sollte man das machen? Das bleibt im Flash.
Gast
#3552067
Mike schrieb: > Also ich bin nicht wirklich fit was so Speicher angeht aber.... Den Eindruck macht es. Da wird dir wohl keiner ernsthaft widersprechen wollen.
Gast
#3552157
Mark Brandis schrieb: > Meinst Du das hier? > > AVR32825: Executing code from external SDRAM > > http://www.atmel.com/Images/doc32160.pdf Ja/Nein, Ich würde gerne Code vom internen RAM ausführen.
Gast
#3552167
Ich suche auch nach einer Möglichkeit C-Funktion in den RAM zu kopieren und von da auszuführen.
Gast
#3552169
In den internen RAM Was hindert dich daran, das analog zu obiger Anleitung für ein externes RAM zu versuchen? Du erstellst eine entsprechende Section, kopierst den Inhalt beim booten an die richtige Addresse im RAM, fertig.
Gast
#3552322
Wozu eigentlich? Die Ausführungszeiten sind nicht kürzer. Der Aufwand ist größer. Code im Flash zum Einschaltzeitpunkt und später ins RAM kopieren. In diesem Umfeld kommt noch hinzu: RAM ist meist teurer.
Gast
#3552348
vn nn schrieb: > Was hindert dich daran, das analog zu obiger Anleitung für ein > externes > RAM zu versuchen? > Du erstellst eine entsprechende Section, kopierst den Inhalt beim booten > an die richtige Addresse im RAM, fertig. Also könnte ich mit der Anleitung auch auf dem internen RAM Code ausführen?
Gast
#3552372
Der Prozessor wird keine C-Funktion ausführen, weder aus dem RAM noch aus dem Flash! Die CPU versteht nur Maschinencode!
Gast
#3552378
Mike schrieb: > Der Prozessor wird keine C-Funktion ausführen, weder aus dem RAM noch > aus dem Flash! Die CPU versteht nur Maschinencode! Ich glaube er weiß, dass seine C-Funktion in Maschinencode übersetzt wird.
Gast
#3552386
Der AVR ist http://de.wikipedia.org/wiki/Harvard-Architektur Ohne Tricks geht das nicht.
Gast
#3552392
Es geht hier um den AVR32 und da geht das!
Gast
#3552393
Vielleicht geht es ja dem Thread-Ersteller nur darum mal zu testen wie man das macht und ob er es hinbekommt Code vom Ram aus auszuführen. Ob man es glaubt, oder nicht manchmal machen die Leute seltsame Sachen um sich in neue Technologien einzuarbeiten. Wenn es möglich ist, müssen die Schritte der obigen Anleitung angepasst funktionieren!
Gast
#3552404
Amateur schrieb: > Der Aufwand ist größer. Code im Flash zum Einschaltzeitpunkt und später > ins RAM kopieren. Der AVR32 AP hat gar keinen Flash ;-( Vielleicht will er einen Bootloader programmieren, welcher sich selber updaten kann oder zur Laufzeit nachladbare Programmteile (Plugins) programmieren. ;-) Georg G. schrieb: > Mike schrieb: >> Zur Laufzeit wird das doch in >> einen RAM geladen und dort ausgeführt. > > Warum sollte man das machen? Das bleibt im Flash. Er wird seine Erfahrungen auf einem anderen System gemacht haben. Bei den embedded Linux Systemen u.ä. wird das so gemacht. Amateur schrieb: > Die Ausführungszeiten sind nicht kürzer. Lt. Handbuch benötigt der Flash beim AT32UC3 1 Wait State bei 66MHz. Insofern dürfte auch beim AVR32 gelten was für viele andere Prozessoren gilt: Bei höheren Taktraten werden Programme aus dem RAM schneller ausgeführt als aus dem Flash. Daher werden auch gerne zeitkritische Interruptroutinen ins Ram verlagert.
Gast
#3552759
Code im RAM kann auch sinnvoll sein, wenn man das Flash in der Apllikation umprogrammieren will und die program/erase Wartezeiten für kritische Programmteile zu lange sind.
Gast
#3552895
Also, ich suche eine Möglichkeit um in der Laufzeit noch weitere Programmfunktionen in den AVR32 zu laden. Ob in den RAM oder in den Flash ist mir erstmal egal.
Gast
#3552908
Schon mit Linkerscripts in Berührung gekommen? Wenn nicht dann ist es jetzt Zeit dafür. Was du machen musst ist für deine Funktionen eine Section zu erstellen. Mithilfe von externen Variablen im Linkerscript überträgst du dann die Informationen, an welcher Adresse der Maschinencode im Flash steht und wie groß dieser ist, ins eigentliche C-Programm. Dann kopierst du diesen ins RAM und führst die Funktionen mittels Funktionszeiger aus. Keine Ahnung ob du noch was Spezielles beachten musst, habe nur mit ARM Erfahrung nicht mit AVR32.
Gast
#3552936
nein ich hab mich leider noch nicht mit Linkerscripts beschäftigt. Was meinst du in den RAM kopieren? Ich dachte der Maschinencode ist im Flash. Wieso im Flash? Ich denke, Du willst Code nachladen. M. schrieb: > Ob in den RAM oder in den Flash ist mir erstmal egal. Wenn der Flash-Speicher das Ziel sein soll, was ist dann bitte die Quelle?
Gast
#3552965
M. schrieb: > Was meinst du in den RAM kopieren? Ich dachte der Maschinencode ist im > Flash. Du sagst es doch schon selbst. Also entweder musst du das manuell machen oder vom Startupcode machen lassen. Linkerscript muss dann natürlich angepasst werden. Beschäftige dich erstmal mit Linkerscripts.
Gast
#3552970
ok mein Fehler. Ich würde den Maschinencode in der Laufzeit über UART empfangen und dann im RAM ausführen. So hab ich mir das erst gedacht.
Gast
#3552976
So entfällt natürlich das Linkerscript. Das wird gebraucht, wenn der zu ausführende Code mit gelinkt werden soll. Wenn du dann keine Probleme mit der PC Seite hast, ist es ziemlich einfach. Maschinencode mit UART empfangen, ins RAM kopieren, mit Funktionszeiger ausführen. Assemblerkenntnisse sind möglicherweise hilfreich. Naja, das Linkerscript wird schon gebraucht. Jedoch bei der Erstellung des Programmcodes, welcher nachgeladen wird. Der Code muss entweder adressenunabhängig compiliert werden oder eben speziell für die RAM Adresse, auf die er geladen wird. TriHexagon schrieb: > Maschinencode mit UART empfangen, ins RAM kopieren, mit > Funktionszeiger ausführen. Denke ich auch, mehr ist dazu nicht zu sagen, es sollte recht einfach sein. Wenn Du die empfangenen Daten laufend in ein Array schreibst, dann kannst Du mittels Funktionspointer (der auf das Array zeigt) dann gleich reinspringen. Sinnvoll wäre natürlich noch, das ganze nach dem Empfang mit einem CRC zu prüfen, nicht dass wegen eines Übertragungsfehlers irgend ein Scheiss ausgeführt wird.
Gast
#3559556
Wenn ich dann zum Beispiel eine Funktion im RAM ausführe, kann ich dann aus dieser Funktion heraus, Funktionen im Flash aufrufen? Müssten nicht dann die Flash und Ram-Funktionen zusammen kompalliert werden? Sonst besteht doch kein Zusammenhang, oder?
Gast
#3559683
Du kannst alle Funktionen getrennt kompilieren, aber du musst sie gemeinsam linken. Der Linker weist dann jeder Funktion eine Adresse zu, den Flash-Funktionen eine Flash-Adresse, den RAM-Funktionen eine RAM-Adresse. Der Startup-Code des Controllers muss dann die RAM-Funktionen (aus dem Flash) an ihre richtige RAM-Adresse kopieren und die Hauptfunktion anspringen. Fertig.
Gast
#3559684
Nachtrag: Wenn du das alles dynamisch haben möchtest, dann brauchst du eine Tabelle aller Funktionen mit ihrer zugehörigen Adresse. Die Adresse dieser Tabelle muss allen Beteiligten bekannt sein (z.B. per Zeiger an einer fixen Adresse)! Dann kannst du die dort aufgeführten Funktionen mit ihrem Namen anspringen, egal wo sie sich befinden.
Gast
#3559747
Wie kann man den Funktionen getrennt kompilieren? Wenn ich auf eine Funktionen im Flash zuweise, kommt ein Fehler von Kompiler M. schrieb: > Wenn ich auf eine Funktionen im Flash zuweise, wie machst du das? > kommt ein Fehler von Kompiler wie heißt der?
Gast
#3559776
Man könnte sich mal anschauen, wie der Linux-Kernel das macht. Da gibt's zwar nicht die Trennung RAM/Flash, aber es werden auch zur Laufzeit Module nachgeladen, die dann Kernel-Funktionen aufrufen können oder auch Funktionen anderer Module. M. schrieb: > Wie kann man den Funktionen getrennt kompilieren? z.B. indem Du sie per Funktionspointer anspringst, denen Du die Adresse der Funktion, wie oben beschrieben, aus der Funktionstabelle zuweist.
Gast
#3560350
Ich hab jetzt einen ganz einfachen Versuch gemacht. Ich hab eine kompilierte o-Datei mit einer LED-Blink-Funktion in eine bin-Datei umgewandelt und diese an den AVR32 über UART übertragen. Anschließend habe ich den Inhalt in den internen RAM gespeichert. Folgendermaßen sieht mein Code aus:
Die LED blinkt aber leider nicht M. schrieb: > Ich hab eine kompilierte o-Datei mit einer LED-Blink-Funktion in eine > bin-Datei umgewandelt Wie? Die Objektdatei enthält noch unaufgelöste Referenzen, welche erst durch das Linken aufgelöst werden.
Gast
#3560378
M. schrieb: > Ich hab eine kompilierte o-Datei mit einer LED-Blink-Funktion in eine > bin-Datei umgewandelt und diese an den AVR32 über UART übertragen. Das Kompilat ist nichts wert, solange der Linker nicht drübergegangen ist. Wie gesagt ihr müsst euch mit Linkerscripts und den verschiedenen Sections auseinander setzen. Ihr müsst den Linker anweisen alle Sections direkt nebeneinander zu setzen. Die .text Section und eine bestimmte Funktion direkt am Anfang setzten lassen um einfach darauf springen zu können. Den Kompiler einstellen, dass er nur relative Sprungadressen nutzt (wenn man das Programm an jede Speicherstelle setzten will). Und am Ende die elf/hex in bin umwandeln. Die Daten anschließend senden, ins RAM kopieren und an den Anfang springen (Funktionsdeklaration beachten). Das hört sich etwas kompliziert an, ist es aber nicht, Wenn man sich mit dem Linken etwas auseinander gesetzt hat.
Gast
#3560381
Ihr könnt das ja auch erstmal auf x86 probieren, dort ist es nicht anders, aber etwas zugänglicher.
Gast
#3560405
ich erstelle also zuerst eine neue Section. Kann ich die neue Section hinter dem Sack setzen? Wie kann ich dann die gelinkte Datei in den definierten RAM-Berech kopieren? Muss ich dazu umbedingt Assembler verwenden?
Gast
#3560432
M. schrieb: > ich erstelle also zuerst eine neue Section. Kann ich die neue Section > hinter dem Sack setzen? Du setzt .text .bss .data direkt nebeneinander. Für den Startcode erstellst du eine neue Section und setzt diese vor .text, also am Anfang. M. schrieb: > Wie kann ich dann die gelinkte Datei in den definierten RAM-Berech > kopieren? Muss ich dazu umbedingt Assembler verwenden? C reicht. Du kopierst die Daten wie gewohnt in den Speicher, also entweder mit memcpy() oder einer eigenen Funktion.
Gast
#3560437
Ich glaube, dir fehlt ein Verständnis dafür, was Compiler und Linker eigentlich tun. Was du vorhast, ist nicht so einfach. Object-Dateien enthalten keine gültigen Adressen, sondern nur Platzhalter. Der Linker sieht alle Funktionen eines Projekts und füllt damit alle Adressen aus. Das sind nicht nur Funktionen, sondern auch z.B. Labels oder Schleifenköpfe, weil die angesprungen werden können. Und wenn der Linker sagt, dass der Kopf deiner Endlosschleife an 0x12345678 steht, dann wird das Schleifenende an genau diese Adresse springen - egal, ob die Funktion nun da ist oder nicht. Daraus folgt: Du musst deine Funktionen als "position independent code" (PIC) kompilieren (siehe Compiler-Referenz). Nur dann kannst du die Funktion an eine beliebige Adresse kopieren und aufrufen. Dann steht da nämlich nicht mehr 0x12345678, sondern "-0x120 relativ zu PC". Also: Kompiliere deinen Blinker als PIC-Code. Dann linkst du positionsunabhängig und lässt dir das Ergebnis als binary ausgeben. Als nächsten Schritt musst du den Einsprungpunkt-Offset (d.h. die Adresse der ersten Instruktion deines Blinkers relativ zum Anfang des binary) herausbekommen. Dann kann dein Loader diese Binärdatei per UART empfangen, in einen Buffer schreiben, einen Funktionspointer auf Buffer+Offset erzeugen und den anspringen.
Gast
#3560487
Svenska schrieb: > araus folgt: Du musst deine Funktionen als "position independent > code" (PIC) kompilieren (siehe Compiler-Referenz). Nur dann kannst du > die Funktion an eine beliebige Adresse kopieren und aufrufen. Dann steht > da nämlich nicht mehr 0x12345678, sondern "-0x120 relativ zu PC". Nach deiner Erklärung muss ich keine neue Section erstellen?
Gast
#3560548
Richtig. Wenn du ein Programm hast, von dem Teile im RAM und Teile im Flash ausgeführt werden, dann kann der Linker die ganze Magie für dich machen. Dann brauchst du je eine Code-Section für Flash und RAM, sagst an, welche Funktion wo liegen soll, linkst das und fertig. Wenn du aber (relativ) unabhängige Programme per UART übertragen willst, dann ist das prinzipiell mit einem Betriebssystem und Anwendungen vergleichbar. Da gibt es dann spezielle Binärformate (ELF, PE), du musst dich mit relocation rumschlagen und so weiter. Ich vermute, dass du davon auch keine Ahnung hast. Interessiert es dich, dann gibt es unter Stichworten wie ELF-Loader genug Beispielcodes und das wäre der Weg der Wahl. Position Independent Code erspart dir Relocation auf Kosten der Performance. Ohne Relocation gibt es keinen zwingenden Grund für höhere Binärformate mehr, deswegen ist mein Vorschlag der vermutlich einfachste Weg, wenn man alles zu Fuß machen will. Sections gibt es nur bei ELF u.ä.; solange du also keine ELF-Datei per UART übertragen (und parsen) willst, kommen die Section-Definitionen auf deinem AVR32 nie an.
Gast
#3595866
Hallo, ich hab mich noch weiter mit dem Thema beschäftigt aber ich komme immer noch nicht weiter. Ich möchte den unteren Code positionsunabhängig kompilieren und über UART an den AT32UC3B0256 übertragen und in den RAM kopieren. Im RAM möchte ich den Code dann ausführen. Dieser Code befindet sich in helloworld.c
Mein Code kompiliere ich mit folgenden Befehl avr32-gcc -c helloworld.c -fpic Heraus kommt die Objektdatei helloworld.o Wenn ich diese Datei mit dem unteren Befehl disassembliere, bekomme ich folgendes: avr32-objdump mp_init.o -xd
Ist das soweit richtig und wie muss ich jetzt weiter vorgehen?
Gast
#3595871
Wie linke ich diese Objektdatei jetzt? Oder erzeuge ich mir daraus direkt eine .bin?
Gast
#3596303
Jemand eine Idee?
Gast
#3596643
Jemand eine Idee?? Vielleicht hilft dieser Thread weiter: http://embdev.net/topic/129598 Da ist auch ein Link auf ein Beispiel drin, wenn auch nicht für AVR32. Globale Variable dürften ein Problem darstellen.
Gast
#3598705
Hat schon jemand mit position unabhängigen code Erfahrung?
Gast
#3601519
Mark Brandis schrieb: > Vielleicht hilft dieser Thread weiter: > > http://embdev.net/topic/129598 > > Da ist auch ein Link auf ein Beispiel drin, wenn auch nicht für AVR32. hat irgendwie leider nicht weiter geholfen Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|