Forum: Mikrocontroller und Digitale Elektronik Kann ein Interrupt sich selbst unterbrechen?


von Mario H. (rocko)


Lesenswert?

Hi Leute,

Blöde Frage aber ernster Hintergrund:

Ich habe einen timer laufen der mir alle 4ms einen Interrupt auslöst.
Dieser Inkrementiert nur einige Variablen. Unter anderem eine, die 
angibt wie lange auf der RS485 nichts empfangen wurde.

Ist die RS485 schon eine bestimmte zeit frei, wird eine funktion 
aufgerufen die ein Paket zusammenstellt das über die RS485 geschickt 
wird.
Dies kann schon eine Weile dauern (also könnten auch schon mal die 4ms 
vorübergehen).

Jetzt meine Frage:

Wenn der Timerinterrupt nun noch läuft und es wird ein neuer Interrupt 
ausgelöst, was passiert?

* Der Timerinterrupt wird verloren? (damit würde die Uhr jedesmal 4ms 
hinten gehen)
* Der Timerinterrupt unterbricht sich selbst?
* Der Timerinterrupt wird abgearbeitet sobald der erste beendet ist?

Wenn es einer der letzten beiden Punkte ist, ist mir egal welcher 
(Programmcode stört sich gegenseitig nicht!).
Wenn mir der Timerinterrupt verloren geht müsste ich mir was einfallen 
lassen... (Interrupt löst SoftwareInterrupt aus???)

Ach ja, ich arbeite unter AVR-gcc auf einem atmega 2561.


vielen Dank schon mal für die Antworten


lg Rocko

von Dennis (Gast)


Lesenswert?

Der Timer setzt ein Timer-Interrupt-Flag, das wiederum löst den 
Interrupt aus wenn das I-Flag gesetzt ist und der jwlg. Interrupt 
aktiviert wurde.
Das Timer-Interrupt-Flag wird gelöscht, wenn der Interrupt ausgeführt 
wird.

Bei der Ausführung wird das I-Flag gelöscht, also kann der Interrupt 
sich nicht selbst unterbrechen. Es wird dann nur das 
Timer-Interrupt-Flag gesetzt und direkt nach dem return von der 
Interruptroutine mit dem neuen Interrupt weitergemacht.

Wenn das Timer-Interrupt-Flag schon gesetzt ist und der Timer wieder 
überläuft, geht ein Interrupt verloren.

von horst (Gast)


Lesenswert?

Muß die Funktion unbedingt im Interrupt aufgerufen werden?

>> Dieser Inkrementiert nur einige Variablen. Unter anderem eine, die
>> angibt wie lange auf der RS485 nichts empfangen wurde.
Das hört sich doch besser an. In deinem normalen Programm liest du die 
Variable aus, und bei Bedarf wird das Paket geschickt.

von (prx) A. K. (prx)


Lesenswert?

Mario Hirth schrieb:

> Dies kann schon eine Weile dauern (also könnten auch schon mal die 4ms
> vorübergehen).

Sollte nicht im Interrupt geschehen. Im Interrupt ein Flag setzen, im 
Hauptprogramm abfragen und dort den Job erledigen.

von P. S. (Gast)


Lesenswert?

Du kannst die Interrupts wieder freigeben, dann wird der naechste 
Interrupt den gerade laufenden unterbrechen. Nur schiess dir damit nicht 
in den Fuss...

von Mario H. (rocko)


Lesenswert?

Hi Dennis!
Wow das ging ja schnell, danke.

Also wenn ichs Richtig verstanden habe:

Wenn die Abarbeitung der Interruptroutine länger als 4ms braucht, wird 
ein neuerlicher interrupt einfach später ausgeführt.
Ein zweiter Interrupt (wenn der erste immer noch nicht fertig ist!) geht 
dann aber verloren.
In meinem Fall hab ich also 8ms Für die Abarbeitung des codes.


Klingt böse.
Da werd ich wohl noch einen Softwareinterrupt auslösen müssen in dem die 
langen routinen drin sind!

lg Rocko

von Stephan H. (stephan-)


Lesenswert?

Peter Stegemann schrieb:
> Du kannst die Interrupts wieder freigeben, dann wird der naechste
> Interrupt den gerade laufenden unterbrechen. Nur schiess dir damit nicht
> in den Fuss...

ist dann eben schon etwas anspruchsvoller.
Die Int müssen mitgezählt werden.
Und ein eigener Interrupthandler kann dann das Management übernehmen.
Ob das Sinnvoll ist....sei dahingestellt.
Kann schon sein das eine 3. oder 4. Ebene gebraucht wird.

von Mario H. (rocko)


Lesenswert?

A. K. schrieb:

