mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wieviel Code in den Interrupt?


Autor: Tine Schwerzel (tine)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Wie handhabt ihr die Programmierung der IR Routinen? Versucht Ihr nur 
Flags zu setzen oder Variablen zu ändern, die dann im Hauptprogramm 
aufgerufen und endverarbeitet werden, oder packt ihr schon größere 
Längen Code in den Interrupt? Oder unterscheidet sich das gar für die 
Art des IR (Timer, Capture)?
Vorteil von wenig Code im IR ist die schnelle Rückkehr ins Programm, und 
mögliche "Aufarbeitung" ansonsten verpasster IR's.
Das Problem ist dann natürlich, dass man im Hauptprogramm die Flags und 
Variablen pollen muss, was sinnlos Zyklen verheizt.
Viel Code im ISR dagegen spart zwar Zyklen, aber wenn im Hauptprogramm 
was zeitkritisches läuft (UART kommt rein...), könnte man da Probleme 
bekommen.
Irgendwelche Tipps oder Ansichten, oder frei nach soviel wie nötig und 
so wenig wie möglich?

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tine Schwerzel schrieb:
> Hallo,
>
> Wie handhabt ihr die Programmierung der IR Routinen? Versucht Ihr nur
> Flags zu setzen oder Variablen zu ändern, die dann im Hauptprogramm
> aufgerufen und endverarbeitet werden, oder packt ihr schon größere
> Längen Code in den Interrupt? ...

Hallo,

es gibt eine 3. Möglichkeit: nur minimale Bearbeitung (Daten holen, Flag 
rücksetzen usw.), dann aber nicht Rückkehr ins Hauptprogramm (oder was 
immer sonst gerade läuft), sondern in eine Fortsetzungsroutine der 
Interrupt-Bearbeitung.

Das setzt natürlich perfekte Kenntnis des Befehlsablaufs, des 
Stackaufbaus usw. voraus. Und da diese Routine mit niedrigerer Priorität 
läuft und selbst interrupted werden kann - das ist ja der Zweck der 
Sache - sollte man auch in threaded und concurrent programming fit sein. 
Im Prinzip nutzt man so verschachtelte Interrupts obwohl sie der 
Prozessor nicht kann. Die Fehlersuche kann recht schwierig werden.

Wenn der Prozessor nested interrupts kann, braucht man das nicht.

Gruss Reinhard

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich packe immer soviel Code wie möglich in die ISR. Die Obergrenze gibt 
die noch verfügbare Rechenzeit an. Wenn der Controller sonst nicht viel 
zu tun hat und dies auch nicht sonderlich Zeitkritisch ist kann die ISR 
ruhig etwas Voluminöser ausfallen.

