WinAVR und INT Priorität?

Hallo,

bisher habe ich beim ATmega unterbrechbare INT-Routinen vermieden.

Ich denke momentan aber über ein Projekt nach, wo sich das wohl nicht vermeiden lassen wird. Dazu hab ich mir mal den Artikel

formatting link

durchgelesen.

Im Prinzip ist das schon alles klar. In Assembler auf nem 8031 hab ich früher solche Sachen auch schon gemacht.

Mir ist da jetzt nur eine Aussage in dem Artikel aufgefallen, die mir nicht ganz einleuchtet:

------snip ------------------------------------------------------- #include

ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */ { /* Interrupt-Code */ }

....Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das Global Enable Interrupt Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden ? auch XXX-Interrupts.

Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen durch Rekursion...

Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau: ...

ISR (XXX) { // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen

// Erlaube alle Interrupts (ausser XXX) sei();

//... Code ...

// IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos // aktivieren zu koennen cli();

} Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.

---------------- snip --------------------------------------------------

Wieso sollte sich der xxx-IRQ selbst unterbrechen können?

Ich dachte, das könnte nur ein höher priorisierter IRQ? Es müsste doch ausreichen, das IRQ-Flag am Ende der ISR-Routine zu löschen. Dann gehen zwar diese zusätzlichen IRQ-Anforderungen verloren, aber bei meiner aktuellen Anwendung wäre das sogar erwünscht.

Gruß

Stefan

Reply to
Stefan
Loading thread data ...

Das ist Unsinn. Eine ISR, die sich selbst unterbricht (also zweimal aufgerufen wird), führt nicht zu einer " Art Endlosschleife". Insbesondere ist der Gedanke der "Rekursion" hier falsch. Ein ISR ruft nicht einen anderen ISR auf, die Stacks werden nur aufeinander geschachtelt. Es kann halt zu Stack-Overflow kommen, wenn ISRs zu oft aufgerufen werden. Prinzipiell bedeuted ein ISR, der zweimal zuschlägt noch überhaupt nicht, dass der ISR auch ein drittes Mal kommt.

Nein, das hast du falsch verstanden. Bei der 8-Bit AVR Architektur entscheidet die Priorität (also die Position in der Vektortabelle) nur darüber, welcher aufgerufen wird, wenn gleichzeitig zwei Interrupts anstehen (also die IFs gesetzt sind). Die 8 bit AVR-Architektur kennt aber nur zwei Priolevels, IRQ und !IRQ. Insofern nützt da die Priorisierung recht wenig.

Wenn du in einer ISR IRQs wieder zulässt, kann jeder (auch der, der gerade abgearbeitet wird), wieder zuschlagen.

Viele Grüße, Johannes

Reply to
Johannes Bauer

Stefan schrieb:

Nein. So ist halt die CPU-Architektur von AVRs. Die CPU "weiß" gar nicht, dass sie gerade die ISR eines Interrupts mit der Priorität X ausführt. Wie soll sie dann wissen, ob der gerade ausgelöste Interrupt eine höhere oder niedrigere Priorität hat?

Oder in den Worten des ATmega16-Datenblatts (exemplarisch ausgewählt, Hervorhebung von mir): "When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts are disabled. The user software can write logic one to the I-bit to enable nested interrupts.

*All* *enabled* *interrupts* can then interrupt the current interrupt routine."

Christian

--
Christian Zietz  -  CHZ-Soft  -  czietz (at) gmx.net
WWW: http://www.chzsoft.de/
PGP/GnuPG-Key-ID: 0x6DA025CA
Reply to
Christian Zietz

Stimmt nicht ganz. Die XMega-Architektur kennt das momentane IRQ-Level sehrwohl. Nur die kleinen 8-Bitter (Mega) können das nicht.

Gruß, Johannes

Reply to
Johannes Bauer

Johannes Bauer schrieb:

"Kleiner 8-Bitter (Mega)", "kleiner 8-Bitter (Mega)", wenn ich das schon höre! Zu meiner Zeit war ein kleiner 8-Bitter ein AT90S1200! Und den mussten wir noch per Assembler programmieren, unter Windows 98! Wir hatten ja nix! Und das AVR Studio mussten wir mit unseren 56k-Modems herunterladen! Jaja, so war das! Und trotzdem sind wir zurande gekommen!

SCNR Henning

Reply to
Henning Paul

Haha, ich bin schon etwas verwöhnt, seitdem ich Cortex-M3/M4 verbastele (auch hobbymäßig) will ich eigentlich mit den AVRs nicht mehr viel machen. Und preislich ist der Unterschied nicht mehr groß.

Aber die alten AT90S1200 habe ich auch noch programmiert. Und, mal ehrlich, das war schon ne ziemliche Pest. Wobei man mit dem auch C programmieren konnte, wenn man den 90S2313 als Target eingestellt hatte (IIRC hatte der schon einen festen Stack von 8 Bytes oder so für ISRs).

Viele Grüße, Johannes

Reply to
Johannes Bauer

Johannes Bauer schrieb:

Waren meine ersten Schritte mit Microcontrollern im eigentlichen Sinne, nachdem ich vorher Hand-Assembler auf Z80 mit EEPROM gemacht hatte. Da war das schon eine Verbesserung.

Gruß Henning

Reply to
Henning Paul

Am 18.09.2012 11:52, schrieb Henning Paul:

Ging bei mir auch mit Z80 los. Hand-Assembler und dann von einem Basic Programm aus Data Zeilen ins Ram Ge-Poked ;-)

Später dann 8088, dann den Proz aus meinem Sharp-Taschenrechner PC1251,

6802, 8031, PIC, jetzt AVR. Momentan lese ich mich in STM32 ein.

Gruß

Stefan

Reply to
Stefan

schrieb:

Nun, bei mir war das 1996... :-)

Gruß Henning

Reply to
Henning Paul

Am Tue, 18 Sep 2012 11:40:41 +0200 schrieb Henning Paul:

Das war doch mehr als reichlich ;-)

Die ersten Programme auf Papier in Assemblersprache erstellt, per Hand in Hex codiert und dann über die Taschenrechnertastatur eines selbstgebauten Rechners in einen EPROM gebrannt. Der wanderte dann zum testen in den Sockel der Zielplattform und kurz danach zum löschen unter die UV-Lampe (selbstgebaut aus HQL-Leuchte ohne Glas).

Dann wieder zurück zum Papier in Assembler ...

Lutz

--
Mit unseren Sensoren ist der Administrator informiert, bevor es Probleme im 
Serverraum gibt: preiswerte Monitoring Hard- und Software-kostenloses Plugin 
auch für Nagios - Nachricht per e-mail,SMS und SNMP: http://www.messpc.de
Messwerte nachträgliche Wärmedämmung http://www.messpc.de/waermedaemmung.php
Reply to
Lutz Schulze

Am 18.09.2012 11:30, schrieb Christian Zietz:

Klingt soweit plausibel. Ich hab im Datenblatt des ATmega88 den folgenden Satz gefunden:

"The ICF1 Flag is automaticaly cleared, when the interrupt is executed."

Bezüglich INTF1 und INTF0 steht da so ziemlich das gleiche.

Das Flag wird also nicht erst beim "Return from Interrupt", sondern bereits beim Aufrufen der INT-Routine(?) zurückgesetzt.

Beim 8031 kenne ich das etwas anders. Da wurde der INT erst mit dem RETI wieder freigegeben. Da hatte ich manchmal Timer-Routinen, die jedes

1000. Mal oder so länger brauchten und deshalb von sich selbst unterbrochen werden können sollten. Da hab ich dann die Adresse des langen Programmteils auf den Stack geschrieben und dann ein RETI ausgeführt um das INT-Flag zurückzusetzen.

Gruß

Stefan

Reply to
Stefan

Am 18.09.2012 12:06, schrieb Henning Paul:

War bei mir 1980 ;-)

Gruß

Stefan

Reply to
Stefan

Wieso sollte er das nicht können?

Es gibt bei den AVRs keine Interruptprioritäten im üblichen Sinne, sondern nur in dem stark eingeschränkten Sinne, daß dadurch geregelt ist, welcher Vektor zuerst aufgerufen wird, wenn zwei Interrupts gleichzeitig erfolgen.

Nein, bei den allermeisten Interrupts der AVRs ist das nicht der Fall, weil das interuptspezifische Flag jeweils automatisch beim Durchlaufen des zuständigen Interruptvektors zurückgesetzt wird. Dann ist die einzige verbleibende Hemmung gegen eine erneute Auslösung das globale Interruptflag.

Wenn du dieses Verhalten haben möchtest, dann müßte die ISR ungefähr so aufgebaut sein (für die Interrupts mit Autoreset des Flags):

-spezifischen Interrupt disablen

-globalen Interrupt enablen

-... (dein Nutzcode)

-spezifisches Interruptflag löschen (könnte inzwischen gesetzt worden sein)

-spezifischen Interrupt enablen

Reply to
Heiko Nocon

IMHO ein übler design Fehler :( Du kannst böse Fehler im Echtzeitverhalten bekommen.

Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang

--
Wolfgang Allinger, anerkannter Trollallergiker :) reply Adresse gesetzt!
Ich diskutiere zukünftig weniger mit Idioten, denn sie ziehen mich auf
ihr Niveau herunter und schlagen mich dort mit ihrer Erfahrung! :p
(lt. alter usenet Weisheit)
Reply to
Wolfgang Allinger

Am 18.09.2012 12:48 schrieb Stefan:

Moment, das sind 2 Paar Schuhe. IFC1/INTFx sind die Flags des jeweiligen Interrupts. Sie zeigen an, ob/daß ein entsprechender Interrupt aufgetreten ist und daß die ISR ausgeführt werden soll. Dies wird sie aber nur dann, wenn das globale Interrupt Enable-Flag gesetzt ist.

Das globale, ja.

Thomas

Reply to
Thomas Rachel

Am 18.09.2012 17:00, schrieb Wolfgang Allinger:

Hat perfekt funktioniert ;-)

Gruß

Stefan

Reply to
Stefan

Du hast möglicherweise ein anderes Verständnis von Echtzeit. Bei meinen Echtzeit Anwendungen durfte nie nich ein IR sich selber unterbrechen, da dann als 1. die zeitliche Zuordnung auf der Strecke bleibt und der Rest ähnelt einem Zufallsgenerator. Ein absolutes nogo!

Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang

--
Wolfgang Allinger, anerkannter Trollallergiker :) reply Adresse gesetzt!
Ich diskutiere zukünftig weniger mit Idioten, denn sie ziehen mich auf
ihr Niveau herunter und schlagen mich dort mit ihrer Erfahrung! :p
(lt. alter usenet Weisheit)
Reply to
Wolfgang Allinger

5058b60f$0$30119$ snipped-for-privacy@newsreader.ewetel.de

wrote:

Sowas habe ich auch schonmal programmiert und das geht, wenn man vorsichtig programmiert. Ist in meinem Fall ein schneller 1024 Hz Timer Interrupt, der zunächst am Anfang Sensorwertmittelung usw. macht und danach genau jedes 64. mal in eine bis zu 16 ms dauernde Routine verzweigt, und dazu dann sich selbst wieder freigibt, um währenddessen für die Sensorabfrage wieder aufgerufen zu werden. Alles auf einem kleinen HC08 Microcontroller implementiert und keine Probleme mit Echtzeit und der zeitlichen Zuordnung. Sind schon einige von dem Produkt verkauft worden wo das drin läuft, seit Jahren keine negativen Rückmeldungen.

--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
Reply to
Frank Buss

Hör mir mit dem Atmel-Scheiß auf. Damals vor paar Jahren habe ich bei Batronix den billigeren EPROMer gekauft, ohne µC-support, dachte, das brauche ich eh nie. Nun steht es an, einem kleinen 8-Beiner von Atmel neue Software zu verbraten. Also so'n AVR-Drachen gekauft. Kein Sockel drauf, na gut, ich brauch das Ding eh selten, ZIF lohnt net, also Stiftleisten eingelötet. Software runtergeladen und dabei bemerkt, man muß eine Monstrer-Entwicklungsumgebung installieren. Argl. Dann diese und die Doku näher angesehen, dabei bemerkt, man muß noch x Drähtchen als Brücken einsetzen, um überhaupt erst mal eine passende Konfig zum IC zu verdrahten. Mega-Argl. Ich hätte doch einfach bei Batronix "kaufen" klicken sollen :(

-ras

--

Ralph A. Schmid

http://www.schmid.xxx/ http://www.db0fue.de/
http://www.bclog.de/
Reply to
Ralph A. Schmid, dk5ras

Wenn das so war, hast du was bei der Implementierung falsch gemacht.

Tatsächlich ist es des öfteren so, daß ich unterbrechbare ISRs verwende. I.d.R. dann, wenn burstartige Lastspitzen auftreten, wo zwar während des Bursts die Rechenzeit nicht genügt, sie im Durchschnitt aber hinreichend ist. Genau das ist übrigens das erste Kriterium, an dem sich die grundsätzliche Machbarkeit entscheiden läßt.

Dann bestehen die ISRs aus zwei Teilen, einem nicht unterbrechbaren, in dem die "Daten" erstmal nur in einen (Ring-)Puffer geschrieben werden und einem unterbrechbaren, der die Daten aus dem Puffer holt und dann den zeitaufwendigeren Teil der Operationen daran durchführt. Die Größe des verfügbaren Puffers ist das zweite Kriterium für die Machbarkeit. Sie bestimmt mit, wie lange so ein Hochlast-Burst maximal andauern darf.

Was zu tun bleibt, um das von dir beschriebene Fehlverhalten zu vermeiden, ist einfach bloß eine saubere Synchronisierung zwischen den Interruptinstanzen. Diese Synchchronisation und der "Umweg" der Daten über den Puffer kosten aber natürlich auch Rechenzeit. Dieser Aufwand ist das dritte Kriterium für die Machbarkeit, hierdurch wird nämlich der Maximaldurchsatz in der Burstphase bestimmt.

An diesem Grundkonzept sind übrigens noch einige Optimierungen möglich. Z.B. kann man den nicht unterbrechbaren Teil der ISR so konstruieren, daß sie bei sehr hoher Last zeitweise zu einer Pollingschleife mutiert. Das erhöht den möglichen Spitzendurchsatz signifikant, weil dann der Aufwand für Interruptauslösung und Synchronisation entfällt. Man kann auch dafür sorgen, daß bei geringer Last die Pufferung unterbleibt, was dann in dieser Situation etwas mehr Rechenzeit für den Rest des Systems frei läßt.

Reply to
Heiko Nocon

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.