Forum: Compiler & IDEs globale Variablen als struct trotz volatile?


von Phil (Gast)


Lesenswert?

Hallo,

bisher haben wir für die Kommunikation z.B. über den UART zwei globale 
Variablen verwendet. Wobei eine den Empfangsbuffer darstellt und die 
andere ein Flag, dass der main() Funktion signalisiert, dass ein 
kompletter Datenblock empfangen wurde.

Beide Variablen sind als volatile deklariert, weil auf diese im IRQ wie 
auch in der main() zugegriffen wird. In dem Artikel zur Code-Optimierung 
ist nun beschrieben, dass es bei globalen Variablen sinnvoll ist diese 
in einer struct zusammenzufassen. Dies würde den Code auch etwas 
aufräumen.

Ist dieses Vorgehen auch für die Kommunikation mit einem IRQ sinnvoll 
oder würde jetzt bei jedem Zugriff auf das Empfangsflag der gesamte 
Empfangsbuffer jedesmal geholt werden und beim Schreiben des Flags der 
gesamte Buffer neu geschrieben?

Ich denke dabei an folgendes Beispiel:

volatile struct {
unsigned char flag;
unsigned char buffer[20];
}

Oder ist vielleicht eine völlig andere Möglichkeit Daten mit dem IRQ 
auszutauschen viel sinnvoller?

Vielen Dank schonmal

von Micha S. (e-tec)


Lesenswert?

Auf IRQ verzichten und die flags mittels einer passenden funktion 
(enthält dann den code deines interrupts) auswerten (zyklische abfrage 
ob eins der i-flags gesetzt ist). nihct vergessen den zugehörigen 
interrupt zu deaktivieren!

grüße

von Phil (Gast)


Lesenswert?

Vielen Dank für Deine Antwort. So machen wir es auch in vielen Projekten 
bei denen der Controller keine weiteren zeitaufwendigen Dinge erledigt. 
In diesem Fall werden allerdings lang laufende Funktionen im 
Hauptprogramm ausgeführt. Durch den  Buffer bekommt das Hauptprogramm im 
Prinzip immer soviel Zeit wie das Empfangen eines ganzen Blocks dauert 
(es wird zwar unterbrochen, aber darum muss man sich nur wenig kümmern).
Wenn ich Deinen Vorschlag richtig verstehe darf das Hauptprogramm dabei 
nicht länger beschäftigt sein als es Zeit zwischen zwei Bytes gibt. Das 
wäre nicht praktikabel.

Viele Grüße

von Micha S. (e-tec)


Lesenswert?

Ja da hast du recht, sonst würden daten verloren gehen.
Hast du es denn schon ausprobiert was ein struct mit einer volatile 
macht? sollte im prinzip ja genauso funktionieren, nur das die vol. var 
länger braucht (lesen / schreiben), da sie in einem anderen 
speicher(bereich) steht. und ob es jetzt eine 8 bit variable ist oder 
ein struct darf meiner meinung nach keinen unterschied machen. einfach 
mal ausprobieren :))

von Micha S. (e-tec)


Lesenswert?

so habs grad ausprobiert, scheint zu funktionieren!

code (ist von was anderem also wunder dich nicht):
1
volatile struct filter_speicher
2
{
3
               // Wertespeicher für filter.c
4
               ui16 values1[werte];
5
               ui16 values2[werte];
6
               ui16 values3[werte];
7
               ui16 values4[werte];
8
} filter;

von Karl H. (kbuchegg)


Lesenswert?

Phil schrieb:

> In dem Artikel zur Code-Optimierung
> ist nun beschrieben, dass es bei globalen Variablen sinnvoll ist diese
> in einer struct zusammenzufassen.

Ob das tatsächlich optimiert oder nicht hängt vom Einzelfall ab. Es kann 
was bringen (in Punkte Codegröße), aber in den meisten Fällen würde ich 
das bezweifeln.

> Dies würde den Code auch etwas
> aufräumen.

Das zweifellos, weil du durch die Struktur eine logische Gliederung 
schaffst, in der du Dinge die zusammen gehören auch logisch 
demenstprechend gruppierst. So wie Vorname und Nachname zusammen gehören 
oder Tag/Monat/Jahr zusammen ein Datum bilden.

> Ist dieses Vorgehen auch für die Kommunikation mit einem IRQ sinnvoll
> oder würde jetzt bei jedem Zugriff auf das Empfangsflag der gesamte
> Empfangsbuffer jedesmal geholt werden und beim Schreiben des Flags der
> gesamte Buffer neu geschrieben?

Warum soll der jedesmal geholt werden nur weil du auf das Flag 
zugreifst? Der Compiler weiß doch, wo das Flag im Speicher liegt und 
holt den Wert von dort. Die Struktur ist hier mehr eine logische 
Gruppierung als sonst irgendwas.

> Oder ist vielleicht eine völlig andere Möglichkeit Daten mit dem IRQ
> auszutauschen viel sinnvoller?

:-)
Du hast gar keine andere Möglichkeit als über globale Variablen zu gehen 
oder über Funktionen, die sich die Werte zumindest modulglobal merken. 
Da ist der direkte Zugriff auf globale Variablen so gesehen noch die 
harmlosere Variante auch wenn man auf 'den großen Systemen' die Parole 
hat: keine globale Variablen.


Die Wiki-Seite mit den Optimierungen ist mit Vorsicht zu geniessen. 
Optimierungen ändern sich mit jeder Compilervresion. Was heute noch gut 
war, kann morgen schon kontraproduktiv sein. Von daher sollte deine 
Hauptdevise lauten: schreib deinen Code so, dass er gut lesbar und 
wartbar ist. Dann entscheide ob er schnell genug ist und erst dann fang 
mit Optimierungen an.

Premature optimization is the root of all evil.

von Detlev T. (detlevt)


Lesenswert?

Es ist doch auch möglich, nur einige Mitglieder der struct volatile zu 
deklarieren, oder nicht. (Mein Programm funktioniert jedenfalls damit 
:-) )

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.