Forum: Compiler & IDEs GPIOR0 als globale volatile Variable


von OlliW (Gast)


Lesenswert?

Hallo Zusammen,

ich komme nicht dahinter und/oder bin zu dumm die Lösung im Netz zu 
finden:
ich will eines der SFRs beim AVR wie z.B. das GPIOR0 als globale 
Variable (keine Bits bzw. Flags) zum Austausch zwischen main und 
Interrupt-Routinen benutzen.

Als Ansätze für Lösungen habe ich z.B. gefunden #define variablennamen 
GPIOR0, oder die Lösung hier 
Beitrag "variable/zeiger in GPIOR0 fest registrieren", die ich allerdings 
nicht verstehe (was mich ärgert :-)).

Tut's #define variablename (* (*((volatile unsigned char**) (&GPIOR0))) 
)?

Was das tut verstehe ich wie gesagt nicht, aber es kompiliert zumindest, 
ergibt bei mir mit -Os allerdings 2 Byte grösseren Code als volatile 
unsigned char variablename und scheint also nichts zu bringen.

Wie ginge es richig?


Danke schon mal,
  Olli

von Stefan E. (sternst)


Lesenswert?

GPIOR0 ist quasi bereits eine globale volatile Variable und kann 
direkt als solche verwendet werden. Wenn du der Variable einen eigenen 
Namen geben willst, dann reicht ein einfaches #define.
1
#define SomeVar GPIOR0
2
3
main () {
4
5
    while(SomeVar < 10) {}
6
}
7
8
ISR () {
9
10
    SomeVar++;
11
}

von OlliW (Gast)


Lesenswert?

Hallo Stefan,

ja, das hatte ich ja auch schon geschrieben (:-)), aber wie sag ich's 
dem Compiler das die auch noch volatile ist?

Danke trotzdem,
  Olli

von (prx) A. K. (prx)


Lesenswert?

Das sind die SFRs doch per Deklaration sowieso schon alle.

von OlliW (Gast)


Lesenswert?

AHA... das war ein nützlicher Hinweis. Tatsächlich, in sfr_defs.h steht 
was ähnliches wie in dem zitierten Beitrag oben:

#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

Cool, das hätte ich nie gefunden weil ich gar nicht auf die Idee 
gekommen wäre da zu suchen... DANKE!

Olli

PS: ich finde ja das es sehr nützlich ist wenn gerade auch solche 
"Kleinigkeiten" im Tutorial stehen, jetzt würde ich mich aber in 
Anbetracht meines Nichtprofistatus nie trauen da selber etwas 
reinzueditieren. Wie ist das eigentlich, könnte oder sollte ich z.B. das 
ins Tutorial schreiben, kann ich dabei etwas "kaput" machen, und kann 
man damit rechnen dass es "Korrektur gelesen wird", also wenn es nicht 
ganz richtig oder gar falsch dargestellt wäre schon von "irgendjemanden" 
auskorrigiert werden würde?

von Stefan E. (sternst)


Lesenswert?

OlliW schrieb:

> man damit rechnen dass es "Korrektur gelesen wird", also wenn es nicht
> ganz richtig oder gar falsch dargestellt wäre schon von "irgendjemanden"
> auskorrigiert werden würde?

Ja, davon kannst du ausgehen.
Ich z.B. sehe die Änderungen dort relativ regelmäßig durch, und ich bin 
sicher auch nicht der einzige, der das macht.

von Oliver W. (olliw)


Lesenswert?

Super. Dann hoffe ich mal dass du oder sonstwer über den Absatz 
Speichern von globalen volatilen Variablen auf der avr-gcc 
Codeoptimierungsseite stolpert... war aufregend da zum erstenmal was 
reinzuschreiben... :-)

DANKE nochmals zusammen!

(mein ca. 1k grosser Code mit 3 globalen volatilen Variablen ist mit den 
GPIROs um 70bytes geschrumpft (-Os)... lohnt sich also ziemlich... :-))

von Peter D. (peda)


Lesenswert?

Oliver W. schrieb:
> (mein ca. 1k grosser Code mit 3 globalen volatilen Variablen ist mit den
> GPIROs um 70bytes geschrumpft (-Os)... lohnt sich also ziemlich... :-))

