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


von Bernhard M. (bernhard84)


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

von Gast (Gast)


Lesenswert?

aus gcc.pdf

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

von Hc Z. (mizch)


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.

von egberto (Gast)


Lesenswert?

klar geht das.....

von Bernhard M. (bernhard84)


Lesenswert?

also wie jetzt?
alles in assembler machen?

Bernhard

von Karl H. (kbuchegg)


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.

von Bernhard M. (bernhard84)


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.

von Läubi .. (laeubi) Benutzerseite


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?

von Stefan E. (sternst)


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?

von RTFM (Gast)


Lesenswert?


von sam (Gast)


Lesenswert?

1
// direktzuweisung von variablen zu registern 
2
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.

von Karl H. (kbuchegg)


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?

von egberto (Gast)


Lesenswert?

habe ich schon mehrfach ohne Probleme gemacht...z.B. hier

Beitrag "Klingel mit 100 Melodien - last minute Weihnachtsgeschenk"

von egberto (Gast)


Lesenswert?

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

http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind

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

von Stefan E. (sternst)


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
1
ich habe keine Probleme damit
zu
1
kann man so machen
ist und bleibt eine unzulässiger Schlussfolgerung.

von Stefan E. (sternst)


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.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von egberto (Gast)


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

von Stefan E. (sternst)


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.

1
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:
1
Extreme care should be taken that the entire application is compiled
2
with a consistent set of register-allocated variables, including possibly
3
used library functions.

von RTFM (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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.

von RTFM (Gast)


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.

von Vlad T. (vlad_tepesch)


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.

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
Noch kein Account? Hier anmelden.