mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Länge von ISR?


Autor: Lutz Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

eine ISR soll ja so kurz wie nur irgend nötig sein und der Rest bzw.
Rechenintensive Sachen im Hauptprogramm in einer Endlosschleife durch
in den ISR gesetzten Statusbits erledigt werden. Nun zur eigentlichen
Frage: Gibt es eine Art Faustregel, ab wann man etwas aus der ISR
auslagern soll, z.B. Anzahl der (voraussichtlichen) Takte in der ISR?
Ist wohl schwer zu sagen, deshalb mein konkretes Beispiel: Ich will
z.B. timerinterruptgesteuert eine Spannung mit dem ADC messen. Um die
Batterie zu schonen, soll der ADC nur dann laufen, wenn er auch muß.
Ich muß also in der ISR des Timers nachschauen, ob der ADC schon an ist
und ob ein globales "Unter"statusbit (Dummyreadout schon erledigt;
richtige Messung kann folgen) gesetzt ist. Ist er nicht an, so muß ich
ihn anschmeißen und einen Dummyreadout machen. Macht 25 ADC-Takte +
Ergebnis speichern + irgendwas für Statusbits sezten + hin- und
rücksprung etc. Und jetzt endlich die Frage: Schicke ich ihn nach
Starten des ADC und anleiern des Dummyreadout wieder aus der ISR in
Hauptprogramm und warte auf den ADC-complete-Interrupt oder nicht?
Leider häufen sich solche Fragen in letzter Zeit bei mir und ich kann
es absolut nicht abschätzen, da ja auch die ISR und das Hauptprogramm
länger werden und zusätzlich ständig hin- und hergesprungen wird. Oder
gilt: Alles egal, Hauptsache ISR so kurz wie irgend möglich?

Danke und Gruß
Lutz

Autor: seacrash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Warteschleifen in der ISR sind wohl fehl am Platz. Gleiches gilt
auch für´s Hauptprogramm. Dort sollte sich dann aber die Abfrage
befinden die auswertet, ob eine bestimmte Aktion schon erledigt ist
oder nicht. Falls nicht, kann man locker weitergehn zum nächsten
Problem und kommt dann später wieder mal vorbeigeschländert. und schaut
mal nach. Das sichert einem eine möglichst schnelle Abarbeitung aller
Programmteile.

Sollte es aber unabdingbar sein das man etwas möglicherweise
"aufschiebt" , dann muß es in der ISR erledigt werden. Aber meistens,
machen ein paar ms (worst case beachten?) wohl nicht fett.

Grüße

Autor: seacrash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wen denn?

     den Kohl!!!!!

natürlich

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

eines vorneweg - es gibt da keine generelle Vorgehensweise. Man muß die
Gesammtsituation bewerten und dann die richtige Lösung wählen.

Das ist jetzt natürlich etwas "Bla-Bla", aber ich will das etwas
verdeutlichen:

