www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt Epilog aufrufen


Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:

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

Hier auch.

Autor: Napfkuchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

ISR (UART_RX_vect) {

  if ((Bedingung1) ||  (Bedingung2)) {
    error_function ();
    // HIER INTERRUPT VERLASSEN nicht mehr notwendig
  }
  else {
    // ...
  }
}


Autor: Napfkuchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Napfkuchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

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

Autor: Napfkuchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void __vector_9(void) __attribute__ ((signal, used, externally_visible));
void __vector_9(void)
{
  // ...
}
Wobei die Zahl am Ende des Namens ('9') die Interruptnummer ist.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.