Autor: Joerg Wolfram (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es bisher immer so gehandhabt, möglichst nur einen 
Timer-Interrupt zu benutzen. Das Hauptprogramm selbst agiert nur über 
Variablen im Speicher und "sieht" bestenfalls von der Hardware gar 
nichts. Wenn etwas für einen Timerzyklus zu lange dauert (z.B. 
Umwandlung von PS2-Tastatur nach ASCII), dann teile ich das über eine 
FSM auf mehrere Slots auf.
Um beim Beispiel PS2-Tastatur zu bleiben, das Hauptprogramm nutzt 
letztendlich nur den aktuellen Tastaturcode (oder 0 wenn keine Taste 
gedrückt ist), den letzten Tastaturcode (wird nicht auf 0 zurückgesetzt) 
und ein Byte mit dem Status der Shift-, Control- und Alternate-Tasten. 
Für eine mobile Anwendung lese ich dann z.B. Tasten an einem Port ein 
und schreibe die entsprechenden Codes (Pfeiltasten, ENTER, ESC). Dem 
Hauptprogramm ist es dabei letztendlich egal, woher die Daten kommen.

Ich kenne aber auch genug Leute in verschiedenen Foren , die so eine 
Herangehensweise für absolut grauselig halten, weil sie der "reinen 
Lehre von den minimalen Interruptroutinen" wiederspricht.

Jörg

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joerg Wolfram schrieb:
> weil sie der "reinen
> Lehre von den minimalen Interruptroutinen" wiederspricht.

Du solltest nicht so tun, als wäre das ein grundloses Dogma. Ich halte 
diesen Ansatz "Fasse dich kurz" - zumindest für meine Projekte - auf 
jeden Fall für richtig.

Ein Interrupt hat meist den Zweck, eine Aktion auszulösen, die 
einigermaßen eilig erledigt werden muss. Hätte ich alle Zeit der Welt, 
bräuchte ich keinen Interrupt. Dann würde es reichen, im Hauptprogramm 
das Flag bei Gelegenheit abzufragen.

Verschiedene Interrupts blockieren sich aber. ("NOBLOCK" widerspricht da 
meiner Vorstellung von "eilig") Deshalb sollte jede ISR den Controller 
möglichst schnell wieder frei geben.

Dein Beispiel mit der PS/2-Tastatur (vermutlich über USART 
angeschlossen) würde ich zum Beispiel so gestalten, dass die ISR die 
Scancodes entgegen nimmt und wie bei entsprechenden UART-Routinen erst 
einmal in einen Puffer schreibt. Nur das Vorkommen einer 
Unterbrecher-Taste würde ich noch detektieren und ein entsprechendes 
Flag setzen. Die Auswertung der Tasten (Shift usw.) würde erst die 
Routine übernehmen, die eine Taste zurück liefern soll.

Im Gegensatz zu dir nutze ich auch eher mehr Interrupts. Das ist sicher 
auch ein Grund, warum ich hier eine anderen Standpunkt habe.

Gruß, DetlevT

Autor: Zwölfliter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Möglichst wenig in der Interrupt-Routine ist bei einfache Behandlung 
ohne sei() Pflicht. Daraus kann man aber keine Regel machen.

Z.B. habe ich eine Firmware so aufgebaut, dass im Hauptprogramm nur der 
Bildspeicher vom Controller zum Display übertragen wird, und das ohne 
Pause in einer while(1)-Schleife. Das eigentliche Programm, bzw. seine 
verschiedenen Teile, werden von einem Timer-Interrupt, je nach 
Wichtigkeit, verschieden oft aufgerufen.

Mit dieser Methode ist garantiert, dass alles Wichtige im Timer 
abgearbeitet wird und das Display nur die wirkliche Freizeit verbraucht. 
Mann muss sich aber in nested Interruptus rein denken, denn der 
Timer-Interrupt unterbricht sich dabei selbst.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zwölfliter,

wir sollten vielleicht einmal klar stellen, was unter "ISR" zu verstehen 
ist, sonst reden wir aneinander vorbei. Ich verstehe unter einem ISR 
eine Routine, die Hardware (intern oder extern) möglichst zeitnah zu 
einem Ereignis ansteuern soll. Was du da beschreibst, nutzt den 
Interrupt als technisches Mittel, um ein Multi-Threading-System mit 
unterschiedlichen Prioritäten zu erzeugen. Das ist etwas ganz anderes 
als was ich mit da vorstelle. In solchen Fällen würde ich wohl eher auf 
ein entsprechendes (Pseudo-) RTOS zurückgreifen.

Gruß, DetlevT

Autor: Ferkel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Interruptroutine muß soviel erledigen, wie bis zum Eintreffen des 
nächsten Interrupts unbedingt erforderlich ist.

Bei einem Zyklus von 1ms reicht es aus, die Dekodierung von 
Tastatureingaben im weiterverarbeitenden Programmteil auszuführen, da 
höchstens alle 0,1s ein neues Ereignis auftritt UND ein verlorener 
Tastendruck nicht so schlimm ist; man drückt noch einmal.
Liefert eine Mechanik ein Ereignis, was gezählt werden und immer stimmen 
muß, gehört die Verarbeitung in den Interrupt.
Soll ferner ein Timer mit 1ms hochgezählt werden, muß dies in der 
Routine erfolgen. Das leuchtet ein :-)

Was nie in eine Interruptroutine gehört, sind Warteschleifen, die über 
wenige µs hinausgehen.

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ferkel schrieb:
> ...ein verlorener
> Tastendruck nicht so schlimm ist; man drückt noch einmal.

Solche Geräte kenne ich auch, und ärgere mich jedesmal. Das muss einfach 
nicht sein. Wenn für sowas keine Zeit übrig ist, hat der Entwickler was 
falsch gemacht.

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

pauschal kann man das nicht sagen:

Wenn ich nur einen einzigen Timer-Interrupt habe (z.B. DCF77-Uhr) dann 
ist fast der ganze Code im Interrupt (Multiplexen, Signalerfassung, 
Tastaturabfrage). Im Hauptprogramm ist dann nur noch der 1-Sekunden 
Tick. (Decodieren, Zeit hochzählen usw).

Wenn ich mehrehre zeitkritische Interrupts mit unvorhersehbaren 
Zeitabständen habe dann wird im Interrupt nur der erfaßte Wert in einen 
Ringpuffer gepackt oder ein Flag (Tastaturabfragetick, Sekundentick) 
fürs Hauptprogramm gesetzt. bei einem 16MHz AVR komme ich dann auf max. 
ca 60 Takte = 5us Interruptdauer.

Gruß Anja

Autor: Ferkel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Solche Geräte kenne ich auch, und ärgere mich jedesmal.

Natürlich, aber ich meinte mit diesem Beispiel die unerwartete, absolute 
Ausnahme, die nie auftreten wird. Falls doch, wäre es dennoch nicht 
schlimm.
Wenn der Endschalter eines Antriebes nicht erkannt wird, wäre dies 
fatal.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Interrupt und Multitasking. Das richtige Pollen von Flags 
verbrät keine nennenswerte CPU-Leistung.

MFG
Falk

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ferkel schrieb:
> Wenn der Endschalter eines Antriebes nicht erkannt wird, wäre dies
> fatal.

Klar, dafür würde ich noch gleichzeitig den Motorstrom überwachen, 
zusätzlich ein Zeitlimit per Timer setzen und wenn alles nichts hilft 
per Watchdog abschalten.

Das alles darf mich aber nicht daran hindern, das "Human-Interface" am 
Leben zu halten. Der Frustrierte am Not-Aus-Schalter kann mehr Mist 
bauen, als Du Dir vorstellen kannst.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hängt davon ab, ob die CPU Interruptprioritäten hat oder nicht.

Ohne Prioritätslevel behindern sich alle Interrupts gegenseitig. Dann 
müssen alle Interrutps zusammen weniger Zeit benötigen, als der 
schnellste Interrupt.
Hast Du z.B. einen Timerinterrupt alle 100µs auf einem AVR mit 16MHz, 
dann darf die Worst-Case Summe aller Interrupts max 1600 Zyklen 
betragen.

Bei MCs mit Prioritäten (z.B. 8051) kann man das deutlich entspannter 
angehen. Nur die Interrupts mit hoher Priorität müssen schnell genug 
sein.

Daneben sollte aber auch die Mainloop nicht zu stark verzögert werden. 
Z.B. ein Userinterface sollte schon alle <300ms zum Zug kommen.


Peter

Autor: Grolle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tine Schwerzel schrieb:
> Ansichten, oder frei nach soviel wie nötig und so wenig wie möglich?

Die Programmierin ist der Gott des Computers. Letzterer macht es so wie 
DU willst und es vorschreibst. Wichtig ist nur, dass DU am Ende sagen 
kannst: "Und sie sah, dass es gut war."

Wenn es zuverlässig wie gewünscht funktioniert, ist es ok. Im Glauben an 
das gute Programmieren brauchen wir keine Religionskriege.