Beispiel 1: 10 KHz-PWM. Angenommen ich möchte eine 10 KHz PWM
realisieren (Taus + Tan = 100 us), die als in 100 Schritt Auslösung
eine Motorleistung sateuert, dann hat Tan die Werte 0us (keine
Leistung, 1us(1%Leistung, 2 (2%.....), .... 100us (100% Leistung) um
entsprechend die Leistung zu regeln. Wenn ich nach 5us z. wieder die
PWM ausschalten muß, dann ist es offensichtlich, daß ich im
Mikrosekundenbereich reagieren muß und alle ISR entsprechend kurz sein
müssen, damit sich hier nichts unnötig verzögert.
Hier hat man also keine Zeit zu verschenken und muß wirklich alles was
geht aus der ISR raushalten.

Beispiel 2: Deine Spannungsmessung. Ich nehme im Beispiel mal an, du
mußt eine Spannung messen und hast sonst nichts zeitkritisches
auszuführen - es kommt also auf ein paar mikrosekunden mehr oder
weniger nicht an. Vielleicht machen sogar ein paar Millisekunden mehr
oder weniger auch nichts aus.
Dann ist es sogar fraglich, warum man überhaupt einen Interrupt nehmen
sollte. Wenn der Ablauf sequentiell ist - zb beispiel Spannung messen,
auswerten, reagieren, Spannung messen, auswerten .... dann würde ich
sogar alles in der Hauptschleife erledigen und das AD-ready Flag
pollen.

Also, ich hoffe etwas zum Verstehen beigetragen zu haben. Man muß den
Aufwand immer angepaßt betreiben: So einfach und simple als möglich, so
schnell (und kompliziert) als nötig.

Ich habe auf meiner Homepage unter "Interessantes/Echtzeit auf uC"
auch einen kleinen Artikel über Mikrocontroller und Echtzeit -
vielleicht wirfst Du mal einen Blick rein.

Gruß

Wolfgang
--
www.ibweinmann.de
Brushless Development Kit - der Einstieg in die Brushless Regler
Technik

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das andere Extrem hab ich auch schon verwendet:
Das Hauptprogramm besteht nur aus einer Endlosschleife wie:
main: rjmp main
und alles andere wird komplett in der ISR erledigt.

Es gibt keine generelle Regel, wie mit ISRs unzugehen ist.
Der Interrupt ist ein Werkzeug, das von Fall zu Fall
sinnvoll eingesetzt werden muss.

MfG Willi

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine A/D-Wandlung dauert im Vergleich mit anderen Aktionen recht lange
(je nach eingestellter Taktfrequenz des ADC, bei 125kHz z.B. ~200µs für
die erste und ~100µs für die folgenden Wandlungen). Wenn Deine
Timer-Geschichte der einzige Interrupt in Deiner Anwendung ist, und das
Programm ansonsten außer warten sowieso nichts tut, dann ist das völlig
unkritisch. Wenn Du aber andere Interrupts bearbeiten musst (die u.U.
öfter als alle 100...200µs auftreten können), dann ist das definitiv zu
viel. Dein Posting erweckt den Eindruck, dass dieser Vorgang tatsächlich
die einzige Tätigkeit des Programms ist und der Timer-Interrupt der
einzige verwendete Interrupt. In dem Fall dürfte das kein Problem sein.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Willi

"Das Hauptprogramm besteht nur aus einer Endlosschleife wie:
main: rjmp main
und alles andere wird komplett in der ISR erledigt."


Dann benutzt Du funktional gesehen überhaupt keine Interrupts.

Erklärung:

Da es keine Main-Aktivitäten gibt, die unterbrochen werden, gibt es
auch nur einen Ausführungslevel.

Du kannst also genau so gut alle Interrupts abschalten und in der
Main-Loop die Ereignisflags pollen und dann die Behandlungsroutine
aufrufen. Dein Programm wird um keinen Deut anders laufen.

Interrupts haben nur dann einen Sinn, wenn sie auch wirklich etwas
anderes unterbrechen, d.h. mindestens 2 Ausführungslevel existieren.


Peter

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
>>Interrupts haben nur dann einen Sinn, wenn sie auch wirklich etwas
anderes unterbrechen...

Nicht nur dann:
Interupts sind auch die schnellste Möglichkeit auf ein Ereignis zu
reagieren. Es wird ja sofort über den INT-Vector die richtige ISR
angesprungen. Pollen, und dann entscheiden wo hinzuspringen ist,
verlängert die Reaktionszeit doch erheblich.
Ich habe noch keine schneller Möglichkeit gefunden. (beim AVR)

Auch lässt es sich so (mit noch etwas mehr Aufwand) erreichen, auf
einen internen Timer synchron zu reagieren. Damit meine ich die
Latenzzeit eines Timer-Interrupts konstant zu halten. Also z.B. genau
alle 50us, und nicht 50us + 1 oder 2 oder 3 Takte je nachdem welchen
Befehl der AVR gerade ausführt.

Das "Unterbrechen" der jmp-main-Schleife geht übrigens sogar
schneller, als das "Aufwachen" aus dem Sleep- oder Standby-Zustand.

Also nochmal:
Es gibt keine generelle Regel, wie mit ISRs unzugehen ist.
Der Interrupt ist ein Werkzeug, das von Fall zu Fall
sinnvoll eingesetzt werden muss.

Mfg Willi

Autor: Ronny F. (ronny)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein weiterer Sinn wäre der Energie-Apekt.So kann man manche Controller
in einen Ruhezustand schicken,der erst von dem Timer unterbrochen
wird.

Je nach Controller existieren verschiedene Stufen,z.B nur der Timer
oder ein externes Signal 'wecken' den Rechenkern wieder auf oder
jegliche Pheripherie kann das tun.Wenn der Controller so nur einige
Millisekunden pro Sekunde arbeiten muss und die restliche Zeit
weitgehend im Standby/ Sleep Mode ist,macht sich das langfristig über
die Batterielaufzeit schon bemerkbar.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Willi

"Interupts sind auch die schnellste Möglichkeit auf ein Ereignis zu
reagieren. Es wird ja sofort über den INT-Vector die richtige ISR
angesprungen. Pollen, und dann entscheiden wo hinzuspringen ist,
verlängert die Reaktionszeit doch erheblich.
Ich habe noch keine schneller Möglichkeit gefunden. (beim AVR)"


Nö, eben nicht.

Wenn alle Programme Interrupts sind, wird immer schön gewartet, bis
einer fertig ist, ehe der nächste ran darf.
Und damit bist Du gleich schnell, als ob Du im Main die Flags abfragst,
nachdem eine Funktion fertig ist.

Interrupts können nur das Main unterbrechen, nicht aber sich selber.

Und das mit der Latenzzeit funktioniert nur dann ausnahmsweise, wenn
kein anderer Interrupt auslösen kann, der muß nähmlich erst beendet
werden.


Peter

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter hat recht. Hinzu kommt, dass auch ein Interrupt nicht sofort
bearbeitet wird. Bei den AVRs z.B. dauert der Einsprung in den
Interrupt-Vektor mindestens 4 Taktzyklen. Wenn die ISR nicht direkt in
der Vektortabelle Platz findet, dann sind zusätzlich noch mal 2 bzw. 3
Zyklen für den (r)jmp fällig. Wenn man nur einen einzigen Interrupt
bearbeitet und das Programm sonst auch nicht viel zu tun hat, dann ist
Polling jedenfalls nicht langsamer als die 'echte'
Interrupt-Bearbeitung. Aber wie weiter oben bereits erwähnt: Meist
lässt man seinen Controller süß schlummern, wenn nix anliegt und dann
gehts nur mit nem Interrupt weiter. Das Aufwachen dauert allerdings
u.U. noch länger, als ein normeler Interrupt, weil je nach gewähltem
Sleep-Mode erst mal der Oszillator wieder anschwingen muss...

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:
"Wenn alle Programme Interrupts sind, wird immer schön gewartet, bis
einer fertig ist, ehe der nächste ran darf.
...
Interrupts können nur das Main unterbrechen, nicht aber sich selber."

Das ist so nicht richtig.
Du kanst jederzeit, auch beim AVR innerhalb der ISR,
per sei-Befehl die Interupts wieder freigeben,
dann wird auch die ISR unterbrochen.
Das ist auch nötig, da ja unterschiedliche Prioritäten im Programm
abgebildet werden müssen.

Du musst natürlich wissen was du tust, z.B wer wen unterbrechen
darf und welche Interupt-Flags statisch sind usw. sonst geht das
schief.

@jonny.m
Der Sprung in die ISR dauert nicht mindestens, sondern genau 4 Zyklen,
nachdem der AVR den laufenden Befehl beendet hat. Alles was danach
kommt, auch der evtl. nötige Weitersprung ist exakt berechen- und
planbar. Wenn ich also dafür sorge das der AVR garantiert in einem
1-Zyklus-Befehl (z.B. NOP) ist, und der Interrupt duch einen
(taktsynchronen) Timer ausglöst wird, dann ist alles weiter syncron zum
Timerereignis. Und ich brauche genau 4 Zyklen vom Timerereignis bis zum
ersten Befehl der ISR. Wichtig ist vor allem: Ich brauche bei diesem
Timerinterrupt immer genau 4 Zyklen. Wie willst du in 4 Zyklen
irgendwas pollen und noch irgenwo hinspringen, und dabei noch
Taktsyncron zum Timerereignis bleiben ?


Mfg Willi

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich also dafür sorge das der AVR garantiert in einem
> 1-Zyklus-Befehl (z.B. NOP) ist

Und wie springt man in der Mainloop mit einem "1-Zyklus-Befehl"
wieder an den Anfang?

Exakt die gleiche Interrupt-Response-Time gibt es meiner Meinung nach
(beim AVR) nur aus dem Sleep-Zustand.

...

Autor: Willi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hannes:
"Und wie springt man in der Mainloop mit einem "1-Zyklus-Befehl"
wieder an den Anfang?"

Dafür zu sorgen, daß der AVR zum Zeitpunkt des Timerinterrupts
gerade einen 1-Zyklus Befehl abarbeitet ist etwas tricky.
Vereinfacht erklärt:
Der Timer kann auf mehrere Arten einen Interupts auslösen.
einmal der Output Compare Interrupt (OCI) und einmal
der Overflow Interrupt (OVI).
Wenn du z.B. exact alle 50us einen bestimmten Befehl in deiner ISR
erreichen willst, dann setzt du erst mal den OCI als "Vor-Interrupt"
auf sagen wir mal 49us. Dieser Interrupt unterbricht das Hauptprogramm,
(der Timer läuft weiter). Die Interrupts werden wieder enabled und der
AVR wird in eine Kette aus NOPs geschickt, die dann bei 50us vom OVI
unterbrochen wird. Die zweite ISR muss dann Ihre Rückkehradresse vom
Stack poppen, damit später beim RETI die richtige Rückkehradresse
benutzt wird. Die erste ISR wird praktisch nie beendet.
Das Ganze ist eine ziemlich häßliche Zyklenzählerei beim Programmieren,
funktioniert aber tadellos. Wenn alles richtig läuft braucht du nur eine
Kette von drei NOPs.

So erhältst du eine konstante Timer-INT-Response-Time bei beliebigem
Hauptprogramm.

MfG Willi

Autor: Black Fist (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das werde ich gleich mal sehen.

Black Fist

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.