mikrocontroller.net

Forum: Compiler & IDEs Ram-Nutzung C/ASM-Mischprogramm


Autor: Christian (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

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

Autor: Christian (Gast)
Datum:

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

Autor: Oliver (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Oliver (Gast)
Datum:

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

Oliver

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun gut, danke für die Tipps und Hinweise. Ich werd mich ersteinmal 
tiefer einlesen und das Konzept nochmal überdenken. :-)

Grüße
Christian

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.