Forum: Compiler & IDEs Verhalten MCU während Durchlauf einer If-Schleife bei eintreten eines Interrupt


von HeyHey (Gast)


Lesenswert?

Hallo zusammen,

ich programmiere gerade auf meinem ATmega1284p eine kleine Uhr.
Mir stellt sich jetzt jedoch die Frage, was eigentlich passiert, wenn 
der Mikrocontroller gerade eine If-Schleife bearbeitet und dabei ein 
Interrupt-Event eintritt. Eigentlich sollte doch der MCU alles quasi 
zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört 
hat.

ergibt es aus sicherheitsgründen sinn während den sehr wichtigen 
If-Schleifen, die Interrupt abzuschalten und danach wieder einzuschalten 
oder funktioniert das immer korrekt?

Beispiel:
1
if(day == 31 && ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && hour == 23 && minute == 59 && second == 59)
2
    {
3
      month++;
4
      second = 0;
5
      minute = 0;
6
      hour = 0;
7
      day = 1;
8
    }

Angenommen während er gerade die Variable minute auf 0 setzt, tritt ein 
Interruptevent ein. Läuft der Programmpointer danach wirklich bei hour = 
0 weiter?

Gruß

HeyHey

von Penner (Gast)


Lesenswert?

HeyHey schrieb:
> ergibt es aus sicherheitsgründen sinn während den sehr wichtigen
> If-Schleifen, die Interrupt abzuschalten und danach wieder einzuschalten

Ja.

von Floh (Gast)


Lesenswert?


von Peter II (Gast)


Lesenswert?

http://www.if-schleife.de/

> Angenommen während er gerade die Variable minute auf 0 setzt, tritt ein
> Interruptevent ein. Läuft der Programmpointer danach wirklich bei hour =
> 0 weiter?

er macht genau da weiter wo er aufgehört hat.

von Dussel (Gast)


Lesenswert?

HeyHey schrieb:
> eine If-Schleife bearbeitet
Zeig mir mal bitte, wo in dem Beispiel eine Schleife sein soll.

HeyHey schrieb:
> Eigentlich sollte doch der MCU alles quasi
> zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört
> hat.
Der Controller macht da (außer PC) gar nichts von selber. Der Compiler 
kümmert sich zum Teil drum, wichtige Register zu sichern. Das ist aber 
meines Wissens nur das Status Register.

von Norbert (Gast)


Lesenswert?

HeyHey schrieb:
> Hallo zusammen,
>
> wenn
> der Mikrocontroller gerade eine If-Schleife bearbeitet

Wirklich gefährlich wird es erst beim sogenannten
1
month++
Vergleich, bzw beim
1
second = 0;
Sprung!

Im schlimmsten Fall kann bei einer Polaritätsumkehr des Taktsignals 
ein Interrupt sich selbst unterbrechen.

von Intr nicht verpennen (Gast)


Lesenswert?

Penner schrieb:
> Ja.

Hier ist das aber nicht so schlau. Bei der zeitlichen Verschiebung läuft 
mir die echte Zeit davon. Der Timer Interrupt für die Zeitreferenz muss 
die höchste Priorität haben und immer laufen.

von AVR (Gast)


Lesenswert?

Nein, das sollte der Compiler richtig machen, d.h. er sollte in der ISR 
alle Register sichern, die er verwendet.
Ausnahmen sind Zugriffe auf gemeinsame Variablen. Z.B. ISR ändert Zeit, 
während Hauptprogramm diese gerade verwendet.
Bei AVR-gcc gibt es dafür util/atomic.h. Damit kann man atomare, d.h. 
nicht unterbrechbare, Abschnitte definieren.
BTW, ist der 1284 groß genug für Deine Uhr?  ;-)

von Falk B. (falk)


Lesenswert?

@ HeyHey (Gast)

>der Mikrocontroller gerade eine If-Schleife bearbeitet

Gibt es nicht.

> und dabei ein
>Interrupt-Event eintritt. Eigentlich sollte doch der MCU alles quasi
>zwischenspeichern damit er wieder da weitermahcen kann wo er aufgehört
>hat.

Macht er auch.

>ergibt es aus sicherheitsgründen sinn während den sehr wichtigen
>If-Schleifen, die Interrupt abzuschalten

Ja, nennt sich atomarer Zugriff und ist im Artikel Interrupt 
beschrieben.

>und danach wieder einzuschalten
>oder funktioniert das immer korrekt?

Nein. Nur, wenn die Variablen NICHT in Hauptprogramm und im Interrupt 
verwendet werden.

von PittyJ (Gast)


Lesenswert?

Noch mal zur Uhr selber:
Eigentlich keiner speichert seine Uhrzeit in 6 Variablen (year, month, 
day, hour ...) ab und rechnet damit herum.
Sinnvoller ist es, die Zeit in nur einer Variablen abzubilden. Bei Unix 
z.B. Sekunden seit 1.1.1970. Bei MS gibt es etwas ähnliches ab 1900.
Nur zur Ausgabe werden dann Stunden, Minuten etc berechnet.
Das reduziert den Aufwand, dass man in der Interrupt-Routine dann diese 
vielen If-Vergleiche für unterschiedliche Monate und Schaltjahre hat.

von Karl H. (kbuchegg)


Lesenswert?

PittyJ schrieb:
> Noch mal zur Uhr selber:
> Eigentlich keiner speichert seine Uhrzeit in 6 Variablen (year, month,
> day, hour ...) ab und rechnet damit herum.

Das würde ich so nicht unterschreiben.
Kommt immer drauf an, was man mit der Uhr vor hat.

> Das reduziert den Aufwand, dass man in der Interrupt-Routine dann diese
> vielen If-Vergleiche für unterschiedliche Monate und Schaltjahre hat.

DIe sind für einen AVR harmlos, weil alles auf Bytebene geht.
long-Rechnerei ist allerdings für einen AVR auf nicht gerade 
Zuckerschlecken mit seinen 8 Bit Registern.

Wobei allerdings das hier
1
if(day == 31 && ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) && hour == 23 && minute == 59 && second == 59)

schon unnötig komplex ist (denn da wird ja noch wo eine Regel für 30 
Tage sein, eine Regel für den Februar). Da ist man mit einem Array 
besser bedient, in dem die Tage pro Monat stehen und die Weiterschaltung 
anhand der Uhrzeit ergibt sich durch die Schachtelung sowieso von 
alleine. EInzig Schaltjahre erfordern ein bischen Rechnerei.

Aussserdem: genau dieser Teil der Uhrenweiterschaltung STEHT 
vernünftigerweise in der Interrupt Routine, die die Uhr bedient. D.h. 
die Fragestellung stellt sich so gar nicht.

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.