Forum: Mikrocontroller und Digitale Elektronik Merken sich AVRs Interrupts?


von Ben _. (burning_silicon)


Lesenswert?

ich habe noch eine verständnisfrage zu den AVR interrupts. wenn man 
mehrere interrupts verwendet besteht ja die möglichkeit, daß sich diese 
zufällig überlagern. sprich interrupt B wird ausgelöst während die ISR 
von interrupt A noch nicht beendet wurde.

der AVR sollte in so einem fall nun aus der ISR A in die ISR B springen, 
diese abarbeiten, danach wieder zur ISR A zurückkehren und dort 
fortsetzen wo sie unterbrochen wurde.

machen die AVRs das von hause aus so oder muß ich dieses verhalten erst 
irgendwie "anfordern"?

von hdd (Gast)


Lesenswert?

Der neuere Interrupt wird erst dann abgearbeitet, wenn du Interrupts 
global wieder aktivierst. Die geschieht z.B. mit sei oder reti.
Wenn du am Anfang der ISR A die Interrupts wieder frei gibst und der 
Interrupt B auftritt, wird zu ISR B gesprungen und am Ende von B wird A 
fertig abgearbeitet.
Wenn aber immer wieder ein Interrupt kommt, bevor der letzte fertig 
wird, geht das nur solange, bis dein Stack überläuft vor 
Rücksprungadressen.

von MWS (Gast)


Lesenswert?

In einer ISR sind andere Ints per Global Interrupt Flag gesperrt.

Evtl. weitere auftretende Int-Anforderungen werden in entsprechenden 
Flags "gemerkt" und dann ausgeführt, sobald die gegenwärtige ISR beendet 
ist.

Sind mehrere Ints gleichzeitig "gemerkt", so gibt's eine 
Ausführungspriorität.

In einer ISR können weitere Ints mit SEI erlaubt werden. Bei der 
expliziten Freigabe, und damit der Umgehung des AVR Int Systems, sollte 
man allerdings genau wissen was man da so macht.

von Stefan B. (Gast)


Lesenswert?

Ja, Interrupts werden gemerkt, allerdings, wenn mehrere der gleichen 
Sorte auftreten, dann wird nur der erste dieser Sorte gemerkt. 
Beschrieben ist das im Datenblatt.

"Normal/Üblicher" ist, dass Interrupt B erst bearbeitet wird, wenn 
Interrupt A fertig ist. Dein beschriebenes Verhalten nennt man /nested 
interrupts/ und das ist in der avr-libc beschrieben
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

von Simon K. (simon) Benutzerseite


Lesenswert?

Prinzipiell ist kein "mehrstufiger Merker" für Interrupts im AVR 
vorgesehen.
Aber Jede Hardware Einheit hat ein Interruptflag, was bei der jeweiligen 
Bedingung gesetzt wird.
Und dann gilt einfach eine UND Verknüpfung (Maskierung) mit sei und dem 
jeweiligen Interrupt Enable.