Ich bin ein Fan davon, zu messen, wie lange so eine ISR dauert. Das kann 
über einen Pin geschehen, der am Anfang der ISR gesetzt und am Ende 
zurückgesetzt wird (dann mit Oskar o.ä. anzeigen), das kann über ein 
Flag gemacht werden, mit dem die ISR prüft, ob sie rekursiv aufgerufen 
wird, das kann man manchen, indem die ISR die Zeit für ihren eigenen 
Ablauf misst und den Maximalwert irgendwo abrufbar abspeichert. So kann 
man dann gut einschätzen, ob man eine flinke Gazelle oder einen unter 
dem eigenen Gewicht sich erdrückenden Saurier programmiert hat.

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grolle schrieb:
> Die Programmierin ist der Gott des Computers

Die Programmzeile "Es werde Licht" hat bisher noch kein Compiler 
angenommen - oder ist das nur bei mir so?

Autor: Grolle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus 2m5 schrieb:
> ist das nur bei mir so?

Du verstehst halt nicht, worum es hier geht, lässt nur mal wieder ein 
wenig Verspottung am Überlauf raus, und schreibst deswegen komplett OT.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Bei MCs mit Prioritäten (z.B. 8051) kann man das deutlich entspannter
> angehen. Nur die Interrupts mit hoher Priorität müssen schnell genug
> sein.

IMO verschiebt man das Problem damit aber nur. Denn wenn etwas nicht 
schnell sein muss, warum dann überhaupt ein Interrupt? Dann kann ich 
auch in der Hauptschleife nur das Flag pollen. Das sieht vielleicht 
nicht so elegant aus, erfüllt aber seinen Zweck.

Wichtiger als irgendwelche Hardware-Spezialitäten ist es wohl, am Anfang 
eine ordentliche Aufstellung der zeitlichen Anforderungen aufzustellen. 
Diesen Punkt überspringen viele aus Faulheit und versuchen dann erst am 
Ende, den Schaden zu beheben. Gute Planung sind nach meiner Erfahrung 
4/5 der Programmiererei.

Autor: Ferkel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Denn wenn etwas nicht
>schnell sein muss, warum dann überhaupt ein Interrupt?

Damit man nicht unnütz Zeit vergeudet, immer wieder ein Ereignis 
abzufragen und dennoch optimal schnell reagieren kann. Auch bei geringer 
Baudrate ist es besser, per RX-Interrupt einen Ringpuffer zu füllen, als 
dauernd das RXC-Bit zu pollen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus 2m5 schrieb:
> Grolle schrieb:
>> Die Programmierin ist der Gott des Computers
>
> Die Programmzeile "Es werde Licht" hat bisher noch kein Compiler
> angenommen - oder ist das nur bei mir so?

http://www.bible-reading.com/godpc.html

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tine Schwerzel schrieb:
> Wie handhabt ihr die Programmierung der IR Routinen? Versucht Ihr nur
> Flags zu setzen oder Variablen zu ändern, die dann im Hauptprogramm
> aufgerufen und endverarbeitet werden, oder packt ihr schon größere
> Längen Code in den Interrupt?

Es kommt nicht so sehr auf die Länge des Codes in der ISR an, sondern 
auf die Zeit, die der Code im Interrupt verbrät. Man kann durchaus 
größere Zustandsautomaten in der ISR programmieren. Wenn pro 
Interrupt-Durchlauf davon nur ein Bruchteil durchlaufen wird, ist alles 
im grünen Bereich.

Ich selbst habe für IRMP eine ellenlage ISR geschrieben - da würden sich 
bei einigen hier die Zehennägel hochkringeln. Tatsächlich wird aber pro 
Zustand...

 - Es bleibt "hell"
 - Es bleibt "dunkel"
 - Wechsel von "dunkel" auf "hell"
 - Wechsel von "hell" auf "dunkel"

