Hallo zusammen, bei den STM32, die ich kenne, muss man am Anfang der von der On-Chip-Peripherie ausgelösten ISRs, z.B. Timer-ISRs, in Software ein Flag löschen - anonsten wird die ISR unmittelbar wieder ausgelöst. Ich habe noch keine (befriedigende) Erklärung für den Grund gefunden. Bei anderen MCUs, beispielsweise AVRs, ist es ja nicht so. Gibt es a) einen Anwendungsfall, wo dies als Feature vorteilhaft ist? Werden ISRs als Iterator-Funktionen möglichst effizient in do-while-Manier durchlaufen? b) hat es traditionelle Gründe? Auf der ersten XXX-Prozessoren war das die übliche Vorgehensweise. Damit haben die Prozessor-Entwickler zwei komplette Gatter eingespart. Aus Gewohnheit ist es gebleiben (vgl. A20-Gate)? c) Hst es einen anderen Grund für die Design-Entscheidung, dass das Flag in Software gelöscht werden muss?
:
Bearbeitet durch User
Walter T. schrieb: > Ich habe noch keine (befriedigende) Erklärung für den Grund gefunden. Automatisches Löschen der Interrupt-Flags ist einfacher, wenn der Interrupt-Controller unmittelbar im CPU-Kern integriert ist. Bei ARMs ist der Interrupt-Controller eine abgesetzte Peripherieeinheit, auch wenn die bei den Cortex-M zur Grundausstattung gehört. Bei den ARM7/9 hatte jeder MCU-Anbieter seine eigenen Brötchen gebacken. > Bei anderen MCUs, beispielsweise AVRs, ist es ja nicht so. Wie gross ist deine Übersicht über Prozessorfamilien? Es ist m.E. eher so, dass ein Verhalten wie bei den STM32 die Regel ist, nicht die Ausnahme, wenn man nicht nur gezielt auf vollintegrierte Microcontroller schaut.
:
Bearbeitet durch User
Bei den ARM muß man sogar 2 Flags löschen. Zuerst das Flag der Interruptquelle und dann das Flag des Interruptcontrollers. Durch die Auftrennung in einen separaten Interruptcontroller ist ein automatisches Löschen nicht mehr möglich.
(prx) A. K. schrieb: > Wie gross ist deine Übersicht über Prozessorfamilien? Gering. Ich kenne nur die zwei, mit denen ich Projekte gemacht habe und andere nur vom Hörensagen. Aber dass es bei den zweien, die ich kenne, unterschiedlich ist (um genau zu sein: Es ist ja schon bei einem der beiden unterschiedlich), bedeutet in erster Linie ja, dass es eine bewußte Design-Entscheidung und keine technische Notwendigkeit ist. (prx) A. K. schrieb: > Bei ARMs > ist der Interrupt-Controller eine abgesetzte Peripherieeinheit, Wobei interessant: Die "mitgelieferten" ISRs erwarten nicht, dass ein Flag gelöscht wird (SysTick, PendSV, Fault etc.)
:
Bearbeitet durch User
Walter T. schrieb: > Aber dass es bei den zweien, die ich kenne, unterschiedlich ist, > bedeutet in erster Linie ja, dass es eine bewußte Design-Entscheidung > und keine technische Notwendigkeit ist. Eine grosszügige Aussage bei so geringer Grundlage. ;-)
Walter T. schrieb: > Wobei interessant: Die "mitgelieferten" ISRs erwarten nicht, dass ein > Flag gelöscht wird (SysTick, PendSV, Fault etc.) Die genannten Exceptions haben einen Bezug zum Prozessorkern.
:
Bearbeitet durch User
(prx) A. K. schrieb: > Eine grosszügige Aussage bei so geringer Grundlage. ;-) Für diese Aussage würde es sogar ausreichen, nur einen zu kennen. Innerhalb des STM32F103C8T6 haben die von ARM bereitgestellten ISRs ein anderes Verhalten als die von der On-Chip-Peripherie bereitgestellten. Und das war entweder ein "Hoppla" oder eine bewußte Design-Entscheidung. Ich gehe erst einmal naiv von zweiterem aus.
Für mich ist die Begründung "Design Entscheidung" keine Begründung. Es ist ungefähr so aussagekräftig wie "aus technischen Gründen". Noch weniger Aussage hat eigentlich nur "Ist so." Ja - sie teilt die Menge der möglichen Aussagen zwischen "Hoppla" und "mit Absicht", aber die Menge der Designentscheidungen ist immer noch unüberschaubar.
:
Bearbeitet durch User
Der NVIC löscht seine Anforderung typ. bei Aufruf der ISR. Das Flag der Peripherie kann explizit oder auch durch Ansprechen eines peripheren Registers gelöscht werden. Beispielsweise das Lesen eines Capture-Registers bei einem Timer beim STM32. Walter T. schrieb: > Für mich ist die Begründung "Design Entscheidung" keine Begründung. Deine nächste Frage: "Warum ist die Banane krumm?"
m.n. schrieb: > Deine nächste Frage: "Warum ist die Banane krumm?" Das hat seit langer Zeit Armin von der Sendung mit der Maus geklärt und hängt mit dem Wachstum an der Staude zusammen. m.n. schrieb: > Der NVIC löscht seine Anforderung typ. bei Aufruf der ISR. Das Flag der > Peripherie kann explizit oder auch durch Ansprechen eines peripheren > Registers gelöscht werden. Das ist der Sachverhalt, den ich eingangs erwähnte. An dieser Stelle können wir jetzt weiter machen.
Walter T. schrieb: > An dieser Stelle können wir jetzt weiter machen. Nein. Nicht wir. Da du die Antwort "Design-Entscheidung "vorgibst und ausdrücklich nach der Begründung dieser Design-Entscheidung suchst, gibt es genau eine richtige Stelle für die Frage: den Designer. Technische Aspekte habe ich angedeutet: es geht um den Informationsaustausch zwischen zwischen Prozessorkern, Interrupt-Controller und Interrupt-Quelle. Bei den System-Exceptions ist die Interrupt-Quelle der Prozessorkern. Bei normalen Timern, Ports etc ist das nicht der Fall.
:
Bearbeitet durch User
Bei PICs gibt's z.B. nur effektiv 2 Interruptvektoren, bei vielen Familien sogar nur einen. Das Flag muss also gesetzt bleiben, damit der Programmierer mehrere Typen unterscheiden kann, so kann "eine" Int-Routine mehrere Funktionen nacheinander erledigen. Das hat historische Gründe, ganz am Anfang gab es nur einen (den Timer), und je mehr Peripherie reingebastelt wurde, desto mehr Flags kamen dazu, aber es gibt nunmal nur einen Vektor. Hätte man daran rumverschoben, wären die Codes nicht mehr binärkompatibel über die Familien, also die Krücke über die etlichen geODERten Flags.
Jens M. schrieb: > Bei PICs gibt's z.B. nur effektiv 2 Interruptvektoren, bei vielen > Familien sogar nur einen. > Das Flag muss also gesetzt bleiben, damit der Programmierer mehrere > Typen unterscheiden kann, so kann "eine" Int-Routine mehrere Funktionen > nacheinander erledigen. Oha. Das ergibt für mich einen völlig neuen Blickwinkel. Ich dachte, der "Interrupt Vector" hieße so, weil er mehrere Elemente enthält. Stattdessen heißt er also so, weil er eine Sprungrichtung und -Betrag enthält. "Interrupt Vector Table" ist also gar nicht doppelt gemoppelt. Jens M. schrieb: > also die Krücke über die etlichen > geODERten Flags. Das gibt es ja bei den STM32s auch - dass ich so die Interrupt-Quelle bestimmen kann, wenn ich die ISR für mehrere Interrupts nutze, war mir auch nicht bewußt. Danke! Das ergibt Sinn!
Jens M. schrieb: > Bei PICs gibt's z.B. nur effektiv 2 Interruptvektoren, bei vielen > Familien sogar nur einen. > Das Flag muss also gesetzt bleiben, damit der Programmierer mehrere > Typen unterscheiden kann, so kann "eine" Int-Routine mehrere Funktionen > nacheinander erledigen. Und dann gibt es Typen (z.B. Renesas RX), die für jedes Flag eine eigene ISR aufrufen. Und dann gibt es Peripherie, die beim Auslesen des Statusregisters alle Flags löscht. Und dann noch die Typen, die garkeine INTs haben ....
m.n. schrieb: > Und dann gibt es Peripherie, die beim Auslesen des Statusregisters alle > Flags löscht. Warum tun sie das?
m.n. schrieb: > Der NVIC löscht seine Anforderung typ. bei Aufruf der ISR. Das Flag der > Peripherie kann explizit oder auch durch Ansprechen eines peripheren Korrekt. Das "Pending" Bit in der NVIC der Cortex-M wird bei Interrupt-Entry automatisch gelöscht. (Das Active Bit hingegen gesetzt) Der Interrupt Service Request der Peripherie muss bei externen Peripherien fast immer durch irgendeine Interaktion mit der Peripherie gelöscht werden. Wenn die Peripherie beim Verlassen der ISR immer noch oder wieder ihren Interrupt-Request anzeigt wird der entsprechenden Vector sofort wieder auf Pending gesetzt und man landet direkt wieder im Handler. Das vereinfacht den Code an diversen Stellen erheblich, man braucht sich keine Gedanken über Interrupt Requests während der ISR zu machen. Es gibt auch Anwendungsfälle, in denen man in der ISR den Interrupt abschaltet und dann erst später im Task Kontext / Hauptschleife in die Interrupt Register der Peripherie reinschaut welche Ereignisse anstehen, die dürfen dann nicht automatisch gelöscht werden. (Gerade bei Ethernet oder ähnlich schnellen Schnittstellen will man sowas machen um gegen DoS Angriffe zu härten)
Walter T. schrieb: > m.n. schrieb: >> Und dann gibt es Peripherie, die beim Auslesen des Statusregisters alle >> Flags löscht. > > Warum tun sie das? Weil es dem Konstrukteur das Leben erleichtert. Umgang mit Interrupt-Flags ist ein heisses Eisen, denn es muss verhindert werden, dass ISR#1 durch ihren Umgang mit dem Flags-Register versehentlich INT#2 gleich mit löscht. Man kann das auch dadurch erledigen, indem man es immer so macht und der Programmierer gefälligst damit klar kommen soll.
Beitrag #6784971 wurde vom Autor gelöscht.
Walter T. schrieb: > Bei anderen MCUs, beispielsweise AVRs, ist es ja nicht so. Bei den meisten AVRs ist es zumindest bestimmten Interrupts auch so. Und bei den neueren (XMega-Erben) und den XMegas ist es sogar meist bis fast immer so.
c-hater schrieb: > Bei den meisten AVRs ist es zumindest bestimmten Interrupts auch so. Und > bei den neueren (XMega-Erben) und den XMegas ist es sogar meist bis fast > immer so. "Witzig" ist in diesem Zshg.: Selbst die Datenblätter des Herstellers versprechen hier bei den XMega-Erben teilweise die automatische Löschung der Interruptflags, aber die Hardware tut's nicht wirklich. Definitiv gilt das z.B. für SPIn und TCDn auf AVRxDyz.
Walter T. schrieb: > bei den STM32, die ich kenne, muss man am Anfang der von der > On-Chip-Peripherie ausgelösten ISRs, z.B. Timer-ISRs, in Software ein > Flag löschen - anonsten wird die ISR unmittelbar wieder ausgelöst. Muss nicht unbedingt am Anfang sein. Aber ganz am Ende als allerletzten Befehl kann Probleme auslösen. Die Notwendigkeit, Flags zu löschen besteht übrigens nicht bei allen Interrupts. Zum beispiel setzt die UART ihr Interrupt-Signal automatisch zurück, wenn du auf ihr Data Register zugreifst. > Ich habe noch keine (befriedigende) Erklärung für den Grund > gefunden. Bei anderen MCUs, beispielsweise AVRs, ist es ja nicht so. Das kommt daher, dass die STM32 in Schichten aufgebaut sind: Die betroffenen Interrupt-Signale durchlaufen -> Extendened Interrupt Conroller -> Interrupt Controller (NVIC) -> CPU Kern. Der NVIC gehört zur ARM CPU, er reagiert auf Pegel. Wenn eine Peripherie nur kurz ein Interrupt-Signal setzt und dann wieder zurück nimmt noch bevor die ISR angesprungen wurde, dann wird das Signal letztendlich ignoriert. Die ISR wird nicht ausgeführt. Drauf hat ST den Extendened Interrupt Conroller gesetzt, welcher zusätzliche Funktionen hinzu fügt, vor allem die Erkennung von Flanken. Bei einer steigenden (oder fallenden) Flanke des Interrupt-Signals setzt er ein Flipflop auf HIGH und das bleibt dann so, bis es von der Software zurück gesetzt wird. Der Extendened Interrupt Controller kann nicht wissen, ob und wann die ISR ausgeführt wurde, denn dazu müsste er in den CPU Kern oder zumindest in den NVIC integriert sein, was nicht der Fall ist. Tatsächlich handelt es sich beim Extendened Interrupt Controller die sogar von einem anderen hersteller (als ARM) kommt. Er kann auch nicht wissen, wenn du ein I/O Register gelesen hast, weil er auch damit keine direkte Verbindung hat. Bei AVR kommt hingegen alles aus einem Guss, so dass die Komponenten miteinander verbandelt sind. Das vereinfacht einiges.
(prx) A. K. schrieb: > Walter T. schrieb: >> m.n. schrieb: >>> Und dann gibt es Peripherie, die beim Auslesen des Statusregisters alle >>> Flags löscht. >> >> Warum tun sie das? > > Weil es dem Konstrukteur das Leben erleichtert. Teilweise auch dem Programmierer und teilweise kann auch die Geschwindigkeit erhöht werden. Sobald der Zugriff auf Peripherie-Register mit Wartezyklen verbunden ist, ist eine lokale Variable schneller zu modifizieren als ein erneut irgendwo in der Peripherie ein Flag ohne Seiteneffekt zu löschen. Beim Umgang mit diversen µCs mußte man sich ggf. darauf einstellen. Am besten gefallen hatte mir die Interruptverarbeitung bei Hitachi/Renesas Controllern der Serien H8 H8S RX, die zum Beispiel für eine UART vier Vektoren in der Tabelle für RX-fertig, RX-Fehler, TX-Puffer leer und TX-SR leer haben. Mit Aufruf der ISR war das betreffende Flag gelöscht und es mußte im Statusregister nicht nachgesehen werden, welche Quelle die ISR ausgelöst hat. (Beim AVR ist das ja ähnlich, wobei die Priorität starr vorgegeben ist.) Beim STM32 gibt es immer nur eine gemeinsame ISR, die alle Möglichkeiten "abklappern" muß.
Walter T. schrieb: > Wobei interessant: Die "mitgelieferten" ISRs erwarten nicht, dass ein > Flag gelöscht wird (SysTick, PendSV, Fault etc.) Weil der NVIC zum ARM Kern gehört. Die beiden können sich direkt Signale schicken. Walter T. schrieb: > Für mich ist die Begründung "Design Entscheidung" keine Begründung. Dann musst du bei ST nachfragen und hoffen, dass sie sich dir gegenüber für ihre Entscheidungen vor 20 Jahren rechtfertigen. Viel Glück. Walter T. schrieb: >> Und dann gibt es Peripherie, die beim Auslesen des >> Statusregisters alle Flags löscht. > Warum tun sie das? Weil das eine Designentscheidung war. SCNR Es bringt halt ein kleines bisschen Geschwindigkeit.
c-hater schrieb: > Selbst die Datenblätter des Herstellers > versprechen hier bei den XMega-Erben teilweise die automatische Löschung > der Interruptflags, aber die Hardware tut's nicht wirklich. Zweifelhafte Manuals und Application Notes hatten manchen Leuten die auf ARM7 aufgebauten LP2000 verleidet, ebenso den STM9. Das Interrupt-System der alten 32-Bit ARMs war von Anfang an eine Fehlkonstruktion, ganz besonders wenn man priorisierte und verschachtelte Interrupts verwendete. Dazu kam ARMs löchrig dokumentierter Interrupt-Controller, der wichtige Fragen offen lies - auch eine AN genau dazu ändert das nicht wirklich. Das gesamte und recht komplexe Interrupt-System der Cortex-M, sowohl in der CPU also auch beim NVIC, ist eine Reaktion auf die Fehler davor, und eine gute.
:
Bearbeitet durch User
Walter T. schrieb: > "Interrupt Vector" hieße so, weil er mehrere Elemente enthält. > Stattdessen heißt er also so, weil er eine Sprungrichtung und -Betrag > enthält. "Interrupt Vector Table" ist also gar nicht doppelt gemoppelt. C++-Only-Schwachmat. Klarer kann man sich selber garnicht definieren!
c-hater schrieb: > C++-Only-Schwachmat. Klarer kann man sich selber garnicht definieren! Merkst du nicht, was dieser Müll über dich aussagt?
Stefan ⛄ F. schrieb: > Merkst du nicht, was dieser Müll über dich aussagt? Merkst du nicht, das dieser "Müll" kein Müll ist? Sondern vielmehr einer Inkarnation des Problems der Kampfameise in Lauerstellung: ihr Horizont ist einfach zu eng, um den Begriff "Vector" anders zu sehen und zu begreifen als in dem einzigen Zusammenhang, in dem er dieser dumme Kampfameise bisher begegnet ist...
c-hater schrieb: >> "Interrupt Vector" hieße so, weil er mehrere Elemente enthält. >> Stattdessen heißt er also so, weil er eine Sprungrichtung und -Betrag >> enthält. "Interrupt Vector Table" ist also gar nicht doppelt gemoppelt. > > C++-Only-Schwachmat. Klarer kann man sich selber garnicht definieren! Dass der Begriff "Vektor" überhaupt nicht aus C++ stammt, sondern in der Informatik schon lange vorher auch für eindimensionale Arrays verwendet wird, ist dir in deinem Hass wohl entgangen. Und damit hatte er völlig unabhängig von C++ beide Vorstellungen zu Auswahl: Die eben erwähnte und die geometrische. Und hatte das Pech, dass Interrupt-Vektoren geometrisch inspiriert sind. Man könnte sagen, dass es sich um einen Vektor aus Vektoren handelt, um beide Varianten zu kombinieren. ;-)
:
Bearbeitet durch User
c-hater schrieb: > C++-Only-Schwachmat. Ein wenig hat das etwas von der Filmfigur des Bible Belt Farmers, der nachts Außerirdische sieht und mit "Verdammte Kommunisten!" anbrüllt. Dass es noch mehr in der Welt gibt als Patrioten und Kommunisten, entfällt komplett seinem kleinen Weltbild. So langsam dämmert mir, dass "C-Hater" sich gar nicht auf die Programmiersprache bezieht, sondern nur die Posten "alpha-hater" und "beta-hater" schon vergeben waren. Unterm Strich ist der Thread ja doch noch ganz lehrreich geworden zu sein.
(prx) A. K. schrieb: > Dass der Begriff Vektor überhaupt nicht aus C++ stammt, sondern in der > Informatik schon lange vorher für ein eindimensionales Array stand, ist > dir in deinem Hass wohl entgangen. Doch, das ist mir (und vielen anderen) offensichtlich entgangen. Insbesondere allen, die wissen, was sie tun. Nein, ein "Vektor" ist nur in C++ (std::vector) definitiv ein eindimensionales Array. In vielen anderen Zusammenhängen kann es auch was anderes sein. Z.B. im Fall von Interruptvektoren. Da ist es typisch entweder einfach nur ein Zeiger an einer bestimmten Stelle im Speicher oder sogar nur eine bestimmte Stelle im Speicher. Je nach Hardware. Das eindimensionale Array ergibt sich bestenfalls aus der Tatsache, dass die Interruptvektoren (man beachte hier die Mehrzahl!) meist in Form einer Tabelle organisiert sind. Da wird erst diese Tabelle im Sinne von C++ zu einem "vector", aber nicht der einzelne Interrupt-Vector. Sinnvollerweise haben allerdings alle C++-Hasser (und alle Leute, die C++ überhaupt noch nicht kannten) überhaupt keine Rücksicht auf die Befindlichkeiten gehirnamputierter C++-Anbeter genommen. D.h.: sie haben den Begriff "vector" im mathematischen Sinne verwendet. Du kannst gerne nachschlagen, was z.B. Wikipedia dazu meint, was ein Vector ist... Falls du es allein nicht herausbekommst: Nein, das ist NICHT was C++ darunter versteht.
c-hater schrieb: > Nein, ein "Vektor" ist nur in C++ (std::vector) definitiv ein > eindimensionales Array. Bereits im Kontext von APL, einer sehr mathematisch inspirierten Programmiersprache aus den 60ern, wird dieser Begriff routinemässig für eindimensionale Arrays verwendet. Ebenso wie Matrix für zweidimensionale.
Walter T. schrieb: > sondern nur die Posten "alpha-hater" und > "beta-hater" schon vergeben waren Seit Corona sollte man doch wissen, dass er dann Gamma-Hater hiesse.
(prx) A. K. schrieb: > Bereits im Kontext von APL, einer sehr mathematisch inspirierten > Programmiersprache aus den 60ern, wird dieser Begriff routinemässig für > eindimensionale Arrays verwendet. Ebenso wie Matrix für > zweidimensionale. So what? Gibt es halt noch andere bescheuerte Programmiersprachen ausser C++. Was soll das beweisen?
c-hater schrieb: > Was soll das beweisen? Dass diese Aussage Unfug ist: c-hater schrieb: > Nein, ein "Vektor" ist nur in C++ (std::vector) definitiv ein > eindimensionales Array. Hervorhebung von mir.
(prx) A. K. schrieb: > Walter T. schrieb: >> sondern nur die Posten "alpha-hater" und >> "beta-hater" schon vergeben waren > > Seit Corona sollte man doch wissen, dass er dann Gamma-Hater hiesse. Ich halte ihn für älter. Wahrscheinlich ist der Name noch aus dem UseNet. Vor Unicode.
:
Bearbeitet durch User
c-hater schrieb: > Gibt es halt noch andere bescheuerte Programmiersprachen ausser C++. Ich hatte nicht wirklich erwartet, dass du APL in dein Herz schliessen willst, ist diese Sprache doch geradezu ein Gegenpol von Assembler. Wenngleich dir die Strukturierung von Programmen in APLv1 gefallen könnte. Aber auch bei FORTRAN sind die Begriffe Vektor und Matrix in analoger Weise verbreitet.
:
Bearbeitet durch User
Der mathematische Ursprung dieses Vektorbegriffs findet sich beispielsweise im Spaltenvektor und Koordinatenvektor.
(prx) A. K. schrieb: > Zweifelhafte Manuals und Application Notes hatten manchen Leuten die auf > ARM7 aufgebauten LP2000 verleidet Ja, die ARM7TDMI von NXP hatten diese lustigen Spurious Interrupts. Es hat ne Weile gebraucht, bis ich herausgefunden hatte, daß man sie einfach ignorieren kann, d.h. sofort verlassen. Ein echter Interrupt wird danach ja wieder aufgerufen. Es geht also kein Ereignis verloren, nur etwas CPU-Zeit.
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.