Forum: Mikrocontroller und Digitale Elektronik Atmega Interupts. Provoziere ich so einen Absturz?


von 006 (Gast)


Lesenswert?

Hi,
mal eine Fragen zu AVR ATmega Mikrocontrollern:

Ein Timer soll alle 10us einen Interrupt auslösen.
Die Interuptroutine benötigt aber stets 20us bis sie abgearbeitet ist 
und geschlossen wird.

Was passiert dann genau?

Viele Grüße,
006

von (prx) A. K. (prx)


Lesenswert?

Kein Absturz.

: Bearbeitet durch User
von Marcel (Gast)


Lesenswert?

Der Interrupt wird abgearbeitet und der Interrupt, welcher während des 
Abarbeiten ausgelöst wird, wird ignoriert.

Es gibt keinen Absturz, aber es passiert nicht das, was du vom Programm 
erwartetst.

von (prx) A. K. (prx)


Lesenswert?

Marcel schrieb:
> Der Interrupt wird abgearbeitet und der Interrupt, welcher während des
> Abarbeiten ausgelöst wird, wird ignoriert.

Nö, der nicht.

: Bearbeitet durch User
von Max H. (hartl192)


Lesenswert?

006 schrieb:
> Ein Timer soll alle 10us einen Interrupt auslösen.
> Die Interuptroutine benötigt aber stets 20us bis sie abgearbeitet ist
> und geschlossen wird.
Dann würde ich effizientere Programmierung und wenn das nichts hilft 
einen Schnelleren µC verwenden.

Der µC wird die ganze Zeit in einer ISR sein und hat keine Zeit für die 
Ausführung der main();

: Bearbeitet durch User
von Marcel (Gast)


Lesenswert?

Das entsprechende Interrupt-Flag wird zwar gesetzt, aber nicht direkt 
abgearbeitet. Alle 10µs kommt ein IRQ, alle 20µs ist der Interrupt 
fertig. Das Programm arbeitet also nur jeden zweiten IRQ ab. Während der 
IRQ nicht direkt ignoriert wird, wird er aber auch nicht abgearbeitet.

Wenn du per sei() am Anfang des Interrupts wieder neue IRQ zulässt wird 
der Interrupt immer wieder unterbrochen und es wird niemals einer fertig 
abgearbeitet.

von g457 (Gast)


Lesenswert?

> Der µC wird die ganze Zeit in einer ISR sein und hat keine Zeit für die
> Ausführung der main();

Doch, die wird schon ausgeführt (sofern der IP sich in der main() 
aufhält), aber ziemlich langsam :-)

> Wenn du per sei() am Anfang des Interrupts wieder neue IRQ zulässt wird
> der Interrupt immer wieder unterbrochen und es wird niemals einer fertig
> abgearbeitet.

..und insbesondere läuft der Stack ratzfatz voll. Also ein gaaanz 
schlechte Idee.

von Peter II (Gast)


Lesenswert?

Marcel schrieb:
> Wenn du per sei() am Anfang des Interrupts wieder neue IRQ zulässt wird
> der Interrupt immer wieder unterbrochen und es wird niemals einer fertig
> abgearbeitet.

und dann stützt er wirklich ab, dann damit überschreibst du dir nach 
einer weile den Stack.

von Ein Elektroniker (Gast)


Lesenswert?

Marcel schrieb:

> Wenn du per sei() am Anfang des Interrupts wieder neue IRQ zulässt wird
> der Interrupt immer wieder unterbrochen und es wird niemals einer fertig
> abgearbeitet.

Abgesehen davon, daß der Stack dann schnell überläuft: Warum läßt man 
das in der Architektur zu, einen Interrupt wieder beginnen zu können, 
wenn er noch nicht fertig ist? Ich kann es noch gar nicht richtig 
glauben.

Bei 8051 ist das doch besser gelöst, und ein Interrupt wird erst 
automatisch wieder frei gegeben, wenn er beendet wurde. Zusätzlich ist 
noch gewährleistet, daß zwischen zwei Interrupts immer ein einziger 
Befehl des Hauptprogrammes noch abgearbeitet wird, damit dieses nicht 
ganz stehen bleibt. Dort würden Interrupts einfach nur verschluckt, wenn 
die Verarbeitung länger ist als die Interruptintervalle. Daß immer ein 
Hauptprogrammbefehl zwischen Interrupts verarbeitet werden muß, war mal 
ein Fortschritt zu Zeiten, als 8085 und 8048 und kurz darauf der 8051 
entwickelt wurde.

Den pegelgetriggerten Interrupt macht man sich so beim 8051 für einen 
Software-Single-Step zu Nutze. Echten Single-Step kann er ja wegen 
dynamischem Design nicht.

Ich kenne ATmega nicht, frage einfach nur mal locker in die Runde.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Da läuft überhaupt kein Stack voll.

Wenn ein neuer Interrupt eintrifft, während der µC noch in der ISR ist, 
dann wird ein Flag gesetzt, dass ein neuer Interrupt eingetreten ist.

Sobald die aktuelle ISR verlassen wird, wird die ISR direkt wieder neu 
gestartet, da ja das Flag gesetzt ist.

Wenn also die Interrupts schneller reinkommen als sie abgearbeitet 
werden, wird lediglich die ISR dauerhaft aufgerufen und bekommt so 100% 
CPU-Zeit.

Aber da es kein rekursiver Aufruf ist (denn erst nach Verlassen wird die 
ISR erneut aufgerufen), läuft da auch nix über - schon gar nicht der 
Stack.

