INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Interrupt und Sicherung der Prozessorregister
30.08.2016, 15:11
Beitrag #1
Interrupt und Sicherung der Prozessorregister
Bei dem Gebrauch von Interrupts ergibt sich grundsätzlich das Problem, dass in der Interrupt Routine Prozessorregister und Flags verändert werden. Am Anfang der Interruptroutine müssen also Flags und benutzte Prozessorregister gesichert und am Ende wieder hergestellt werden. Ohne Sicherung dieser, entzieht man der unterbrochenen Funktion die Fähigkeit unbeeinflusst weiter arbeiten zu können. Durch Verwendung der Programmiersprache C verliert man ja die Adress- und Registerhoheit, d.h. diese sind compilerabhängig und damit auch abhängig von dessen Version. Lokale Variablen sind diesbezüglich auch nicht hilfreich, denn eine C-Anweisung kann mehrere Assembleranweisungen notwendig machen. Und der Prozesser selbst kennt kein C sondern nur Assembler. Eine Interrupt-Unterbrechung findet immer auf der Assemblerebene statt.
Die Flags zu sichern ist ja kein Problem, wie schaut es aus mit den restlichen 32 Registern (R0 .. R31), welche davon müssen ebenfalls gesichert werden? Die Registerbank ist ja nicht umschaltbar.
Von Nachteil ist auch, dass nach dem Compilieren alle Assemblerdateien gelöscht werden, man hat also keine Chance zu kontrollieren welche Register verwendet werden. Ich habe im Forum diesbezüglich nichts gefunden.
Viele Grüße Mkc

Gruß MKc
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.08.2016, 15:33
Beitrag #2
RE: Interrupt und Sicherung der Prozessorregister
Hallo,
aus der Arduino-IDE heraus bleibt nach dem compilieren nach meiner Kenntnis nur noch das HEX-File übrig. Das kann man sich anschauen und rückübersetzten. Big Grin
Ist aber sicher nicht Sinn der Sache.

Ansonsten brauchst du dich um Registerrettung ect. und rücklesen nicht zu kümmern sofern du die Arduino-IDE benutzt und in C programmierst. Der Compiler schreibt alles was an Programmcode bei Aufruf einer Interruptroutine nötig ist für dich.
Wenn du allerdings in der Interruptroutine auf Assemblerebene hinab steigst und dort den Stack manipulierst ist alles Böse möglich.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.08.2016, 17:45
Beitrag #3
RE: Interrupt und Sicherung der Prozessorregister
(30.08.2016 15:33)ardu_arne schrieb:  Hallo,
aus der Arduino-IDE heraus bleibt nach dem compilieren nach meiner Kenntnis nur noch das HEX-File übrig. Das kann man sich anschauen und rückübersetzten. Big Grin
Ist aber sicher nicht Sinn der Sache.

Ansonsten brauchst du dich um Registerrettung ect. und rücklesen nicht zu kümmern sofern du die Arduino-IDE benutzt und in C programmierst. Der Compiler schreibt alles was an Programmcode bei Aufruf einer Interruptroutine nötig ist für dich.
Wenn du allerdings in der Interruptroutine auf Assemblerebene hinab steigst und dort den Stack manipulierst ist alles Böse möglich.

Gruß
Arne
Was macht die IDE dabei genau? Nochmals zum Problem (alles in C programmiert)mit Beispiel:
in C: a = b; ---> compilliert z.B. ldi r16,0x20 //r16 = b, a aber noch nicht gesetzt!!!
out 0x22,r16 //jetzt erst wäre a = b
Annahme: nach dem ldi-befehl schlägt das Interrupt zu, der out-Befehl kann also nicht mehr ausgeführt werden. Annahme: In der Interruptroutine wird das r16 ebenfalls benutzt z.B.:
in C: x = y; ---> compilliert z.B. ldi r16,0x26 //r16 ist jetzt im Interrupt überschrieben worden.
....
nach Beendigung der Interruptroutine wird die unterbrochene Funktion weiter ausgeführt (der zweite Teil der C-Anweisung):
zweiter Teil : out 0x22,r16 //in r16 steht nicht mehr a, sondern irgendetwas anderes.
MKc

Gruß MKc
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.08.2016, 20:03 (Dieser Beitrag wurde zuletzt bearbeitet: 30.08.2016 20:23 von ardu_arne.)
Beitrag #4
RE: Interrupt und Sicherung der Prozessorregister
Hallo,
was genau die IDE bzw. der Compiler aus deinem Code macht kann ich leider auch nicht beantworten. So tief stecke ich da auch nicht drin. Undecided

aber
a = b; ist nur die halbe Miete.
Wie mit den Variablen umgegangen wird hängt auch davon ab wie sie deklariert wurden. Deinen C-Code kennen wir aber nicht.
Du kannst z.B. mit dem Keyword volatile Einfluss darauf nehmen ob eine Variable aus einem Register oder dem RAM geladen wird.

