Hallo ARM-Gemeinde, im Laufe der Woche gab es im Thread Beitrag "Interrupts" eine Frage zum Compiler-Umstieg bei Keil von komfortablen CARM (der im Dezember 2005 von Keil eingestellt wurde) auf RealView für ARM (der neue bei Keil, von ARM übernommen, Keil hat sich Ende 2005 bei ARM eingekauft bzw. wurde von ARM gekauft), der ab diesem Zeitpunkt unter Keil µVision verwendet wird. Dort hatte ich eine Lösung gepostet, wie man die Nested-Interrupt-Technik unter RealView weiterhin anwenden kann, da unter RealView die Inline-Assembler-Makros aus den bekannten Hitex-Examples zum Umschalten nicht mehr funktionieren. RealView verhindert zuverlässig den Zugriff auf die dafür wichtigen Register R13 (SP), R14 (LR) und R15 (PC) aus C-Sourcefiles, auch unter Inline-Assembler. Unter RealView geht sowas nur noch in reiner Assemblerprogrammierung in so genanntem Embedded Assembler. Aber, das ist nicht mehr das Problem, da gelöst. Diese Sache betrifft also nach wie vor anscheinend nicht nur mich, der bereits ein Software-Projekt in tagelanger Arbeit von CARM nach RealView umgebaut hat. Bis heute habe ich im Internet keine Ersatzlösung für die Makros gefunden, und bin nach einigen Überlegungen darauf gekommen, diese letztendlich in Assembler selbst zu schreiben. Dazu habe ich die Makros genommen und sie zu Funktionen umgebaut, die natürlich nicht mehr ganz so komfortabel sind wie die Makros, da sie zwangsläufig etwas mehr Code und Laufzeit haben (Funktionsaufruf, zusätzliche Verwendung und Sicherung eines Registers, denn die Returnadresse der Funktionen muß über die Prozessor-Mode-Umschaltung hinweg erhalten bleiben). Das Assembler-File ist hier direkt downloadbar und in die µVision einbindbar, damit die Funktionen aus einem Interrupt heraus sofort aufrufbar. Eingesetzt in das Nested Interrupt Example von Hitex, funktioniert das auf meinem Keil-Demo-Board MCB2100 wunderbar. Wer möchte mit mir mal verifizieren, ob das alles so in Ordnung ist? Und, wie weit arbeitet der VIC-Controller in den LPC21xx und LPC22xx (PL190 von ARM) mit Nested Interrupts zusammen? Hat mal jemand einen Interrupt-Prioritäts-Handler in Software geschrieben, der verschiedene Interrupt-Prioritäts-Ebenen behandeln kann, wie sie in anderen Mikrocontrollern als Hardware (z.B. 80C515, 80C517, C166) implementiert sind? Wenn nicht, weiß noch jemand ein gutes ARM-Forum auch für ARM7, außer 'YAHOO LPC2000' oder 'Keil'? Gruß Dietmar
@Webmaster: Um einen Thread im ARM-Forum zu eröffnen, bedarf es wohl einiger schwerer Klimmzüge. Da landet so vieles nicht, oder mit anderen Worten, verschwindet vieles, was für die ARM-User interessant wäre. So bin ich auch erst nach 3 Fehlversuchen mit meinem Thread im ARM-Forum gelandet, in dem ich zufällig mal mit ARM-sensitiven Worten im Betreff herum gespielt habe. Wie kommt man auf solche Idee? Nach einigen Überlegungen: Reiner Zufall! Wie kann ich ahnen, daß im "Betreff" irgend ein (und dann auch noch welcher???) ARM-spezifischer Ausdruck vorkommen muß? Der Thread von Wolfgang ("Interrupt") mit der Nested Interrupt Technik, der für die ARM-User enorm wichtig sein kann, ist im allgemeinen Forum mittlerweile auf Seite 5 "versackt". Das interessiert dort kein Schwein mehr. Möglicherweise hatte der, ebenso wie ich, auch versucht, seinen Thread im ARM-Forum zu posten. Hier gibt es sicher noch Verbesserungs-Potential. Z.B., daß, wenn man aus dem ARM-Forum "Neuer Beitrag" anklickt, man denn auch dort an der richtigen Stelle postet. Gruß Dietmar
- Was mit "ARM-Forum" gemeint ist, ist mir immer noch nicht klar. - Im Forum gehen Beiträge realtiv schnell unter, zur Wissenssammlung bietet sich das Wiki ("Aritkel") an. - weitere Foren: en.mikrocontroller.net, devkitarm-users, gnuarm yahoo-Gruppe, Codesourcery. Was ist bei den von NXP für LPC23xx/24xx und LPC213x/4x bereitgestellten Beispielen falsch/unzulänglich, in denen die Verwendung von interrupt-nesting mit dem RealView compiler demonstriert wird? Ich habe den Code zwar nicht selbst ausprobiert, sondern nur als Vorlage für gcc-Portierungen genutzt, aber entsprechende Makros in inline-Assembler für RV ähnlich denen bei einigen älterne CKARM Beispielen sind dort enthalten inkl. ein wenig erläuterndem Kommentar zum Unterscheid CKARM/RV. Das eigentliche "Nesting" hat meines Wissens nichts mit dem Interrupt-Controller direkt zu tun, sondern mit der Funktionalität des Cores. Verwaltung der Prioritäten ist meines Wissens Aufgabe des Interrupt-Controllers (VIC 190/192, AIC etc.). Bin selbst dazu übergegangen, für die allermeisten ARM Entwicklungen einen Assembler-Wrapper für IRQ-Exceptions zu nutzen, bei dem immer "genestet" wird. Die Vorgehensweise spart einiges an Bastelei beim Portieren von Code (keine herstellerspezifischen Erweiterungen wie __irq, inline-assembler etc. im C-Quellcode), verschwendet allerdings ein paar Zyklen, da der Wrapper immer genutzt wird, auch dann wenn man nesting nicht braucht. Zur Not bleibt für kritische Interrupts noch "FIQ". Martin Thomas
Nested Interrupts sind ja schon aufm AVR sauschwer und gefährlich. Du hast Doch 2 Interruptprioritäten, damit sollte man meist auskommen. Oder nimm nen 8051, der hat 4 :) Die ARM7 von ST haben 17 Interruptprioritäten, das sollte ja dicke reichen. Die 35 Seiten dazu im Datasheet sehen allerdings auch nicht gerade einfach aus. Peter P.S.: Die einzige sichere Methode für Interruptprioritäten auf dem AVR, die ich gefunden hab, ist einen Timerinterrupt dazu zu mißbrauchen. Der arbeitet dann quasi als Scheduler aller niederpriorisierter Interruptquellen. Und er stopt sich zuerst selbst, damit er sich nicht selber unterbrechen kann.
@mthomas: >- Was mit "ARM-Forum" gemeint ist, ist mir immer noch nicht klar. Na, hier, die Abteilung, wo wir uns gerade befinden, in der sich nur ARM-spezifische Themen befinden. Es wird ja nach ARM, 8051, PIC, usw. sondiert. Da kann man anscheinend nur dann einen Thread eröffnen, wenn im Betreff ein ARM-sensitives Wort vorkommt. Z.B. "ARM und_das_Thema", siehe Betreff dieses Threads. Nach Betreff, landet der Thread dann dort, wo er hin gehört, nämlich hier. Eine andere Auswahl habe ich nicht gefunden. >Was ist bei den von NXP für LPC23xx/24xx und LPC213x/4x bereitgestellten >Beispielen falsch/unzulänglich, in denen die Verwendung von >interrupt-nesting mit dem RealView compiler demonstriert wird? Ist das jetzt dein Ernst? >mit dem RealView compiler ??? Dem widerspreche ich jetzt: Die Beispiele (Assembler-Inline-Makros) stammen noch aus der Zeit vor RealView, und funktionieren unter RealView eben nicht mehr. Sorry, nach LPC23xx/24xx habe ich noch nicht gesucht, da ich damit nichts zu tun habe. Wenn es da neue Beispiele für RealView gibt: Wo finde ich denn die? Die alten Beispiele (Makros aus 4 Zeilen) kenne ich hinlänglich, siehe meine Beschreibung oben. Aus dem RealView Compiler Manual geht eindeutig hervor, daß der Zugriff auf bestimmte Register aus C-Sourcen nicht mehr funktioniert. Und die Makros funktionieren tatsächlich nicht mehr. Der Compiler macht keine Fehlermeldung an der Stelle, er macht einfach nichts. Darum, meine Frage, und den Aufwand, neue Embedded Assembler Funktionen zu schreiben (die weiter oben downloadbar sind). Gruß Dietmar
>Na, hier, die Abteilung, wo wir uns gerade befinden...
Was du meinst, ist nur ein Filter für die Betreffzeile,
der auf bestimmte Keywords anspricht. Guck doch mal oben
rechts das Suchfeld an...
@Peter: >Nested Interrupts sind ja schon aufm AVR sauschwer und gefährlich. AVR, das ist doch gar kein ARM, noch nicht mal ähnlich, oder? Natürlich weiß ich, was ich tue. Immerhin, ist "Nested Interrupt" in der ARM-Familie ein etablierter Begriff. Es sollte damit möglich sein, sich jede erdenkliche Interrupt-Konfiguration, wenn man sie denn braucht, in Software selbst zu schreiben. Das ist die Grund-Idee, ist flexibler als eine fest eingegossene Hardware-Interrupt-Logik (wenn möglicherweise auch etwas langsamer). >Die ARM7 von ST haben 17 Interruptprioritäten... Nee, das ist ja eine völlig andere Familie, obwohl ARM. Ein Umstieg von LPC zu ST ist wiederum ebenso aufwändig wie der Umstieg von 8051 zu LPC, wegen der völlig verschiedenen Peripherie. Die einzige Gemeinsamkeit ist nur die core-nahe Programmierung, wie eben die Nested Interrupts. Wir haben uns auf LPC festgelegt, weil die zuerst da waren und auch eine höhere CPU-Frequenz boten. Der 8051 ist auch keine Lösung, da wir aus Performance-Gründen von dieser Familie auf ARM umgestiegen sind. Die Interrupt-Verarbeitung funktioniert ja auch sehr gut auf 2 Prioritätsleveln, damit kommen wir aus. Über ARM und 8051 zu diskutieren ist müßig: Ein SiLabs 8051 mit 100 MHz konnte dem ARM mit 60 MHz bei weitem nicht das Wasser reichen: Es ist nicht nur der 8-Bit- zu 32-Bit- Vergleich, auch der ARM-Befehlssatz ist zu mächtig. Ich überlege gelegentlich nur nach verbesserten Lösungen, das ist alles, die festgelegte Abarbeitungsreihenfolge des VIC-Controllers nochmals zu beeinflussen, ohne während der Laufzeit z.B. ständig den VIC-Controller neu programmieren zu müssen. Sowas sollte man ohnehin unterlassen, da Verlust an Überblick. Man möchte womöglich einen FIQ ersetzen, ihn mit der Nested Interrupt Technik auch als IRQ mit maximaler Priorität konfigurieren, der immer andere IRQ durchbricht, was ja normalerweise nicht geht. Gruß Dietmar
@ARM-Fan: Welches Suchfeld? Was soll mir das jetzt bedeuten? Gruß Dietmar
Es gibt zwei recht verschiedene Ansätze, Interrupt-Routinen in ARM zu implementieren. Der hier zunächst beschrieben Ansatz verwendet hoch compilerspezifische Makros (oder eben Aufrufe) vorne+hinten in der Routine selbst, Assembler-Einsprengsel, Registerzugriffe, was immer dazu nötig ist. Mal mit, mal ohne Compiler-Support für Interrupt-Routinen (GCC hat das zwar, aber verbugt, und natürlich ohne Nesting). Was Performance angeht ist das optimal. Was Flexibilität und Portabilität angeht eher nicht. Ich bevorzuge die andere, schon von mthomas skizzierte Variante. Einen zentralen Assembler-Handler für Interrupts, der insbesondere auch für's Nesting sorgt, seinerseits den Vektor abholt, die Funktion aufruft und den/die IRQ-Controller anschliessend freigibt. Vorteile hier: Nesting ist problemlos, der Interrupt-Handler ist eine ganz normale Funktion ohne Sonderbehandlung und es darf insbesondere auch Thumb-Code sein. Das pflege ich dann auch so zu implementieren, dass es einem Interrupt-Handler egal ist, ob er vektorisiert und unvektorisiert aufgerufen wird (LPC2000-Problem mit 32 Quellen aber nur 16 Vektoren). Was das Nesting von LPC2000 angeht: Ich habe das auf LPC21xx ausprobiert und kein Problem dabei gefunden. Die vom VIC implementierten Prioritäten funktionierten tatsächlich wie sie sollten, obwohl die Doku sowohl von ARM als auch von NXP in dieser Hinsicht eher Quell von Irritation als von Information ist.
> Das eigentliche "Nesting" hat meines Wissens nichts mit dem > Interrupt-Controller direkt zu tun, sondern mit der Funktionalität des > Cores. Ein bischen hängt das insofern zusammen, als Nesting nur dann wirklich Sinn ergibt, wenn der Interrupt-Controller sauber mit Prioritäten umgehen kann. D.h. wenn gesichert ist, dass in jeder Phase der Interrupts nur höher priorisierte als der laufende Interrupt durchkommen.
@mthomas, Andreas Kaiser: Danke für eure ausführlichen Antworten, die mir erst mal eine Menge neuer Anregungen verschaffen. Damit ist das Thema noch lange nicht vom Tisch: ARM-Assembler-Programmierung, ja, OK, damit sollten wir laut Compiler-Hersteller eigentlich vollständig verschont bleiben. Da dies aber Wunschdenken ist, habe ich schon erfolgreich z.B. FIQ-Surprise-Handler geschrieben, sowas sollte also gehen. Was ist eigentlich ein Assembler-Wrapper? Ein neuer Ausdruck für "Handler"? Ich werde einige Überlegungen anstellen müssen, mich bei nächster Gelegenheit wieder äußern, und sicher weitere Fragen haben. Gruß Dietmar
> Was ist eigentlich ein Assembler-Wrapper? Ein neuer Ausdruck für > "Handler"? Wrapper = Verpackung. Hier gemeint: ARM-IRQ-Vektor => direkt zu ASM-Code ohne VIC-Vektor, dort: - switch to system stack - save volatile registers - call VIC vector (application IRQ handler) - restore registers - acknowledge VIC - switch back to IRQ stack - return from interrupt D.h. der ganze hässliche Teil steckt im ASM Teil. Der ganze Firlefanz mit Stacks und Registern ist dort, der IRQ-Handler der Anwendung ist eine blitzsaubere C-Funktion. Steckt bei mir im startup.S drin.
Zum Begriff "Verpackung": Eine normale C Funktion wird vom zentralen ASM-Code so verpackt, dass sie als IRQ-Handler dienen kann.
@Andreas Kaiser: Danke für die ausführlichen Hinweise und Auflistung der Schritte für die Vorgehensweise. Mit ARM-Assembler habe ich mich schon angefreundet, z.B. um den Startup-Code zu erweitern, und für spezielle Zwecke, wie Surprise-Interrupt-Handler mit Zähler, ist das auch notwendig. Eine andere Frage wäre noch an mthomas: >Bin selbst dazu übergegangen, für die allermeisten ARM Entwicklungen >einen Assembler-Wrapper für IRQ-Exceptions zu nutzen, bei dem immer >"genestet" wird. "Immer genested" wie kann ich das verstehen? Gruß Dietmar
> wie Surprise-Interrupt-Handler mit Zähler, ist das auch notwendig. Du meinst wahrscheinlich den spurious interrupt handler. Wird gern verwechselt. Der surprise interrupt ist derjenige, der trotz scheinbar abgeschalteter interrupts läuft. > "Immer genested" wie kann ich das verstehen? Vermutlich genau das was ich auch schrieb. Dass nicht jeder einzelne IRQ handler entscheidet, ob er nesting zulassen will, sondern dies zentral und damit bei jedem IRQ geschieht.
>> wie Surprise-Interrupt-Handler mit Zähler, ist das auch notwendig. >Du meinst wahrscheinlich den spurious interrupt handler. Wird gern >verwechselt. Der surprise interrupt ist derjenige, der trotz scheinbar >abgeschalteter interrupts läuft. Nein nein, das war schon ganz richtig gemeint. Gruß Dietmar
Dietmar wrote:
> Nein nein, das war schon ganz richtig gemeint.
Hmm. Es aber eigentlich weder einen Surprise-Interrupt-Handler noch
einen -Vektor. Es gibt unter dieser Bezeichnung nur ganz normale
Interrupts vielerlei Quellen und Vektoren, die in überraschendem Kontext
(bei eigentlich abgeschalteten Interrupt) aufgerufen werden.
>Andreas: Ich sehe schon, Unterschied Spurious- und Surprise- Interrupt, da gibt es wohl noch Klärungsbedarf. In einem anderen Thread, hab ich mich kürzlich zu einem nicht dokumentierten Watchdog-Problem bei den LPC2100/2200 geäußert: Beitrag "ARM Keil Realview: Critical Section" In der YAHOO "LPC2000"-Group gab es in der Vergangenheit heftige Diskussionen zu Spurious Interrupts und Surprise Interrupts in Verbindung mit Nested Interrupts, aber am Ende auch keine klare Lösung. Da harmoniert so manches nicht miteinander. >Der surprise interrupt ist derjenige, der trotz scheinbar >abgeschalteter interrupts läuft. Genau so ist es, nach wie vor! >Hmm. Es aber eigentlich weder einen Surprise-Interrupt-Handler noch >einen -Vektor. Der Default-Interrupt-Vektor, muß immer installiert sein, wenn auch als leere Funktion, alleine nur wegen der Spurious Interrupts, damit das Programm in so einem Fall nicht abstürzt. Mehr muß man dazu zunächst nicht wissen, es bedarf auch keiner besonderen Behandlung, denn der zum Spurious Interrupt gehörende echte Interrupt kommt im zweiten Anlauf sowieso wieder, und dann korrekt, wie er soll. Es geht nichts verloren. Im übrigen konnte ich in meiner Anwendung niemals einen Spurious Interrupt mehr beobachten, wahrscheinlich aus dem Grunde, daß der Vectored Interrupt Controller (ARM PL190) in den LPC-Bausteinen doch sehr schnell geworden ist und die Vektor-Adresse "immer" zum richtigen Zeitpunkt liefern kann. Natürlich gibt es keinen Surprise-Interrupt-Handler, ich hab das mal so genannt, Handler, Wrapper, wie auch immer, da muß man jedenfalls selbst was in Assembler schreiben, wie im User Manual unter dem Kapitel "Spurious Interrupts" ebenfalls grob umrissen. Und es so platzieren und verwenden, wie man glaubt, daß es richtig sein wird. In der Startup.s direkt an den Interrupt-Vektoren habe ich also ein Stück Code platziert, der den Interrupt sofort wieder zurückweisen kann, oder auch nicht, und zwar je am IRQ-Vektor und am FIQ-Vektor. Diesen habe ich mit dem Configuration Wizard in der Keil µVision Oberfläche schaltbar gemacht, ähnlich Präprozessor-Defines. Oder man regelt das über die EQUate-Anweisungen, wenn kein Configuration Wizard vorhanden ist. So kann ich über den Configuration Wizard mit Aktivierung oder Deaktivierung bestimmen, wie Surprise Interrupts behandelt werden, und zwar ob ein Interrupt nach der Sperrung, wenn er auftritt, noch bearbeitet wird, oder später. Das ist wichtig für kritische Sequenzen, z.B. Watchdog Feed, wenn parallel dazu auch ein langwieriger FIQ seine Aufmerksamkeit fordert, der wiederum kritisch für die Nachladezeit des Watchdog werden kann. Surprise-Interrupt-Handler mit Zähler, ich wollte hauptsächlich mal wissen, wie viele Surprise-Interrupts im Schnitt in meiner Anwendung stattfinden, wenn ich FIQ über ARM-Core sperre, anstatt über den VIC-Controller. Funktionieren, tut das alles exzellent. Ich muß es nur zur Compile-Time schon bestimmen. Anderen Lösungen, um das Verhalten (FIQ Zulassung oder Zurückweisung) während der Laufzeit zu bestimmen, z.B. nach Wert einer Variablen entscheiden, steht aber auch nichts im Wege, kostet aber mehr Laufzeit wegen Zugriff auf die Variable. Wenn man seine Anwendung im USER Mode laufen läßt, und nicht im SYSTEM Mode, wie auch von ARM vorgeschlagen, kann man auf ein IRQ-Surprise-Handling verzichten, da niemals Surprise-IRQ auftreten werden, weil IRQ nie gesperrt werden (können, weil es keinen Sinn macht), sondern nur FIQ, wenn FIQ verwendet. Der Konfigurationsmöglichkeiten gibt es eben viele! So kompliziert ist das doch nicht! @mthomas: Habe bei Keil tatsächlich ein neueres Beispiel für Interrupt Nesting mit RealView gefunden. Das hat aber auch einen beachtlichen Stack-Verbrauch, wogegen mein eigenes genanntes (und bisher leider nicht kommentiertes) Beispiel sicher nicht schlecht sein wird! Gruß Dietmar
> In der YAHOO "LPC2000"-Group gab es in der Vergangenheit heftige > Diskussionen zu Spurious Interrupts und Surprise Interrupts in > Verbindung mit Nested Interrupts, aber am Ende auch keine klare Lösung. Ist mir nicht entgangen. Wir hatten das Thema schon früher (als A.K.). > Im übrigen konnte ich in meiner Anwendung niemals einen Spurious > Interrupt mehr beobachten, wahrscheinlich aus dem Grunde, daß der > Vectored Interrupt Controller (ARM PL190) in den LPC-Bausteinen doch > sehr schnell geworden ist und die Vektor-Adresse "immer" zum richtigen > Zeitpunkt liefern kann. Wenn man nicht grad wie der STR9 mit kaskadierten VICs arbeitet, dann hat das weniger mit langsamerem oder schnellerem Timing zu tun, als vielmehr mit dem Programm selbst. Spurious Interrupts entstehen nach meinem Verständnis vorzugsweise dann, wenn man dem VIC hintenrum den Request klaut, beispielsweise indem man einen schon anstehenden UART-Interrupt durch einen UART-Zugriff abwürgt. In diesem Fall entsteht ein Fenster in dem der Prozessor bereits auf den IRQ reagiert hat, der VIC aber keinen Vektor mehr liefern kann. Da der Interrupt-Controller nicht Bestandteil des ARM-Cores ist, wird der Zeitpunkt an dem der Core auf den IRQ reagiert und der Zeitpunkt, an dem der Vektor festgelegt wird, stets differieren und solange der separate Interrupt-Controller seinen Zustand nicht spätestens mit der Reaktion des Cores auf den IRQ einfriert, solange besteht dieses Fenster. Das gilt übrigens prinzipbedingt für alle Architekturen mit dieser Arbeitsabfolge. > Natürlich gibt es keinen Surprise-Interrupt-Handler, ich hab das mal so > genannt, Handler, Wrapper, wie auch immer, da muß man jedenfalls selbst > was in Assembler schreiben, wie im User Manual unter dem Kapitel > "Spurious Interrupts" ebenfalls grob umrissen. Und es so platzieren und > verwenden, wie man glaubt, daß es richtig sein wird. Man kann sie auch schlicht und einfach vermeiden. Werden IRQs und FIQs grundsätzlich nie mit einem Befehl gleichzeitig sondern in definierter Reihenfolge abgeschaltet, dann entsteht das Problem erst garnicht und man muss in Handler nicht darauf Rücksicht nehmen. > Wenn man seine Anwendung im USER Mode laufen läßt, und nicht im SYSTEM > Mode, wie auch von ARM vorgeschlagen, kann man auf ein > IRQ-Surprise-Handling verzichten, da niemals Surprise-IRQ auftreten > werden, weil IRQ nie gesperrt werden (können, weil es keinen Sinn > macht), sondern nur FIQ, wenn FIQ verwendet. Das hat freilich weniger mit USER/SYSTEM als vielmehr mit konsequenter Programmierung zu tun. Indem man für Enable/Disable schlicht zentrale Funktionen verwendet. Ob man das mit Syscalls oder normalen Funktionen macht, ist auf Controllern ohne grösserem Betriebssystem irrelevant.
Das mag ja vielleicht alles stimmen, und den UART habe ich nie verwendet, mit seinen Problemen, wenn man hinten herum einen Request klaut (was immer das bedeuten mag). Ja, ich hätte den LPC auch einen kaskadierten VIC mit 32 vektorisierten IRQ gewünscht, aber die wollten wohl sparen. Ansonsten macht da aber auch nichts mehr Probleme. Das Watchdog-Problem jedenfalls habe ich anhand vieler Konfigurationsmöglichkeiten selbst gelöst. In keinem Papier steht geschrieben, daß die Watchdog Feed Sequenz nicht von Interrupts durchbrochen werden darf. Das muß man erst mal selbst herausfinden, wenn man ständig Watchdog-Resets aufläuft. Mit meiner Anwendung folge ich dem Vorschlag von ARM, die Anwendung vorzugsweise im User Mode zu betreiben und nicht im System Mode. Warum schlagen die denn das vor??? Gegen IRQ geschützte Funktionen habe ich als SWI konfiguriert. Und wenn nötig, sperre ich darin FIQ. Das funktioniert alles ausgezeichnet. Gruß Dietmar
@Andreas: Ein Kollege, der den ARM nur für den UART verwendete, hatte tatsächlich das beschriebene Problem. Aber auch dort gibt es Workarounds, das ist gelöst. Nein, ich wollte ja den vergangenen Krempel (von Ende 2005 ???) auch nicht noch mal von vorne diskutieren. Nichtsdestotrotz, ist bei der Diskussion ja immerhin noch die Idee herausgesprungen, daß ich das Auftreten von Surprise-Interrupts auch während der Laufzeit beeinflussen kann. Nein, ich möchte die nicht einfach nur eliminieren, sondern mal zulassen und mal abweisen. Und das funktioniert vorzüglich. Spurious Interrupts hin, ... Surprise Interrupts her, ... ... eigentlich war meine ursprüngliche Frage ja, ob meine Lösung zu den Nested Interrupts eine brauchbare ist. Dazu gibt es bis jetzt leider immer noch kein Statement. Aus dem neuen Beispiel für RealView zu schließen, wäre meine oben gepostete Lösung sicher auch noch einen Gedanken wert, da auch getestet und funktionell. Sorry, ich durchsuche das Internet gelegentlich mal nach Beispielen, aber nicht gerade regelmäßig (wegen des neuen Beispiels für RealView). Je besser der ARM läuft, desto weniger recherchiere ich. Das muß ich wohl mal überdenken. Ansonsten, muß ich ja zwischendurch auch mal arbeiten:-) Gruß Dietmar
> ... eigentlich war meine ursprüngliche Frage ja, ob meine Lösung zu den > Nested Interrupts eine brauchbare ist. Dazu gibt es bis jetzt leider > immer noch kein Statement. Dazu kann ich mangels Keil und RealView auch keine konkrete Aussage treffen. Ich könnte mir vorstellen, dass GCC unter den Teilnehmern des Forums etwas verbreiteter ist. Grundsätzlich sehen die nested_... Dinger zwar in sich ok aus, nur hat ein stack switch innerhalb einer Funktion gewisse Nebeneffekte für die Funktion selbst. Einen korrekten stack frame gibt es so nicht, also muss man genau aufpassen, dass auch keiner erforderlich ist (lokale Variablen betreffend). Am sichersten geht das, indem man dort nicht viel macht als eine weitere (normale) Funktion aufzurufen, die den eigentlichen Job erledigt. Oder man kontrolliert im erzeugten Code genau, dass nichts unpassendes geschieht. Und das ist ein Grund, weshalb ich, wie beschrieben, das Problem auf andere Weise angehe (wie auch mthomas), bei der interrupt handler ganz normale Funktionen sind. So nebenbei erspare ich mir dadurch auch diesbezügliche Bugs im GCC und muss nicht krampfhaft ARM- und Thumb-Code auseinanderdividieren.
Kleiner Exkurs: AvrX verwendet für die top level functions von threads Funktion ohne korrekten Frame (naked). Was auch sauber dokumentiert ist. Wenn man also lokale Variablen auf dem Stack braucht, kann man das nicht im top level machen sondern muss das in eine aufgerufene Funktion auslagern. Soweit ok. Kann man mit leben, wenn man genau aufpasst. Wirklich ganz genau aufpasst. Und immer mal kontrolliert. Denn zum Problem wurde das dann doch, mehrfach, weil GCC, dem das sinnlos vorkam, mir eine Nase drehte und solche Funktionen schlicht wieder eingliederte (inlining). Und das ist genau die Sorte Ärger, die ich gern vorneweg vermeide.
Hallo Dietmar! Ich weiß, dein Beitrag ist schon etwas älter, aber ich habe dein Nested_irq.s - File eingebaut und es funktioniert hervorragend. Dankeschön. Ein paar Fragen habe ich jedoch noch: So wie aus meinen Tests hervorgeht, kann nur ein IRQ höherer Priorität eine gerade laufende IRQ-Routine unterbrechen. Sagen wir der Timer 0 hat den Vektor 2, und in der IRQ-Routine wird nach dem Löschen des IRQs die Funktion: nested_irq_enable(); aufgerufen, dann ist die Routine nur dann unterbrechbar, wenn ein IRQ vom Vektor 0 oder 1 während dieser Zeit aktiv wird. Wird ein IRQ z.B. mit Vektor 3 oder 4 während dieser Zeit aktiv, dann können diese IRQs, die laufende Vektor 2 Routine nicht unterbrechen. Warum ist das so? Ich dachte, nach aufruf von nested_irq_enable(); sind grundsätzlich alle IRQs wieder freigegeben. Danke für eure Antworten. Tschüss Schönen Feiertag Martin
Auch wenn der Thread schon ewigkeiten her ist, vielleicht kann mir jemand das ja beantworten: Ist dieser Nested Interrupt Code auch für ein AT91SAM7X256 brauchbar? Die Variante, dass die Prioritäten mit kontrolliert werden und nur Interrupts mit höherer Priorität den anderen Interrupt unterbrechen können klingt interessant.
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.