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.