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
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.
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?
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.
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... :-))
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
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.
;-)
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...
@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