mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVRGCC globale Variable in festem Register


Autor: Bernhard Mayer (bernhard84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich möchte aus Geschwindigkeitsgründen eine globale Variable einem 
festen Register zuweisen. d.h. dass die variable uint8_t x nicht im RAM 
gespeichert wird, sondern im z. B. nur im Register R16. Dadurch will ich 
vermeiden, dass am Anfang einer Interruptroutine erst die ganzen 
Register mit push und pop gesichert und dann die Variablen aus dem RAM 
gelesen werden müssen.

Wie kann ich das dem avrgcc mitteilen? oder geht das gar nicht?

Danke
Bernhard

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aus gcc.pdf

You can define a global register variable in GNU C like this:
register int *foo asm ("a5");

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für eine globale Variable wird das nicht gehen.  Selbst wenn avr-gcc die 
Möglichkeit hätte, würde das bedeuten, dass Du die ganze C-Library neu 
übersetzen musst, denn die kann ja nichts davon wissen.

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klar geht das.....

Autor: Bernhard Mayer (bernhard84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also wie jetzt?
alles in assembler machen?

Bernhard

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

Bewertung
0 lesenswert
nicht lesenswert
Lass es besser bleiben.
Im Normalfall ist es keine so gute Idee, dem Compiler da ins Handwerk zu 
pfuschen. Wie Hazeh schon geschrieben hat, kann das mächtig ins Auge 
gehen, wenn du Funktionen aus der C-Runtime Library benutzt.

Und dadurch, dass du an dieser Stelle dem Compiler ein Register nimmst, 
kriegt der Compiler an anderen Stellen unter Umständen kräftige 
Probleme, weil ihm dann genau dieses Register fehlt.

Aus diesem Grund ignorieren praktisch alle Compiler seit langem das in C 
vorgesehene 'register' Schlüsselwort und verlassen sich lieber auf ihre 
eigene Datenflussanalyse als darauf, dass der Programmierer den 
Überblick hat, wieviele und welche Register vorhanden und frei sind, um 
dort oft benutzte Werte abzulegen.

Autor: Bernhard Mayer (bernhard84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider muss ich es aber machen, da meine ISR innerhalb von etwa 50 
Taktzyklen reagieren muss und ein bisschen was berechnen muss und da 
komme ich mit den ganzen push und pop nicht hin.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard Mayer schrieb:
> Leider muss ich es aber machen, da meine ISR innerhalb von etwa 50
> Taktzyklen reagieren muss und ein bisschen was berechnen muss und da
> komme ich mit den ganzen push und pop nicht hin.
Wie wäre es den dann mit einer "naked" ISR und inline ASM?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läubi .. schrieb:

> Wie wäre es den dann mit einer "naked" ISR und inline ASM?

Sofern man nicht schon mit Inline-ASM vertraut ist, ist eine separate 
Asm-Datei die bessere Wahl, da einfacher.

@  Bernhard Mayer:
> komme ich mit den ganzen push und pop nicht hin.

Du rufst doch nicht etwa in der ISR eine andere Funktion auf, oder?

Autor: RTFM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: sam (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
// direktzuweisung von variablen zu registern 
register volatile uint8_t mask0_r10 asm ("r10");
man kann da ruhig dem kompiler ins handwerk pfuschen ... ich hab 8 
Register auf diese weise belegt und keinerlei probleme damit.

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

Bewertung
0 lesenswert
nicht lesenswert
Nochmal, das das geht bezweifelt keiner.

Aber: Du musst dann auch die C-Runtime Library mit dieser neuen 
Einschränkung neu kompilieren. Ansonsten kann beim ersten Aufruf einer 
Standard-Funktion alles mögliche passieren ...
...
WEIL DIESE LIBRARY FUNKTIONEN NICHTS DAVON WISSEN, DASS EIN REGISTER 
ABGEZWACKT WURDE

Welcher Teil dieses Satzes ist unverständlich?

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe ich schon mehrfach ohne Probleme gemacht...z.B. hier

Beitrag "Klingel mit 100 Melodien - last minute Weihnachtsgeschenk"

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann bitte mal konkret - AVRGCC - wo gibt es denn da die Kollisionen 
mit

http://www.nongnu.org/avr-libc/user-manual/FAQ.htm...

Welche Funktionen aus der C-Runtime benutzen denn diese Register?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:
> habe ich schon mehrfach ohne Probleme gemacht...z.B. hier

Du benutzt dort ja auch keinerlei "echte" Funktion aus der Lib.

Von
ich habe keine Probleme damit
zu
kann man so machen
ist und bleibt eine unzulässiger Schlussfolgerung.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:

> Welche Funktionen aus der C-Runtime benutzen denn diese Register?

Disassembliere die Lib, und schaue nach. Vielleicht keine. Aber selbst 
dann kann es mit der nächsten Version der Lib schon ganz anders 
aussehen.

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

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:

> Welche Funktionen aus der C-Runtime benutzen denn diese Register?

Ich denke nicht, dass man als Programmierer sich darüber Gedanken machen 
müsste / sollte. Denn:
* Wird im Compiler der Optimizer verändert, kann sich alles umdrehen.
* Macht man im Applikationsprogramm zu Debug-Zwecken nur einen
  simplen itoa rein, kann es zu dubiosen Fehlern kommen.
  (Selbiges mit allen anderen Library Funktionen)

Die Frage lautet: Soll man sich als Programmierer wirklich solche schwer 
zu überschauenden Abhängigkeiten schaffen?

Wenn die Not groß ist, kann ich das vielleicht noch akzeptieren. Aber 
selbst dann würde ich alles daran setzen, keine speziell angepasste 
Runtime-Library zu benötigen. Das sind Zeitbomben.

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

Bewertung
0 lesenswert
nicht lesenswert
Muss ja auch gar nicht die Runtime Library sein.
Der nächste, der deine Klingel einsetzen will und sich als Zusatz ein 
LCD  (zb mit den bewährten Fleury Funktionen) zusätzlich drann bauen 
will, wird sich schön bei dir bedanken, wenn er nach Stunden draufkommt, 
dass du ein paar Variablen fix in Register gelegt hast und er jetzt 
Register-Clashes mit zb den LCD-Funktionen hat. Da kommt er nicht gleich 
drauf, nein, das dauert lange, bis er merkt, dass Variablen 
'seltsamerweise' magisch ihre Werte auf unverhersehbare Weise ändern.

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich spreche auch nur für den Hobbybereich!

Ich habe obiges Manual quasi als "offiziell" angesehen - soll heißen, 
für die aktuelle Compilerversion gilt das geschriebene oder?

Diese Register wurden auch nur wegen platzknappheit verwendet - schön, 
wenn man noch solche Reserven hat.

Und wer zusätzlich noch Code der gleichen "Machart" verwendet, muß eben 
sehr genau hinschauen...

Grüße,

egberto

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:

> Ich habe obiges Manual quasi als "offiziell" angesehen - soll heißen,
> für die aktuelle Compilerversion gilt das geschriebene oder?

Ja. Da steht aber auch nicht, dass man das gefahrlos machen kann.

Typically, it should be safe to use r2 through r7 that way.
Man beachte das "typically" und das "should".

Und vor allem beachte man diesen Satz dort:
Extreme care should be taken that the entire application is compiled
with a consistent set of register-allocated variables, including possibly
used library functions.

Autor: RTFM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die GPIORs sind übrigens eine gute Alternative zu Registern.
Leider gibts viel zu wenige davon :-)

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

Bewertung
0 lesenswert
nicht lesenswert
egberto schrieb:
> Ok, ich spreche auch nur für den Hobbybereich!

Gerade dort würde ich das nicht machen.
Professionals dokumentieren so was nämlich ausführlichst und weisen 
darauf hin. Hobbyprogrammierer tun das nicht.

> Ich habe obiges Manual quasi als "offiziell" angesehen - soll heißen,
> für die aktuelle Compilerversion gilt das geschriebene oder?

Das Manual ist auch ok.
Aber auch dort steht ja explizit (wenn auch nicht sehr deutlich) 
drinnen, dass besondere Vorsicht geboten ist.

> Diese Register wurden auch nur wegen platzknappheit verwendet - schön,
> wenn man noch solche Reserven hat.

Schon klar. Bei dir macht dieser Unterschied gerade die paar Bytes aus, 
damit noch alles in den Tiny reinpasst. Mit einer grossen Warnung, die 
auch ein Blinder aus 3 Meter Entfernung noch ertasten kann, ist das ok.

> Und wer zusätzlich noch Code der gleichen "Machart" verwendet,

Muss noch nicht einmal 'die gleiche Machart sein'. Stinknormaler, 
üblicher C-Code aus einer anderen Quelle, der sich an die üblichen 
Regeln hält, reicht bereits.

> muß eben
> sehr genau hinschauen...

Genau darum gehts. Die Praxis zeigt, dass 'dann muss man eben genau 
schauen', eine regelmässige Zeitbombe ist. In einem halben Jahr weiß das 
nämlich kein Mensch mehr.

Autor: RTFM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe allerdings noch nie Probleme mit r2 bis r6 gehabt.
Bei keiner Compiler/Stdlib Version.

Einfach machen und die Bedenkenträger ignorieren.
Zur Doku schreibst du eine kleine Warnung zur Erinnerung und dann die 
aktuell verwendete Compiler/stdlibversion in den Quältext - und gut is.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
man kann auch register unbenutzter µC funktionen für solche sachen 
benutzen.
Bei denen kommt der Kompiler nicht auf die Idee, sie verwenden zu wollen 
und die haben außerdem noch den Vorteil, dass sie bit-adressierbar sind.
Dh, man kann zB, 8 seperate Flags unterbringen, was nützlich ist um aus 
der Intteruptroutine an die Hauptschleife Flags zu übermitteln, ohne das 
jedes mal erst der Ram gelsesn werden muss (oder zusätzlich noch die 
Bits ausmaskiert werden müssen).

Dazu bieten sich zB folgende Register an:
EPPROm Daten+Adress-Register, so lange man den eeprom nicht braucht.
timer-compare register von unbenutzten Timern.
timer-counter register von unbenutzten Timern.
Daten- und Datenratenregister der seriellen schnittstellen (USI,UART, 
SPI, TWI), solange man die nicht braucht.

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.