Hallo Da ich ein ziemlicher Neuling bin was die Programmierung von Microkontrollern(ARM Cortex M3) angeht hab ich mich folgendes gefragt: Was genau ist ein Nested Vectored Interrupt Controller, wofür ist er zuständig, wofür genau benötige ich ihn und was ist das besondere an ihm? Ich habe mir die Beschreibung auf Wikipedia und hier schon durchgelesen finde aber auf diese Fragen keine konkreten Antworten. MfG neuling
Wenn du schon weisst, was ein Interrupt ist, dann: "The Definitive Guide to the Arm Cortex-M3" von Joseph Yiu.
Datenblatt (bei st gibt es drei davon) lesen ist auch sehr hilfreich...
Wenn du vorher z.B. mit AVR programmiert hast, ist es schon ein riesengroßer Unterschied. Beim AVR wird in einer ISR (üblicherweise) als erstes cli() aufgerufen und als letztes sei(). Damit kann man dann sicher sein, daß innerhalb einer laufenden ISR keine weitere ISR dazwischenhaun kann. Das hat man als AVR-Nutzer schnell und tief verinnerlicht, da es das Programmieren (besonders der ISRen) deutlich vereinfacht. Der NVIC mit seinem ersten Buchstaben haut allerdings (üblicherweise) jederzeit (proritätenabhängig) dazwischen. Da muß man schon enorm mehr beim Programmieren berücksichtigen, besonders wenn man es ganz anders gewohnt war/ist. Bin ich am Anfang auch schön mit auf die Schnauze gefallen, zumal Interruptprogrammierung (z.B. bei EXTIs) meistens nicht so schön reproduzierbar ist.
Lutz schrieb: > Beim AVR wird in einer ISR (üblicherweise) als > erstes cli() aufgerufen und als letztes sei(). Quark. Das macht die Hardware selbst. sei() unmittelbar am Ende der ISR hat sogar die gegenteilige Wirkung und kann zum Stack-Overflow führen. > Damit kann man dann > sicher sein, daß innerhalb einer laufenden ISR keine weitere ISR > dazwischenhaun kann. Was beim NVIC nicht wesentlich anders ist, bezogen auf Interrups gleicher oder geringerer Priorität.
A. K. schrieb: >> Beim AVR wird in einer ISR (üblicherweise) als >> erstes cli() aufgerufen und als letztes sei(). > > Quark. Das macht die Hardware selbst. sei() unmittelbar am Ende der ISR > hat sogar die gegenteilige Wirkung und kann zum Stack-Overflow führen. Nun hätte ich ja geschworen, daß das mal anders war? Schön zu Fuß SREG sichern, cli(), wasauchimmer, SREG zurück (und damit den Status des I). Pauschal sei() am Ende ist natütlich quatsch; haste recht. Die avr-libc hat das ja irgendwann auch so gemacht (meine ich zumindest). Hat Atmel das mal geändert? A. K. schrieb: >> Damit kann man dann >> sicher sein, daß innerhalb einer laufenden ISR keine weitere ISR >> dazwischenhaun kann. > > Was beim NVIC nicht wesentlich anders ist, bezogen auf Interrups > gleicher oder geringerer Priorität. Genau deshalb schrieb ich Lutz schrieb: > Der NVIC mit seinem ersten Buchstaben haut allerdings (üblicherweise) > jederzeit (proritätenabhängig) dazwischen. Wobei im NVIC allerdings die Prioritäten (neben der defaultpriorisierung) einstellbar sind, was man dann ja auch gerne tut. Und genau das kann dann noch zu weiteren Quereffekten führen, die man berücksichtigen muß.
Lutz schrieb: > Nun hätte ich ja geschworen, daß das mal anders war? Schön zu Fuß SREG > sichern, cli(), wasauchimmer, SREG zurück (und damit den Status des I). > Pauschal sei() am Ende ist natütlich quatsch; haste recht. Die avr-libc > hat das ja irgendwann auch so gemacht (meine ich zumindest). Hat Atmel > das mal geändert? Nein, das war schon immer so, bereits beim wohl ersten AVR, dem AT90S1200. Bereits der Aufruf des Handlers schaltet mit dem I Flag die Interrupts ab und der Return-From-Interrupt Befehl schaltet sie mit dem I Flag wieder ein. SREG muss gesichert werden, wenn der Handler selbst irgendwelche Flags verändert. Nicht aber wegen des I Flags. Das I Flag des in einer ISR gesicherten SREG enthält aufgrund des beschriebenen Verhaltens eine 0 und entspricht daher nicht dem SREG des unterbrochenen Codes. Möglicherweise verwechselst du das mit anderen Prozessoren, die bei einem Interrupt automatisch das ursprüngliche Statusregister sichern und bei denen der Return den vorherigen Zustand der Interruptsteuerung über ebendiese Verarbeitung des Statusregisters beim Return wiederherstellt. So ist es meistens. AVR ist da etwas exotisch.
Lutz schrieb: > Beim AVR wird in einer ISR (üblicherweise) als > erstes cli() aufgerufen und als letztes sei(). Quark mit Soße. Sieht man allerdings bei Anfängern öfters. Irgendwie scheint man sich immer nur die Fehler von anderen abzugucken. Lutz schrieb: > Der NVIC mit seinem ersten Buchstaben haut allerdings (üblicherweise) > jederzeit (proritätenabhängig) dazwischen. Nö. Prioritäten würfelt man ja nicht aus, sondern vergibt sie mit Absicht. D.h. man benötigt es, daß ein schneller Interrupt einen langsamen unterbrechen soll. Und nur dann programmiert man es so. Ich habe das schon öfter beim AVR vermißt. Man muß deshalb erhebliche Klimmzüge beim Programmieren machen. Sogar der uralte 8051 konnte das schon besser (2/4 Prioritäten). Warum dieser Rückschritt beim AVR gemacht wurde, ist mir unverständlich. Das NVIC ist allerdings deutlich komplexer als die Interruptlogik beim 8051. Beim 8051 konnte man auch die Priorität auch innerhalb des Interrupts hochsetzen. Ich hab das mal für einen Frequenzmesser benötigt. Ob das NVIC auch solche Tricks erlaubt, weiß ich nicht. Peter
Peter Dannegger schrieb: > Beim 8051 konnte man auch die Priorität auch innerhalb des Interrupts > hochsetzen. Ich hab das mal für einen Frequenzmesser benötigt. > Ob das NVIC auch solche Tricks erlaubt, weiß ich nicht. Da man mit BASEPRI die aktuell vom NVIC ausgewertete Priorität gezielt hochsetzen kann ist das kein Problem. Interessant scheint mir aber auch der umgekehrte Fall. Man teilt Interrupt-Handler in einen kurzen eiligen und einen längeren weniger eiligen Teil auf. Der eilige läuft mit hoher Prio sofort, triggert abschliessend den weniger eiligen Teil, der auf niedrige Prio konfiguriert ist und beendet sich. Der weniger eilige Teil behindert so keine wichtigeren Handler und wird dennoch alsbald ausgeführt. Die AVR-Regel, im Handler nur das Allernotwendigste zu tun und ansonsten ein Flags zu setzen, das in der Mainloop gepollt wird, darf in diesem Top/Bottom-Half Schema durchbrochen werden.
Peter Dannegger schrieb: > Lutz schrieb: >> Beim AVR wird in einer ISR (üblicherweise) als >> erstes cli() aufgerufen und als letztes sei(). > > Quark mit Soße. Sieht man allerdings bei Anfängern öfters. > Irgendwie scheint man sich immer nur die Fehler von anderen abzugucken. Das mit dem falschen sei() hatten wir ja schon geklärt. Peter Dannegger schrieb: > Lutz schrieb: >> Der NVIC mit seinem ersten Buchstaben haut allerdings (üblicherweise) >> jederzeit (proritätenabhängig) dazwischen. > > Nö. > Prioritäten würfelt man ja nicht aus, sondern vergibt sie mit Absicht. > D.h. man benötigt es, daß ein schneller Interrupt einen langsamen > unterbrechen soll. Und nur dann programmiert man es so. 1.) Was ist an der Aussage falsch? 2.) Na klar, wenn man alles richtig macht, kann man per Definition auch keinen Fehler machen. Mit der Betrachtungsweise kann man so ziemlich jede Diskussion abwürgen. Nur steigt mit der Zahl der Stellschrauben auch die Wahrscheinlichkeit, etwas falsch zu machen. Und gerade Interrupts bieten sich dazu an. Und das ganz besonders, wenn das ganze Interruptkonstrukt auch noch anders funktioniert, als man es verinnerlicht hat. Gerade beim Interruptkonzept ist der Unterschied zum AVR enorm und der NVIC ist weitaus komplexer und hat viel mehr Möglichekiten, als man auf den ersten oder sogar zweiten Blick erkennt. Da ist letztendlich fast die Phantasie des Programmierers der limitierende Faktor. Vorgenanntes Beispiel mit dynamischer Priorisierung veranschaulicht das ganz gut. Beim AVR läuft die ISR durch und Ende. Es sei denn, man ist so verwegen, und zündet zwischendrin mit sei() die Lunte an. Na klar, wenn man weiß, was man macht ... So kann man beim AVR sicher sein, daß eine autonome Peripherie (z.B. Timer) in der ISR nur das macht, was vorher schon eingestellt war oder in dieser ISR geändert wird. Schön einfacher, linearer Gedankengang. Der NVIC kann da aber, je nach Einstellung, zwischenhaun. Und aus der Traum. Beispiel: Man nutzt in einer ISR einen Timer. Sofern da nicht vorher schon was eingestellt war, können nur meine Änderungen in der ISR was verändern. Kommt nun aber ein höher priorisierter Interrupt dazwischen, der über weißnichwas für Umwege auch diesen Timer beeinflußt, ist schon Essig. Und diese möglichen Querbeziehungen werden schnell sehr komplex und natürlich wird da ein vernüftiges Softwaredesign viel wichtiger als beim AVR. Insofern ist es natürlich richtig, daß Prios nicht ausgewürfelt werden. Übrigens stimme ich der Aussage > D.h. man benötigt es, daß ein schneller Interrupt einen langsamen > unterbrechen soll. Und nur dann programmiert man es so. so nicht zu. Die Dauer einer ISR ist ein wichtiges Kriterium für die Prioritätenvergabe, die Bedeutung des Prozesses aber eine weitere, mindestens genauso wichtige. Beides zusammen muß zur Bestimmung der Priorität herangezogen werden. Keine Ahnung: Eine 3 Sekunde lange shutdown-ISR für Notfälle würde ich nun kaum von einer banalen 1 ms "I'm still alive"-ISR unterbrechen lassen.
Lutz schrieb: > Übrigens stimme ich der Aussage >> D.h. man benötigt es, daß ein schneller Interrupt einen langsamen >> unterbrechen soll. Und nur dann programmiert man es so. > so nicht zu. Wenn man "schnell" im Sinn von "eilig" interpretiert, also auf die Latenz statt auf die Dauer bezieht, dann wird ein Schuh draus. Der NVIC ist allerdings schon so ein Gerät, dessentwegen ich Neulingen eher AVR als z.B. STM32 nahelege.
Lutz schrieb: > Keine Ahnung: Eine 3 Sekunde lange > shutdown-ISR für Notfälle würde ich nun kaum von einer banalen 1 ms "I'm > still alive"-ISR unterbrechen lassen. Wenn aus Ausbleiben der 1ms ISR nach 3ms dazu führt, dass der Wachhund zubeisst, dann wärs besser wenn doch. ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.