Das sind 35 Instruktionen.
Ich vermute mal, daß die Funktion zum Datenaustausch mit dem Interrupt 
mehrmals ge-inlined wird und daher die Einsparung.
Nochmehr spart das Inlining abschalten: -fno-inline-small-functions


Peter

von Stefan E. (sternst)


Lesenswert?

Oliver W. schrieb:
> Super. Dann hoffe ich mal dass du oder sonstwer über den Absatz
> Speichern von globalen volatilen Variablen auf der avr-gcc
> Codeoptimierungsseite stolpert... war aufregend da zum erstenmal was
> reinzuschreiben... :-)

Bevor ich da was ändere, möchtest du es ja vielleicht selbst machen. Ich 
hätte da nämlich 3 Sachen:

1) Der erste Satz suggeriert, dass man auch für die Kommunikation 
zwischen 2 Interrupt-Funktionen grundsätzlich eine volatile Variable 
braucht. Dem ist nicht so. Außer in dem seltenen Fall, dass man ihnen 
erlaubt, sich gegenseitig zu unterbrechen. Ich würde z.B. einfach dieses 
Stück Text "z.B. Interruptroutinen oder" entfernen.

2) Du hast nur dann mit der Methode einen nennenswerten Vorteil 
gegenüber einer normalen Variable, wenn das SFR in dem Bereich liegt, 
der per IN/OUT erreichbar ist. Andernfalls spart man lediglich ein Byte 
SRAM. Codegröße und Geschwindigkeit sind dann ansonsten identisch zur 
normalen Variable. Ich denke, diese Einschränkung sollte mit einfließen, 
z.B. dort wo du ein paar mögliche SFRs auflistest.

3) Beim Source-Code unbedingt das Semikolon hinter GPIOR0 entfernen.
(und ein paar Leerzeilen wären auch nicht schlecht)

Ansonsten ist es für einen ersten Beitrag zum Wiki nicht so schlecht. 
;-)

von Sven P. (Gast)


Lesenswert?

Hm, es gibt da zwei Grundsätze beim Optimieren:
Regel 1: Tu es nicht.
Regel 2: Tu es noch nicht.

Ich nehme mal nicht an, dass du auf nem Tiny mit 1kB Programmspeicher 
arbeitest oder? Leeren Programmspeicher kannst du später nämlich nicht 
mehr umtauschen...

von OlliW (Gast)


Lesenswert?

@Stefan: Tausend Dank für die Hinweise.
1) hätte ich eigentlich gewusst und verstehe es, habe aber nicht genau 
genug beim schreiben nachgedacht. Ändere ich.
2) ich glaube zu ahnen was du meinst, bin mir aber nicht sicher ob ich 
das 100% verstehe (ich kenne den Unterschied mit dem bit setzen, dachte 
aber das alle SFRs nur mit IN/OUT erreichbar sind). Kurz, da fühle ich 
mich gerade nicht kompetent und es wäre mir ehrlich gesagt lieber wenn 
das jemand kompetenter ändern würde...
3) jo, das war schlampig, ändere ich.

@Sven: ne, Platzmangel war nicht wirklich der ausschlaggebende Faktor, 
die Preisunterschiede bei 1k-8k kann ich bei meinen kleinen Stückzahlen 
verschmerzen (gibt's halt mal ein Eis weniger...). Bei diesem Beispiel 
war es allerdinsg so dass der Code zunächst knapp über 1k war und ich 
zwei ATtiny13A rumliegen habe und mir so gedacht habe, mal sehen ob 
ich's kleiner bekomme, schon auch nur um dazuzulernen und auch mal zu 
sehen was was wie in der .lss ändert. Es hat mich einfach interessiert, 
und ich habe ja auch einiges dazugelernt. Auch wenn es jetzt in einen 
ATtiny13 passt, werde ich die Schaltung trotzdem mit nem ATtiny45 bauen 
(man weis ja nie was man nicht noch alles implementieren will).

@Peter: bei dem speziellen Beispiel habe ich 3 ISRs und eine main, mehr 
nicht. Habe es gerade noch bei einem anderen Code ausprobiert, und da 
ist der Platzspaareffekt geringer.

Olli

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.