> Sollte nicht im Interrupt geschehen. Im Interrupt ein Flag setzen, im
> Hauptprogramm abfragen und dort den Job erledigen.

Sorry geht leider nicht.
Ich realisiere auf der RS485er ein Kollisionsmanagement mit Prioritäten.
d.H. es ist (auf 4ms genau) zeitkritisch wann das Paket gesendet wird, 
sonst schnappt sich ein Knoten mit niedrigerer Priorität die 
Datenleitung.


Da im Hauptprogramm ein Display angesteuert wird mit schönen Grafiken 
und viel drumherum hab ich Zykluszeiten jenseits der 200ms...

Die Kommunkikation läuft schon, nur habe ich immer das Gefühl als würde 
die Uhr nachgehen ;-)

Die Ursache hab ich ja jetzt gefunden...


lg Rocko

von P. S. (Gast)


Lesenswert?

Stephan Henning schrieb:
> Peter Stegemann schrieb:
>> Du kannst die Interrupts wieder freigeben, dann wird der naechste
>> Interrupt den gerade laufenden unterbrechen. Nur schiess dir damit nicht
>> in den Fuss...
> ist dann eben schon etwas anspruchsvoller.

Nicht viel. In seinem Fall duerfte der Spass mit der einfachen Freigabe 
sogar schon erledigt sein - solange der Interrupt im Extremfall nicht 
laenger dauert, als der Timeout fuer die RS485 ist. Sonst wuerde der 
Langlaeufer wieder aktiviert, waehrend der letzte Langelaeufer noch 
laeuft -> Bumm.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Dies kann schon eine Weile dauern (also könnten auch schon mal die 4ms
> vorübergehen).
Ich würde hier ansetzen:
Warum dauert das Zusammensetzen eines Datenpakets so lange?

von Hemi (Gast)


Lesenswert?

>Sorry geht leider nicht.

Gerade beim Programmieren gilt: Geht nicht gibts nicht.
So lange Interruptroutinen sind schlechter Programmierstil. Basta.

von Johnny (Gast)


Lesenswert?

Schlechter Stil hin oder her, manchmal kommt man so einfach schneller 
ans Ziel. Man sollte gewisse Dinge nur so gut wie nötig implementieren 
und nicht so gut wie möglich.
Natürlich leidet die Erweiter- und Wartbarkeit, kommt halt immer auf das 
Produkt an, welchen Weg mal einschlagen sollte...

von P. S. (Gast)


Lesenswert?

Hemi schrieb:

> Gerade beim Programmieren gilt: Geht nicht gibts nicht.
> So lange Interruptroutinen sind schlechter Programmierstil. Basta.

Dogmata sind ein Zeichen fuer mangelndes Verstaendnis. Basta.

von Hannes Lux (Gast)


Lesenswert?

> Da im Hauptprogramm ein Display angesteuert wird mit schönen Grafiken
> und viel drumherum hab ich Zykluszeiten jenseits der 200ms...

Was hindert Dich daran, innerhalb der (auch nur aus Schleifen 
bestehenden) Grafikroutinen die Semaphores abzufragen und ggf. eine 
kleine Routine zwischendurch zu erledigen? Ich erledige in einem Projekt 
die bedingten Jobs (immer nur einen Schritt davon per SM) in der (vom 
Timer per Semaphore getakteten) Wartezeit auf den nächsten LCD-Zugriff.

Es gibt immer einen Weg, es sei denn, man verbaut ihn sich durch das 
Verwenden unflexibler (unverstandener) Standardbausteine.

...

von Mario H. (rocko)


Lesenswert?

Hallo Allerseits:

danke für die vielen Tips und Diskussionen, ich lerne immer wieder was 
dazu...

Die einfachste Lösung wäre wohl die mit der Interruptfreigabe. Ich 
schieße mir damit auch nicht ins Knie, weil zwischen dem senden 2er 
Datenpakete viel dazwischen liegt (Ich muss auf eine Antwort vom 
Empfänger des Pakets warten).

Die schönste Lösung wäre natürlich das Datenpaket zusammenzustellen, 
gleich in den UART Ringbuffer schieben und nacher erst auf die freie 
Leitung warten.
Im Wesentlichen müsste ich dann nur den "UART-TX-Buffer frei Interupt" 
zum richtigen Zeitpunkt starten, das geht viel schneller und der 
Interrupt ist gleich wieder frei.

Hätte ich gleich drauf kommen können!
Die beiden Lösungen muss ich mir noch durch den Kopf gehen lassen (never 
change a running System)... Mit der Interruptfreigabe kann ich am 
wenigsten beim umprogrammieren verbocken.

Danke fürs draufbringen.

lg Rocko

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.