Hallo, für ein Projekt benötige ich ein Programm, das im Prinzip aus zwei Teilen besteht: Teil 1: Über eine Schnittstelle (RS232?) oder per Taster werden verschiedene Werte in den internen Ram des Controllers geschrieben. Dieser Teil ist vollkommen zeitunkritisch und soll (zwecks besserer Lesbarkeit) in C entstehen. Teil 2: Ein leider sehr zeitkritischer Programmteil liest die vorher gespeicherten Daten aus dem Ram und gibt sie auf einem I/O-Port aus. Der Teil soll in ASM geschrieben werden, da es hier auf jeden Takt ankommt. Mein Ansatz wäre: Statt den Stack-Pointer zu Beginn auf das Ende des Rams zu setzen, würde ich den sagen wir einfach mal auf 25% setzen (muss ich noch genau nachrechnen). Somit könnte ich die unteren 25% des Rams normal für Stack und Heap nutzen unter C. Die auszugebenden Daten muss ich "per Hand" in die oberen 75% schreiben. Vom Compiler selbst dürfte dieser Speicherbereich ja nicht "angefasst" werden können, oder? Im Ausgabeteil in ASM würde ich dann den Ram mithilfe der X/Y/Z-Register lesen und auf den Port schreiben. Der Ausgabe-Teil würde einmal durchlaufen. Die Anzahl der auszugebenden Bytes ist konstant. Kann das so funktionieren? Gibt es sinnvollere oder elegantere Lösungen? Grüße Christian
Christian schrieb: > Kann das so funktionieren? Gibt es sinnvollere oder elegantere Lösungen? Dem Linker ins Handwerk zu pfuschen ist mit Abstand die schlechteste Lösung. Leg einfach unter C die Variable an und schreib eine Dummy-Funktion, die auf diese Variable zugreift. Dann läßt Du diese Funktion nach Assembler compilieren und schon weißt Du, wie Du die Variable in Assembler zugreifen mußt. Peter
Peter Dannegger schrieb: > Dem Linker ins Handwerk zu pfuschen ist mit Abstand die schlechteste > Lösung. > > Leg einfach unter C die Variable an und schreib eine Dummy-Funktion, die > auf diese Variable zugreift. Dann läßt Du diese Funktion nach Assembler > compilieren und schon weißt Du, wie Du die Variable in Assembler > zugreifen mußt. Hallo Peter, Du meinst also, ich soll den Speicher beispielsweise mit volatile uint8_t mein_speicher[1024]; reservieren? Ich vermute, die einzelnen Elemente liegen dann auf aufeinanderfolgenden Adressen, was wohl unbedingt notwendig ist für den ASM-Teil. Mit einer Dummy-Funktion könnte ich den Zugriff tatsächlich hinkriegen. Aber liegt der reservierte Speicher dann noch an der selben Stelle, wenn ich die richtige Funktion verwende (als das Programm umgeschrieben habe)? Da mir ein wenig die Programmiererfahrung fehlt (einfache Programme in ASM aber ohne so "verrückte" Speichersachen und einfache Programme im C, wo sich ja der Compiler um den Speicher kümmert hab ich hinter mir, mehr noch nicht), kann ich nicht so recht einschätzen, warum die von mir angedeutete Lösung schlecht ist. Der Compiler dürfte doch eigentlich nur einen Mikrocontroller mit weniger Ram sehen, als er tatsächlich real hat. Der "untere" Speicherbereich würde wie normal zur Verfügung stehen und der "obere" sollte für den Compiler unzugänglich sein. Die Werte müsste ich dann vermutlich "per Hand" dort ablegen. Natürlich müsste ich dafür sorgen, dass der Stack-Pointer gleich zu Anfang des Programms manipuliert wird. (In ASM muss man den ja sowieso am Anfang angeben. Da könnte man ja stattdessen auch den "gefälschten" Wert nehmen..) Vielleicht kannst du mir den Nachteil oder meinen Denkfehler erklären :-) Grüße Christian
Christian schrieb: > Der > Teil soll in ASM geschrieben werden, da es hier auf jeden Takt ankommt. So etwas glaube ich per se erst einmal nicht. Aber wenn doch, wer sagt denn, daß Assembler-Programme nur völlig ausserhalb der Speicher-Welt von C-Programmen existieren dürfen? Du kannst selbstverständlich globale und lokale Felder und Variablen in C und /oder Assembler definieren, aus beiden Welten darauf zugreifen, und dem linker die Speicherverwaltung überlassen. Wie Peter schon schrieb, am Ende ist eh alles Assembler. Schreib in deinem C-Programm die Daten in ein globales Array, und greif aus der Assembler-Routine darauf zu. Oliver
Christian schrieb: > hinkriegen. Aber liegt der reservierte Speicher dann noch an der selben > Stelle, wenn ich die richtige Funktion verwende (als das Programm > umgeschrieben habe)? Du greifst ja aus dem Assemblerteil nicht über eine absolute Adresse zu, sondern über ein Assembler-Label, das dir der Linker dann mit der richtigen Adresse besetzt. > angedeutete Lösung schlecht ist. > Der Compiler dürfte doch eigentlich nur > einen Mikrocontroller mit weniger Ram sehen, Das fängt schon einmal damit an, das das was du vor hast, gar nicht vom Compiler erledigt wird, sondern vom Linker. Der Compiler übersetzt C-Code im Maschinensprache. Erst der Linker ordnet die Einzelteile im Speicher an. > hat. Der "untere" Speicherbereich würde wie normal zur Verfügung stehen > und der "obere" sollte für den Compiler unzugänglich sein. Der Compiler interessiert sich nicht die Bohne dafür, wieviel Speicher du hast und wo der liegt. Mein Rat läuft in dieselbe Kerbe wie der vom Oliver Schreib erst mal alles in C. Dann siehst du dir an, ob du schnell genug bist. Und erst dann, wenn feststeht, dass dein C-Code nicht schnell genug ist und du auch keine Möglichkeit mehr siehst, wie man den C Code schneller machen kann, erst dann gehts nach Assembler. Dazu nimmst du dir den vom Compiler generierten Assembler-Code und siehst dir an, wie du C-Teile gegen Assembler Teile austauschen kannst.
Für die ganz harten Jungs gibt es dann auch noch eine Doku. Ich weiß, echte Männer lesen sowas nicht, aber du musst es ja nicht weitersagen ;-) http://www.nongnu.org/avr-libc/user-manual/group__asmdemo.html Oliver
Nun gut, danke für die Tipps und Hinweise. Ich werd mich ersteinmal tiefer einlesen und das Konzept nochmal überdenken. :-) Grüße Christian
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.