Forum: Compiler & IDEs Interrupt Epilog aufrufen


von Oliver (Gast)


Lesenswert?

Hallo.
Ich habe folgende Situation: Innerhalb einer Interrupt-Routine werden 
verschiedene Dinge getestet. Liegt ein Fehler vor möchte ich eine 
Funtkion error_function () aufrufen und dann die Interrupt-Routine 
vorzeitig verlassen.

ISR (UART_RX_vect) {

  if (Bedingung1) {
    error_function ();
    HIER INTERRUPT VERLASSEN
  }

  // ...

  if (Bedingung2) {
    error_function ();
    HIER INTERRUPT VERLASSEN
  }

  // ...
}

Bei einer normalen Funktion könnte man einfach return verwenden. Für 
Interrupts gäbe es ja reti(), doch dann würde der von AVR GCC generierte 
Epilog (SREG und Register wiederherstellen) nicht aufgerufen werden...
Gibt es eine Möglichkeit aus der Routine heraus direkt den Epilog 
aufzurufen? Oder habt ihr andere Lösungsvorschläge?

Vielen Dank für eure Hilfe!

Oliver

von (prx) A. K. (prx)


Lesenswert?

Oliver schrieb:

> Bei einer normalen Funktion könnte man einfach return verwenden.

Hier auch.

von Napfkuchen (Gast)


Lesenswert?

An sich ist es überhaupt keine gute Idee im Interrupt Funktionen 
aufzurufen. Setze in der ISR Variablen und prüfe sie in main. Dann 
stellt sich das Problem auch nicht.

Aber wenn es denn unbedingt sein muss, dann verknüpfe die Bedingungen 
mit "oder".

1
ISR (UART_RX_vect) {
2
3
  if ((Bedingung1) ||  (Bedingung2)) {
4
    error_function ();
5
    // HIER INTERRUPT VERLASSEN nicht mehr notwendig
6
  }
7
  else {
8
    // ...
9
  }
10
}

von Napfkuchen (Gast)


Lesenswert?

A. K. schrieb:
>> Bei einer normalen Funktion könnte man einfach return verwenden.
>
> Hier auch.

Auch wieder richtig. Wie kommst Du darauf, kein return benutzen zu 
können?

von (prx) A. K. (prx)


Lesenswert?

Napfkuchen schrieb:

> An sich ist es überhaupt keine gute Idee im Interrupt Funktionen
> aufzurufen.

Sehe ich anders. Sicher, wer seinen halben Programmcode in Interrupts 
verballert, der hat garantiert etwas falsch gemacht. Ansonsten ist es 
Abwägung, inwieweit man Dinge direkt in der ISR erledigt. Manches geht 
nur dort, und bloss des Dogmas wegen verkrampft zu programmieren ist 
auch nicht sinnvoll.

> dann verknüpfe die Bedingungen mit "oder".

In diesem Beispiel sicher, aber das könnte der Vereinfachung geschuldet 
sein.

von Napfkuchen (Gast)


Lesenswert?

A. K. schrieb:
> Sehe ich anders.

Aha. Und?
Es ist sicher auch nicht sinnvoll, an solch einer Stelle eine Diskussion 
darüber anzufangen. Wenn ich sage, das man nicht ohne Fallschirm aus 
einem Flugzeug springen sollte, dann ist das die Antwort auf die Frage 
"wie man ohne Fallschirm aus dem Flugzeug springt". Das man, wenn das 
Flugzeug auf dem Boden steht, dennoch ohne Gefahr aus dem Flugzeug 
springen kann, weiss der ausgebildete Fallschirmspringer aber keiner der 
so fragt. (Na gut, das Beispiel ist nicht so schön, aber dem Sinne nach 
gilt es für Programmierer).

Genau dieses Argument hier:
A. K. schrieb:
> In diesem Beispiel sicher, aber das könnte der Vereinfachung geschuldet
> sein.