Also wie A.K. schon sagte: Kein Absturz.

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ein Elektroniker schrieb:
> Abgesehen davon, daß der Stack dann schnell überläuft: Warum läßt man
> das in der Architektur zu, einen Interrupt wieder beginnen zu können,
> wenn er noch nicht fertig ist? Ich kann es noch gar nicht richtig
> glauben.

Standardmäßig passiert das ja nicht. Man kann den Interrupt früher 
erlauben, als das System es vorsieht - wenn man genau weiß, was man da 
tut.

Deine Frage hört sich an wie: "Warum lässt man bei Autos zu, dass man 
sich nicht anschnallt und dann gegen eine Wand fährt? Ich kann es noch 
gar nicht richtig glauben."

von (prx) A. K. (prx)


Lesenswert?

Ein Elektroniker schrieb:
> Abgesehen davon, daß der Stack dann schnell überläuft: Warum läßt man
> das in der Architektur zu, einen Interrupt wieder beginnen zu können,
> wenn er noch nicht fertig ist?

Sie lsst es von Haus aus nicht zu. Aber sie lässte es zu, dass du dir 
mit SEI absichtlich oder versehentlich in den Fuss schiesst.

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Da läuft überhaupt kein Stack voll.

Das bezog sich auf die SEI Variante. Dann läuft der sehr wohl voll.

von Mike (Gast)


Lesenswert?

006 schrieb:
> Was passiert dann genau?

Das siehst du am besten, wenn du mal den Simulator anschmeißt. Da kannst 
du dir jedes Register angucken, auch den Programm Counter.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Frank M. schrieb:
>> Da läuft überhaupt kein Stack voll.
>
> Das bezog sich auf die SEI Variante. Dann läuft der sehr wohl voll.

Dann natürlich ja. Aber nicht alles ist sinnvoll, was auch erlaubt ist. 
;-)

Ich wollte nur klarstellen, dass im Standardfall (kein frühzeitiges 
Interrupt-Enable in der ISR selbst) nichts passieren kann. Wer das 
dennoch macht, muss sich über die Konsequenzen im Klaren sein.

von Ein Elektroniker (Gast)


Lesenswert?

Frank M. schrieb:

> Wenn also die Interrupts schneller reinkommen als sie abgearbeitet
> werden, wird lediglich die ISR dauerhaft aufgerufen und bekommt so 100%
> CPU-Zeit.

Scheinbar kann ich beim ATmega dann nicht mit reden. Wenn wirklich 
zwischen Interrupts das Hauptprogramm überhaupt nicht mehr läuft, wie 
der eine Befehl, der beim 8051 immer zwischen zwei Interrupts 
abgearbeitet wird, was man schon 1975 als Mangel erkannte, dann ist das 
schlecht.

Allerdings waren diese µC auch noch auf Assembler und kleine Programme 
und nicht C optimiert, und mit Abarbeitung komplexerer C-Funktionen in 
Main kommt man auch nicht besonders weit, daß das Main-Programm gut 
weiter läuft.

von Thomas E. (thomase)


Lesenswert?

Ein Elektroniker schrieb:
> Scheinbar kann ich beim ATmega dann nicht mit reden. Wenn wirklich
> zwischen Interrupts das Hauptprogramm überhaupt nicht mehr läuft, wie
> der eine Befehl, der beim 8051 immer zwischen zwei Interrupts
> abgearbeitet wird, was man schon 1975 als Mangel erkannte, dann ist das
> schlecht.
Das ist beim AVR genauso.

Wie soll man das sonst lösen? Außerdem gab es 1975 noch gar keinen 8051.

mfg.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Die Cortex Ms hingegen kriegt man auf diese Art stillgelegt. Die sind 
darauf optimiert, ISRs möglichst fix abzuarbeiten, und es ist fixer, 
direkt von einer ISR in die nächste zu hüpfen, als zweimal den ganzen 
Stack-Kram abzuarbeiten.

Ob man das freilich als Nachteil sehen sollte? Wer seine Kiste so baut, 
dass sich über eine längere Zeit ISRs dicht an dicht stapeln und im 
Hauptprogramm rein garnichts mehr geht, der hat wohl etwas falsch 
kalkuliert.

von S. R. (svenska)


Lesenswert?

> Abgesehen davon, daß der Stack dann schnell überläuft: Warum läßt man
> das in der Architektur zu, einen Interrupt wieder beginnen zu können,
> wenn er noch nicht fertig ist? Ich kann es noch gar nicht richtig
> glauben.

Weil das eine Voraussetzung für verschachtelte (softwarepriorisierte) 
Interrupts ist. Du kannst ja nicht nur Interrupts global sperren, 
sondern die auch für jede Quelle einzeln ein- und ausschalten.

> Bei 8051 ist das doch besser gelöst, und ein Interrupt wird erst
> automatisch wieder frei gegeben, wenn er beendet wurde.

Das ist auch das normale Verhalten. Für Sonderfälle kann man es aber 
auch anders machen - niemand zwingt dich.

von Max H. (hartl192)


Lesenswert?

Bei den 8 bit PICs ist es ähnlich: Das Interrupt Enable Bit wird beim 
Sprung in die ISR gelöscht und dann mit dem RETFIE (Return from 
Interrupt Enabele) Befehl wieder gesetzt. Dem Programmierer steht es 
natürlich frei das Bit, wenn er es für sinnvoll hält, früher wieder zu 
setzen.

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.