Forum: Compiler & IDEs [AVR] Structs innerhalb von ISR auch ohne volatile?


von Markus (Gast)


Lesenswert?

Hi, ich bastle gerade an der AVR134 AppNote rum (Software RTC). Mir ist 
da gerade aufgefallen, dass die Struct für DateTime nicht volatile ist, 
aber sowohl innerhalb als auch außerhalb verwendet wird.
1
typedef struct{ 
2
unsigned char second;   //enter the current time, date, month, and year
3
unsigned char minute;
4
unsigned char hour;                                     
5
unsigned char date;       
6
unsigned char month;
7
unsigned int year;      
8
            }time;
9
10
 time t;

Trotzdem funktioniert der Code. Ist das jetzt eher Zufall oder ist das 
so beabsichtigt?

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

Hi Markus,

Aber ohne weiteren Programmcode kann dir keiner Helfen !

Ich gehe mal von der angehängten Datei aus oder ?

t wird nicht in der Main gelesen, also ist das auch kein Problem mit der 
ISR.

von Markus (Gast)


Lesenswert?

Doch, t wird sowohl in Main als auch in der ISR verwendet. Hier ein 
Ausschnitt aus der ISR
1
ISR(TIMER2_OVF_vect) //overflow interrupt vector
2
{ 
3
    
4
    if (++t.second==60)        //keep track of time, date, month, and year
5
    {
6
        t.second=0;
7
        if (++t.minute==60) 
8
        {
9
            t.minute=0;
10
            if (++t.hour==24)

Und ein Ausschnitt aus main()
1
void init_rtc(void)
2
{
3
  t.second=0;
4
  t.minute=0;
5
  t.hour=21;
6
  t.date=11;
7
  t.month=7;
8
  t.year=2011;
9
}
10
                                       
11
int main(void)
12
{                        
13
  //char rtc_time[8];  
14
    char temp[4];
15
    init_rtc();
In main() wird sowohl gelesen als auch geschrieben (geschrieben aber nur 
bei deaktiviertem IRQ)

von Ralf (Gast)


Lesenswert?

Markus schrieb:
> Ist das jetzt eher Zufall oder ist das so beabsichtigt?
Wenn es nur diese beiden Varianten gäbe, dann eher Zufall. Dass eine 
Struktur in Registern gehalten wird, ist eher unwahrscheinlich. Also 
muss die irgendwo im Speicher stehen, wo sie auch bleibt. Zur 
einheitlichen und übersichtlichen Deklaration würde ich allerdings das 
'volatile' dazu machen.

von Markus (Gast)


Lesenswert?

also so wäre es richtig?
1
volatile time t;

von Peter II (Gast)


Lesenswert?

wenn du die Struktor volatile machst, dann wird der zugriff auf die 
Variabeln in der ISR langsamer. Wenn das ganze zeitkritisch ist könnten 
damit neue Probleme entstehen.

von Rolf Magnus (Gast)


Lesenswert?

Peter II schrieb:
> wenn du die Struktor volatile machst, dann wird der zugriff auf die
> Variabeln in der ISR langsamer.

Aber nur wenn man in der ISR mehrfach auf die selbe Variable zugreift. 
In diesem Fall bietet es sich an, sie anfangs in eine lokale Variable zu 
kopieren und/oder (je nach Fall) am Ende wieder zurück. Dann die 
eigentlichen Zugriffe auf die lokale Variable machen.

von Ralf (Gast)


Lesenswert?

Peter II schrieb:
> dann wird der zugriff auf die Variabeln in der ISR langsamer
In der ISR kann ich mir das nicht vorstellen. Höchstens in der main(), 
denn die Werte müssen ja immer aktuell sein, falls ein Interrupt 
zuschlägt.
Aber: Wenn die Struktur in der main() und in ISRs verwendet wird, dann 
muss ein ordentlicher Zugriff immer gewährleistet sein. Da darf sich der 
Code in diesem Fall nicht unterscheiden. Ob nun mit oder ohne 
'volatile'. Sonst würde es ja nicht funktionieren.

Markus schrieb:
> also so wäre es richtig?
> volatile time t;
Richtig? Falsch? ... Ich würde es so machen.

von Ralf (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Aber nur wenn man in der ISR mehrfach auf die selbe Variable zugreift.
Hm, hab' ich nicht beachtet.
Rechnet der Compiler damit, dass die ISR unterbrochen werden kann?

von (prx) A. K. (prx)


Lesenswert?

Auch innerhalb der ISR muss der Compiler die Struktur als volatile 
behandeln und jeden Zugriff so ausführen wie hingeschrieben. Der weiss 
nämlich nicht, ob die ISR selbst wiederum unterbrechbar ist oder ob die 
betreffenden Daten irgendwie von der Hardware verändert werden (DMA, 
I/O-Register, ...).

von Peter II (Gast)


Lesenswert?

Ralf schrieb:
> In der ISR kann ich mir das nicht vorstellen.

ist aber so.

jeder Zugriff auf die Variabel finden im Ram statt im Register statt. 
Das heist für jeden Zugriff wird die Variable in ein Register gelesen, 
dann das Register geändert und dann sofort das Register zurück in den 
Ram kopiert.

von Ralf (Gast)


Lesenswert?

Nach neuem Erkenntnisstand :-)
So:
Ralf schrieb:
> Markus schrieb:
>> also so wäre es richtig?
>> volatile time t;
> Richtig? Falsch? ... Ich würde es so machen.
Und das beachten:
Rolf Magnus schrieb:
> Aber nur wenn man in der ISR mehrfach auf die selbe Variable zugreift.
> In diesem Fall bietet es sich an, sie anfangs in eine lokale Variable zu
> kopieren und/oder (je nach Fall) am Ende wieder zurück. Dann die
> eigentlichen Zugriffe auf die lokale Variable machen.

von Rolf Magnus (Gast)


Lesenswert?

Ralf schrieb:
> Rolf Magnus schrieb:
>> Aber nur wenn man in der ISR mehrfach auf die selbe Variable zugreift.
> Hm, hab' ich nicht beachtet.
> Rechnet der Compiler damit, dass die ISR unterbrochen werden kann?

Der Compiler weiß nichts von ISRs. Für ihn sind das ganz normale 
Funktionen. Auch volatile steht erstmal in keinem direkten Zusammenhang 
mit ISRs. Also behandelt der Compiler die Variable in der ISR ganz genau 
so, wie er sie auch außerhalb behandeln würde.

von Markus (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Also behandelt der Compiler die Variable in der ISR ganz genau
> so, wie er sie auch außerhalb behandeln würde.

Hm, eine andere (normale) Variable hat er aber anscheinend wegoptimiert. 
Zumindest hat es erst funktioniert, nachdem ich sie volatile gemacht 
habe

von Rolf Magnus (Gast)


Lesenswert?

Markus schrieb:
> Rolf Magnus schrieb:
>> Also behandelt der Compiler die Variable in der ISR ganz genau
>> so, wie er sie auch außerhalb behandeln würde.
>
> Hm, eine andere (normale) Variable hat er aber anscheinend wegoptimiert.

Ja, also eben so, wie er es in einer normalen Funktion auch getan hätte.

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.