spricht nach meiner Ansicht, dafür, das der Fragesteller nicht in der 
Lage war sein Problem (ob es nun eines war, spielt dabei keine Rolle) 
selbst mit trivialen Mitteln zu lösen, also ein Anfänger ist.
Meinen Hinweis finde ich darüber hinaus in solchen Fällen und in denen, 
bei denen der Code der aufgerufenen Funktion unbekannt ist, sinnvoll.

Die Formulierung "überhaupt keine gute Idee" hat zugegebenermaßen den 
Odem eines Dogmas. Mit dem Nachsatz, "Aber wenn es denn unbedingt sein 
muss ..." meinte ich meine Aussage hinreichend relativiert zu haben, so 
das sogar ein Anfänger erkennen konnte, das es sich eben nicht um eine 
strikte Regel handelt.

von (prx) A. K. (prx)


Lesenswert?

Nur kann ich an seinem Code oben nichts frevelhaftes der Marke "ohne 
Fallschirm aus dem Flugzeug springen" erkennen.

von Napfkuchen (Gast)


Lesenswert?

A. K. schrieb:
> Nur kann ich an seinem Code oben nichts frevelhaftes der Marke "ohne
> Fallschirm aus dem Flugzeug springen" erkennen.

Um in dem Beispiel zu bleiben: Du siehst seinen Rücken und kannst keinen 
"Buckel" erkennen. Hat er den Fallschirm nun vor der Brust unter dem 
Hosenboden oder garkeinen?

von Oliver (Gast)


Lesenswert?

Vielen Dank für die Antworten. Das Funktionsaufrufe in Interrupts 
problematisch sind weiss ich schon, und ich habe mir auch bereits 
überlegt das ganze mit Flags zu machen, die dann in main überprüft 
werden.
Problematisch ist jedoch, dass sobald der UART einen Interrupt auslöst 
(sprich ein byte empfängt), relativ viel code möglichst schnell 
ausgeführt werden muss. In main würde es unter Umständen zu lange 
dauern, bis die Hauptschleife durch ist und das nächste Mal die Flags 
geprüft werden.

Einfach return einzusetzten muss ich mal ausprobieren. Ich dachte, das 
geht nicht, da es sich bei ISR (UART_RX_vect) nicht um eine C-Funktion 
im eigentlichen Sinn handelt. ISR ist ja eigentlich ein Makro...

von ... (Gast)


Lesenswert?

Oliver schrieb:
> Einfach return einzusetzten muss ich mal ausprobieren. Ich dachte, das
> geht nicht, da es sich bei ISR (UART_RX_vect) nicht um eine C-Funktion
> im eigentlichen Sinn handelt. ISR ist ja eigentlich ein Makro...
>

Wenn Du Dir das Makro anschaust, wirst Du feststellen, daß da nur ein 
paar zusätzliche Funktionsattribute gesetzt werden und das ganze 
ansonsten eine (fast) normale C-Funktion ist.

Im Endeffekt sieht das dann etwa so aus:
1
void __vector_9(void) __attribute__ ((signal, used, externally_visible));
2
void __vector_9(void)
3
{
4
  // ...
5
}
Wobei die Zahl am Ende des Namens ('9') die Interruptnummer ist.

von Karl H. (kbuchegg)


Lesenswert?

Oliver schrieb:

> Einfach return einzusetzten muss ich mal ausprobieren. Ich dachte, das
> geht nicht, da es sich bei ISR (UART_RX_vect) nicht um eine C-Funktion
> im eigentlichen Sinn handelt. ISR ist ja eigentlich ein Makro...

Das ist aber nicht dein Problem.
Dafür gibt es einen Compiler, der die Unterschiede kennt.

von Peter D. (peda)


Lesenswert?

Oliver schrieb:
> Für
> Interrupts gäbe es ja reti()

Ja das ist die beste Methode, Programme abstürzen zu lassen.
Stürzt noch besser ab, als die sleep_mode() Fallgrube.

Das war auch wirklich ne saublöde Idee von den AVR-GCC-Entwicklern, das 
reti() Macro dem unbedarften Nutzer als direkte Fallgrube zugänglich zu 
machen.

Nimm "return;" und gut is.


Peter

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.