Vielleicht löst das schon das beschriebe Problem sofern es wirklich real besteht und das Thema nicht nur theoretischer Natur ist.
Andererseits bin ich aber auch davon überzeugt dass die IDE und der Compiler bei solchen Dingen fehlerfrei arbeitet. Der Benutzer muss aber die "Risiken" eines Interrupts kennen und der IDE sagen was der Compiler aus seinem Code machen soll. Es gibt da Möglichkeiten der Einflussnahme.

Auf dieser Seite ist unter der Überschrift "Interrupts" mehr dazu erklärt.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
31.08.2016, 10:06
Beitrag #5
RE: Interrupt und Sicherung der Prozessorregister
Hey!

Wenn du in C programmierst, wird das zuerst in ASM übersetzt. Schon da werden kleine Veränderungen vorgenommen und aufgepasst, dass Probleme, wie du eben beschrieben, nicht vorkommen.
So wird z.B. mit diesem C-Code
Code:
ISR(INT0_vect)
{
    PORTB ^= 0x01;
}
in ASM (ohne Optimierung) das hier erzeugt:
Code:
1b4:    1f 92           push    r1
1b6:    0f 92           push    r0
1b8:    00 90 5f 00     lds    r0, 0x005F
1bc:    0f 92           push    r0
1be:    11 24           eor    r1, r1
1c0:    2f 93           push    r18
1c2:    3f 93           push    r19
1c4:    8f 93           push    r24
1c6:    9f 93           push    r25
1c8:    ef 93           push    r30
1ca:    ff 93           push    r31
1cc:    cf 93           push    r28
1ce:    df 93           push    r29
1d0:    cd b7           in    r28, 0x3d    ; 61
1d2:    de b7           in    r29, 0x3e    ; 62
1d4:    85 e2           ldi    r24, 0x25    ; 37
1d6:    90 e0           ldi    r25, 0x00    ; 0
1d8:    25 e2           ldi    r18, 0x25    ; 37
1da:    30 e0           ldi    r19, 0x00    ; 0
1dc:    f9 01           movw    r30, r18
1de:    30 81           ld    r19, Z
1e0:    21 e0           ldi    r18, 0x01    ; 1
1e2:    23 27           eor    r18, r19
1e4:    fc 01           movw    r30, r24
1e6:    20 83           st    Z, r18
1e8:    df 91           pop    r29
1ea:    cf 91           pop    r28
1ec:    ff 91           pop    r31
1ee:    ef 91           pop    r30
1f0:    9f 91           pop    r25
1f2:    8f 91           pop    r24
1f4:    3f 91           pop    r19
1f6:    2f 91           pop    r18
1f8:    0f 90           pop    r0
1fa:    00 92 5f 00     sts    0x005F, r0
1fe:    0f 90           pop    r0
200:    1f 90           pop    r1
202:    18 95           reti

Ohne den Code groß durchzugehen: am Anfang sieht man viele "push" und am Ende "pop"-Befehle und damit werden die Register zwischengespeichert. Dh "push" legt die Daten vom Register im Stack ab und dekrementiert den Stackpointer. Pop Liest aus dem Stack, legt die Daten im Register ab und inkrementiert (LIFO Buffer - Last In First Out).
Außerdem wird in der ISR auch das SREG-Register zwischengespeichert (lds r0, 0x005F).

Mit Optimierung wird der Code natürlich einiges kürzer, aber ohne Opt. sieht man schön alle Push/Pop-Befehle.

mfg Scheams
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
31.08.2016, 11:17
Beitrag #6
RE: Interrupt und Sicherung der Prozessorregister
Vielen Dank für ihren Beitrag, das war genau die Information, die mir gefehlt hat und auch im Netz nicht zu finden war.
Viele Grüße Manfred
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  while Schleife nach sleep mode interrupt tklaus 13 265 23.11.2016 17:40
Letzter Beitrag: Tommy56
  NRF24L01 Interrupt MeisterQ 22 519 02.11.2016 15:50
Letzter Beitrag: MeisterQ
  Interrupt matthias3579 5 225 15.10.2016 13:23
Letzter Beitrag: hotsystems
  Interrupt bei Serieller Übertragung Binatone 8 367 21.06.2016 14:09
Letzter Beitrag: Scheams
  Interrupt wenn softwareSerial Daten BennIY 3 447 01.05.2016 18:39
Letzter Beitrag: tiny85fan
  Timer Interrupt Anfängerprobleme Fox 4 623 05.03.2016 02:28
Letzter Beitrag: Fox
  Elektronische Sicherung Chef_2 7 565 16.02.2016 16:28
Letzter Beitrag: Chef_2
  Problem mit Pin Change Interrupt in Library Retian 0 321 10.02.2016 23:37
Letzter Beitrag: Retian
  Aus While-Schleife durch Interrupt aussteigen Zill3 10 1.194 08.02.2016 16:28
Letzter Beitrag: ardu_arne
  Verwendung ? : Arduino MEGA 2560 - Interrupt 3 und 2 (Pin 20 /21) zauche 7 1.467 18.06.2015 22:01
Letzter Beitrag: zauche

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste