Forum: Compiler & IDEs Rückkehr aus Interrupt


von Jonas Diemer(ja, ich bin's) (Gast)


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. :-)

von Phagsae (Gast)


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

von Andreas S. (andreas) (Admin) Benutzerseite


Angehängte Dateien:

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

von Jonas Diemer(ja, ich bin's) (Gast)


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?

von Andreas S. (andreas) (Admin) Benutzerseite


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

von Jonas (Gast)


Lesenswert?

deshalb ja "short int"...

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

von Andreas S. (andreas) (Admin) Benutzerseite


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

von Jonas Diemer (Gast)


Lesenswert?

da haste wahr...

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

Jonas

von Andreas S. (andreas) (Admin) Benutzerseite


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

von Jonas Diemer (Gast)


Lesenswert?

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

von Sämi Lehner (Gast)


Lesenswert?

Hallo

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

gruss sam

von Jonas Diemer (Gast)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

@Jonas

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

SCNR

Peter ;-)

von Sämi Lehner (Gast)


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.

von Jonas Diemer (Gast)


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.

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.