mikrocontroller.net

Forum: Compiler & IDEs Rückkehr aus Interrupt


Autor: Jonas Diemer(ja, ich bin's) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

In meinem programm wird eine funktion von einem interrupt unterbrochen. 
unter gewissen umständen soll nun die programmausführung nach dem 
interrupt nicht in der funktion weitergehen, sondern "darüber", die 
funktion soll also quasi wie mit "return" beendet werden... geht das 
irgendwie, oder sollte ich da umdenken?

hier codebeispiele:


SIGNAL(INTERRUPT0){
  //code
  if (bedingung_erfuellt){
      //funktion f1 soll exitten
  }
}

void f1(void){
  //zeitintensiver code
  //hier tritt der interrupt auf
}

int main(void){
  //code
  f1();
  //hier soll unter bestimmten umständen weitergemacht werden
}

so, vielleicht weiß da wer was. :-)

Autor: Phagsae (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Obwolhl ich das noch nicht genacht habe

Einen höherwertigen Interrupt auslösen der dann auf die orginal Funktion 
zeigt

Wenn du natürlich schon den INT0 hast hilf da nur noch Reset :-)))

Phagsae

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das geht, wenn du den Stack soweit abbaust dass die 
Rücksprungadresse zu main (also da wo fl() aufgerufen wurde) wieder ganz 
oben liegt. Dann ein ret, und du bist wieder in main. Da ich das 
interessant finde, hab ich das gerade mal ausprobiert (siehe Anhang). 
Kann sein, dass in deiner (Interrupt-)Funktion mehr auf dem Stack liegt, 
so dass du öfter POPen ;-) musst, aber dass kannst du ja durchs Lesen 
des erzeugten Assemblercodes oder Simulation im AVR-Studio herausfinden.

MfG
Andreas

Autor: Jonas Diemer(ja, ich bin's) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit dem poppen hab ich mir auch schon gedacht, aber das ist ja schon 
ein derber Hack!!!  Wenn da mal ne variable hinzukommt, dann is sense...

was mit grad einfällt (kanns leider nicht testen, da ich nicht an meinem 
rechner sitze):

short int pointer;

while (pointer != &main() ){ //solange poppen, bis wir zeiger auf main() 
haben
    pointer = pop();
}
push (pointer); //zeiger auf main wieder pushen

so (oder so ähnlich) könnte das doch klappen, oder?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Denk daran, dass der Pointer 16 Bit lang ist, also 2 mal poppen! Dann 
sollte es klappen, probier's halt mal aus.

MfG
Andreas

Autor: Jonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
deshalb ja "short int"...

kann's leider erst ende der Woche testen...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst aber nicht sicher sein dass die Daten immer in 
2-Byte-Abständen auf dem Stack liegen, also darf pop() nur ein Byte 
zurückliefern -> du musst 2 mal POPen.

Andreas

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da haste wahr...

überhaupt ist diese lösung nicht wirklich elegant. gibts da nichts 
anderes?

Jonas

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das mit dem POPen ist wirklich nicht so das Wahre. Die sauberste Lösung 
wäre, in fl() eine Variable abzufragen über die der Interrupt mitteilt 
dass die Funktion beendet werden soll. Aber Achtung, die Variable muss 
als volatile deklariert sein!

MfG
Andreas

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, ich denk mal, dass ich's so machen werde. schade, dasses für sowas 
nix anständiges gibt :-)

Autor: Sämi Lehner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Es gibt eine ANSI-C Funktion setjmp() mit der kannst du dein Problem 
lösen.

gruss sam

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
richtig, einen longjump. wird die auch vom avr-gcc unterstützt?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jonas

Tja, es gibt halt Leute, die Poppen für unanständig halten.

SCNR

Peter ;-)

Autor: Sämi Lehner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist die einzige möglichkeit die mit Sicherheit funktioniert, denn die 
oben genannten Metoden sind zu unsicher. Man kann nicht ausschliessen 
dass eine lokale Variable den gleichen Wert hat, wie die Adresse der 
Funktion auf dem Stack.

Autor: Jonas Diemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, da hast du wahr. aber ich glaub, die wird nicht unterstützt...

ich hab jetzt mein programm umgeschrieben, sodass der interrupt nur kurz 
eingreift und danach vernünftig weitergemacht werden kann. is viel 
besser so, nich son wirrwarr. vorher hatte die interrupt-routine nämlich 
zeitweise komplett "die kontrolle" ansich gerissen, das war sowieso 
nicht das wahre. nun hauts aber rein :-)

danke trotzdem für eure hilfe.

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.