nur immer ein Teil des Codes durchlaufen. Während der meisten Zeit 
(keine Taste an der IR-Fernbedienung gedrückt) ist die Durchlaufzeit 
sogar verschwindend gering. So kann ein 2 bis 3 kb großer Code durchaus 
auch in einer ISR vertretbar sein.

Daher halte ich die generelle Regel

    "Der Code in der ISR soll möglichst kurz sein"

für absurd und falsch. Eher könnte es heissen:

    "Eine ISR sollte möglichst schnell beendet werden"

Dies lässt sich durch intelligente Verarbeitung/Beschreibung von 
Zuständen (Flags) erreichen.

Gruß,

Frank

Autor: Juergen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Programmzeile "Es werde Licht" hat bisher noch kein Compiler
> angenommen - oder ist das nur bei mir so?

Du mußt das natürlich korrekt formulieren.
Oder hast du noch nie eine LED angesteuert?

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es hängt sehr von der Aufgabe ab. Gerde die Programme auf kleinen µCs 
sind sehr verschieden.  Wenn es nur darum geht ein Falg zu setzen, 
braucht man oft gar keine ISR mehr, das Flag kann man oft direkt aus der 
Hardware Auslesen.

Die Länge der ISR reicht von nur einen Pin toogeln bis zum Extremfall wo 
praktisch das ganze Programm in einer ISR steht, inclusive Wartezeiten 
im Sekundenbereich: das Hauptprogramm hat nur noch die Initialisierung 
und eine Endlosschleife, die den µC in den Stromsparmodus versetzt.

Die Regel die ISR kurz zu halten, ist vor allem ein erster Anhaltspunkt, 
vor allem für Anfänger.  Wenn man weiss was man macht, ist fast alles 
erlaubt, auch eine ISR nicht normal zu beenden, sonderen nach Korrektur 
des Stacks an eine bestimmte Stelle des Hauptprogramms zu springen. Wenn 
jemand anders das Programm verstehen soll, braucht es dann aber guter 
Kommentare und ggf. etwas länger.

Autor: Ralli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich keine IRQ-Prioritäten verteilen kann, darf jede ISR nur
genau so lange dauern, wie sie keine weitere ISRs behindert.

Der Rest ist doch nur Faustregel "Wie gehe ich als Anfänger ran".

Nutze ich einen µC für hardwarenahe Signalverarbeitung, kommt
manchmal raus, dass sich der Prozessor zu 99% seiner sinnvollen
Prozessortätigkeit in IRS-en betätigt...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juergen schrieb:
>> Die Programmzeile "Es werde Licht" hat bisher noch kein Compiler
>> angenommen - oder ist das nur bei mir so?
>
> Du mußt das natürlich korrekt formulieren.
> Oder hast du noch nie eine LED angesteuert?

LED0_DDR = 1;
LED0 = LED_ON;  // "Es werde Licht"

funktioniert bei mir einwandfrei.


Peter

Autor: Klaus 2m5 (klaus2m5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Juergen schrieb:
>>> Die Programmzeile "Es werde Licht" hat bisher noch kein Compiler
>>> angenommen - oder ist das nur bei mir so?
>>
>> Du mußt das natürlich korrekt formulieren.
>> Oder hast du noch nie eine LED angesteuert?

LED0_DDR = 1;
LED0 = LED_ON;  // "Es werde Licht"
>
> funktioniert bei mir einwandfrei.

Funktioniert das auch mit einer LED von der Größe einer Sonne? Ich muss 
in 7 Tagen mit allem fertig sein!

Autor: Daniel B. (dannyboy1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich unterscheide das immer noch art des iinteruppts. Bei timerinterupts 
pack ich einfach  so viel rein wie geht, ohne das der nächste overflow 
interupt oder so stört. Bei ADC und AC interupts ist das etwas 
kritischer. Da pack ich nur sehr wenig rein. und verarbeite die daten 
anschließend im hauptprogramm.

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.