Forum: Compiler & IDEs Interrupts beenden


von ISR (Gast)


Lesenswert?

Kann man Interrupts auch in ihnen selber mit cli() beenden, so dass bei 
schnellen Interruppts diese definitiv nicht ein x-tes mal aufgerufen 
werden. Wenn ich das in der main machen würde, könnte es ja sonst sein, 
dass der Interruppt noch einmal ausgeführt wird.
Mit Flag setzen und jedes mal if-Abfrage machen, habe ich evtl zu viel 
Zeitverlust.

von AVRFan (Gast)


Lesenswert?

>Kann man Interrupts auch in ihnen selber mit cli() beenden,

Ein 'cli' beendet überhaupt keinen Interrupt, sondern eine sogenannte 
Critical Section, d. h. einen kurzen, interruptgesperrten Codeabschnitt. 
Interrupts finden ihr Ende üblicherweise mit 'reti' oder 'ret'.

>so dass bei schnellen Interruppts diese definitiv nicht ein x-tes mal
>aufgerufen werden.

Das widerspricht dem Sinn und Zweck von Interrupts.  Immer wenn ein 
Ereignis auftritt, soll auch der Interrupt aufgerufen werden, in dessen 
Handler das Ereignis "verarbeitet" werden kann.  Dadurch kann, wenn man 
es richtig macht,  kein Ereignis verlorengehen.

>Wenn ich das in der main machen würde, könnte es ja sonst sein,
>dass der Interruppt noch einmal ausgeführt wird.

?

>Mit Flag setzen und jedes mal if-Abfrage machen, habe ich evtl zu viel
>Zeitverlust.

?

von Εrnst B. (ernst)


Lesenswert?

Glasskugel:

Du willst nicht, dass ein Interrupt ein weiteres mal ausgeführt wird, 
während noch die erste ISR läuft?

Das macht der AVR schon von ganz alleine. Beim Sprung in den Interrupt 
Handler werden weitere Interrupts abgeschaltet, beim "reti" werden sie 
wieder aktiviert...

von Peter D. (peda)


Lesenswert?

ISR wrote:
> Kann man Interrupts auch in ihnen selber mit cli() beenden

Ein CLI innerhalb eines Interrupthandlers wirkt wie ein NOP.

Ein CLI würde außerdem sämtliche anderen Interrupts abschalten.

Du mußt das Enablebit genau des einen Interrupts auf 0 setzen, damit er 
nicht nochmal ausgeführt wird.

Und vor der erneuten Freigabe das Interruptflag löschen (auf 1 setzen).


Peter

von Oliver (Gast)


Lesenswert?

>beim "reti" werden sie wieder aktiviert...

und wenn in der Zwischenzeit der Interrupt wieder ausgelöst wurde, wird 
die ISR sofort wieder aufgerufen. Verhindern lässt sich das nur, wenn 
der jeweilige Interrupt gesperrt wird.

Ob das das Problem löst, wer weiss?

Oliver

von ISR (Gast)


Lesenswert?

Ich will nicht, dass er wieder  ausgeführt wird, wenn er 
zurückgesprungen ist.  Es kann ja sein, dass so schnell wieder ein 
Interrupt ansteht, dass nach dem Rücksprung sofort wieder 
hineingesprungen wird. Je nach dem and welcher Stelle er in den 
Interrupt hinein bzw zurück gesprungen ist, kann da ja ein wenig Zeit 
bis zum cli() vergehen.
Genau diese Zeit zw. Rücksprung und dem cli() möchte ich vermeiden.

Bsp.: bei Frequenzmessung mit hohen Frequenzen wird aus dem capture 
Interrupt zurückgesprungen (wieder in die main). Bevor ich die 
Interruppt ausstellen kann, wird wieder in diesen gesprungen und der 
Zeitpunkt der Ersten Flanke überschrieben, da ich cli() nicht schnell 
genug ausführen konnte.

Deswegen habe ich gefragt, ob ich die Interrupts schon in der ISR 
ausstellen kann, damit nicht wieder hinein gesprungen wird. Es wird ja 
an die Stelle wieder gesprungen, an welcher in den Interrupt gesprungen 
wurde. UND DAS KANN JA ÜBERALL SEIN.

>>Beim Sprung in den Interrupt Handler werden weitere Interrupts abgeschaltet, 
>>beim "reti" werden sie wieder aktiviert...
weiss ich, das "wieder aktivieren" ist das Problem

von ISR (Gast)


Lesenswert?

@ Peter Dannegger:
ich glaub das mit dem Enablebit ist genau das was ich gesucht habe

gibts da irgendwo eine Zusammenstellung der einzelnen Enablebits für die 
ISR (außer jetzt das ganze Datenblatt zu durchforsten)

von Peter D. (peda)


Lesenswert?

ISR wrote:

> gibts da irgendwo eine Zusammenstellung der einzelnen Enablebits für die
> ISR (außer jetzt das ganze Datenblatt zu durchforsten)

Na Du wirst doch wohl wissen, mit welchem Bit Du den Interrupt 
freigegeben hast.
Und mit genau dem gleichen sperrst Du ihn eben.


Peter

von Falk B. (falk)


Lesenswert?


von Εrnst B. (ernst)


Lesenswert?

1) IIRC wird nach dem RETI immer eine Instruktion ausgeführt bevor 
wieder in eine ISR gesprungen wird. Dein Hauptprogramm kann also nicht 
verhungern.

2) Normalerweise nimmt man Interrupts für Sachen, die zu wichtig sind um 
sie einfach mal auszulassen, Beispiel Frequenzzähler: Der würde falsche 
Werte anzeigen.

3) Wenn du genaue Kontrolle darüber brauchst, wann deine ISR ausgeführt 
wird/werden kann, schalt den Interrupt generell ab, mach ne normale 
Funktion draus, und überprüf einfach an festen Stellen in deiner 
Main-Schleife das entsprechende Bit, ruf die Methode auf wenn gesetzt.

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.