Heißt: Wenn ein Interrupt ausgelöst wird, wird das Flag gesetzt. Die 
Verarbeitung kann aber verzögert stattfinden (gelöschtes I-Bit. Kommt 
allerdings ein zweiter (gleicher) Interrupt, setzt er das Flag noch mal. 
Und das ist die Stelle an der der erste Interrupt "verloren" geht. Es 
sind zwar zwei aufgetreten, aber das kann ja nicht mehr unterschieden 
werden.

von Ben _. (burning_silicon)


Lesenswert?

sprich wenn ich eine usart-RX ISR habe und während ich mir mein zeichen 
hole, es irgendwo in den speicher schmeiße und gleichzeitig wird ein 
timer compare interrupt ausgelöst bzw. "vorgemerkt" dann kann dieser auf 
keinen fall verlorengehen?

ist jetzt nicht so superkritisch, die timer ISR kann ruhig die paar 
takte warten bis usart-RX abgeschlossen wurde. die macht nichts weiter 
als ein flag fürs hauptprogramm zu setzen.

aber für spätere anwendungen wäre es mit einem SEI am anfang einer ISR 
auch möglich, interrupts geschachtelt auszuführen? natürlich nur solange 
genug platz auf dem stack ist und sich nichts rekursiv aufruft. dieser 
situation könnte man zur not ja auch mit einem hilfsflag zuleibe rücken.

von STK500-Besitzer (Gast)


Lesenswert?

>gleichzeitig wird ein timer compare interrupt ausgelöst bzw. "vorgemerkt" >dann 
kann dieser auf keinen fall verlorengehen?
Ja. einer. Wenn mehrere aufgrund einer zu langen ISR auftreten, wird nur 
ein Interrupt registriert.

>aber für spätere anwendungen wäre es mit einem SEI am anfang einer ISR
>auch möglich, interrupts geschachtelt auszuführen?

Ja, ich bin auch der Meinung, dass es von Atmel zu dem Thema eine 
Application Note gibt.

von Falk B. (falk)


Lesenswert?

Siehe Interrupt

von Peter D. (peda)


Lesenswert?

Jedesmal, wenn Interrupts global erlaubt sind, werden alle freigegebenen 
Interruptquellen von neuem geprüft und dann der niedrigste Interrupt 
ausgeführt.

Damit das funktioniert, haben alle Interruptquellen ein Interruptflag, 
welches durch das Ereignis gesetzt wird (unabhängig von der 
Interruptfreigabe).
Und solange dieses nicht gelöscht wurde, wird es nach Freigabe einen 
Interrupt auslösen.


Manchmal will man aber nicht einen Interrupt auf längst vergangene 
Ereignisse auslösen, dann muß man das Interruptflag vor 
Interruptfreigabe löschen (also auf 1 setzen).

Manchmal will man auch das Ereignis wissen, aber keinen Interrupt 
auslösen, dann kann man auf das Interruptflag pollen, muß es danach aber 
per Software löschen.


Peter

von Ben _. (burning_silicon)


Lesenswert?

danke euch für die antworten!

bei mir ists schon so, daß ich die interrupts haben will weil ich mich 
dann weniger um den programmfluß zu kümmern brauche. die flags zu pollen 
finde ich nicht besonders schön.

ich kenne es halt vom PC nur so, daß sich der x86 keine interrupts 
merkt. sprich der unterdrückte interrupt ist verloren. ist aber auch das 
komplexere system, es lassen sich z.b. auch interrupts per software 
aufrufen, welche dann vom BIOS oder TSR-programmen verarbeitet werden.

von Peter D. (peda)


Lesenswert?

Ben _ schrieb:
> die flags zu pollen
> finde ich nicht besonders schön.

Mußt Du ja nicht schön finden.

Schön ist aber, daß man die Möglichkeit hat.
Wird z.B. sehr gerne für die UART verwendet.


> ich kenne es halt vom PC nur so, daß sich der x86 keine interrupts
> merkt. sprich der unterdrückte interrupt ist verloren.

Nö.
Eine CPU, wo Interrupts verloren gehen, wäre nutzlos und würde keiner 
benutzen.

Du hast ein OS und da wäre es blöd, wenn Interrupts ohne Handler ins 
Nichts laufen würden.
Wenn Du einen Handler aufsetzt, kriegst Du auch alle Interrupts.


Peter

von Ben _. (burning_silicon)


Lesenswert?

gerade beim usart finde ich es toll, daß ich kein polling machen muß, 
sondern der µC sich "von alleine" darum kümmern kann. und wenn man es 
einmal verstanden hat ist es meiner meinung nach die deutlich einfachere 
lösung.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ja, klar. Timer Interrupts machen bei Multiplexing zum Beispiel auch 
Sinn.

Aber wenn man einfach nur einen definierten Takt in der Main haben will, 
braucht man nicht unbedingt einen Interrupt (der dann eh wieder nur ein 
Variablen-Flag setzen würde). Dann kann man besser direkt das Interrupt 
Flag des Timers pollen (Statt dem Variablen-Flag).

von Ben _. (burning_silicon)


Lesenswert?

das ist eine frage des programmierstils und wie komplex das programm 
ist. wenn ich z.b. eine uhr habe würde ich die berechnung der stunden, 
minuten und sekunden in die ISR packen damit ich das im hauptprogramm 
aus dem sinn habe. dort kann ich die mich interessierenden werte dann 
direkt verarbeiten ohne sie erst berechnen zu müssen.

von Hannes L. (hannes)


Lesenswert?

Ben _ schrieb:
> das ist eine frage des programmierstils und wie komplex das programm
> ist.

Richtig.

> wenn ich z.b. eine uhr habe würde ich die berechnung der stunden,
> minuten und sekunden in die ISR packen damit ich das im hauptprogramm
> aus dem sinn habe. dort kann ich die mich interessierenden werte dann
> direkt verarbeiten ohne sie erst berechnen zu müssen.

Das kann aber auch nach hinten losgehen, wenn das Programm sich noch um 
einige andere zeitkritische Dinge kümmern muss. Dann kann eine zu lange 
ISR schonmal den ganzen Programmablauf stören, weil ein anderer 
Interrupt (z.B. ICP oder Soft-ICP per ext.-Int.) nicht pünktlich zum 
Zuge kommt und Impulse verliert oder verfälscht.

Wenn nur ein Interrupt (Timer) im Programm ist, dann kann man sogar das 
gesamte Programm in die ISR legen. Sind mehrere Interrupts involviert, 
dann müssen alle Interrupts eben so kurz wie möglich sein. Dann müssen 
aber auch die Mainloop-Jobs so geschrieben werden, dass sie nirgends auf 
irgendetwas warten müssen, sondern sofort zur Mainloop zurückkehren, 
wenn ein Arbeitsschritt momentan nicht ausführbar ist.

Es (das Konzept eines Programms) ist also immer eine Frage der 
Situation. Was in einem Programm sinnvoll erscheint, kann in einem 
anderen Programm kontraproduktiv sein. Wenn Interrupts verloren gehen, 
dann stimmt das Konzept nicht.

...

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.