Welcher Controller? ARM7? RealView, ist sicher ein ARM7-er.
Nun, du hast schon eine Lösung gefunden? Etwas Reflektion über den
Erfolg, wäre manchmal ganz nett.
Trotzdem, schreibe ich noch ein paar Worte dazu, möchte aber niemanden
ins Bockshorn jagen. So ein ARM, braucht eben etwas mehr Aufmerksamkeit
als ein 8051-er. ARM7, nichts was einen weltlichen Bürger vom Stuhl
haut, aber der macht mir umso mehr Spaß, je mehr ich die Details kenne.
Critical Section: Ich nenne mal ein Beispiel für die LPC21xx/LPC22xx,
wobei die Watchdog Feed Sequenz niemals von Interrupts unterbrochen
werden darf, da sonst ganz klar ein Reset stattfindet. Dabei muß der
Watchdog rechtzeitig nachgeladen werden, das soll schon ein wenig
berechenbar sein!
Der Watchdog erzeugt einen Reset, wenn Interrupts die Feed-Sequenz
stören. Aus dem User Manual geht das nicht hervor, auch nicht aus
ERRATA. Das ist möglicherweise auch kein Bug, sondern eine Design-Frage.
Das Problem mit dem Watchdog z.B. im LPC2129 hatte ich schon Ende 2005
mal hier gepostet, mittlerweile habe ich den Workaround dazu selbst
erarbeitet. Zwar verfüge ich nicht über einen In-Circuit-Emulator,
konnte das Problem trotzdem lokalisieren. Unter anderem installierte ich
einen Watchdog-Interrupt für den Debugger, der jedoch laut User Manual
auch nur für Debug-Zwecke vorgesehen ist.
Critical Section könnte so eine Watchdog Feed Sequenz sein, die man
schon als SWI konfiguriert hat, damit sie nicht mehr von in der Regel
mehreren konfigurierten IRQ unterbrochen werden kann. SWI: sperrt IRQ
global.
Jetzt muß man aber auch noch in der Regel einen einzigen FIQ sperren, da
dieser den SWI durchbrechen würde. Das kann man auf 2 Arten: Erstens,
durch die von dir schon genannte Intrinsic-Funktion aus dem SWI-Mode,
und zweitens, durch Sperrung des FIQ im VIC-Controller.
Bei FIQ-Sperrung über die Intrinsic-Funktionen entstehen je nach
Interruptfrequenz mehr oder weniger so genannte Surprise-Interrupts, man
bekommt das normalerweise gar nicht mit (es sei denn, man hat einen
Surprise-FIQ-Handler mit Surprise-Zähler eingebaut gleich am
Interrupt-Vektor, dann kann man den Zähler im Debugger betrachten), und
die müssen auch nicht unbedingt stören: Beim Surprise-Ereignis schlägt
noch ein FIQ während des Sperrbefehls zu und wird vor der Critical
Section komplett abgearbeitet.
Entscheidend ist hier, wir befinden uns jetzt nach der Sperrung direkt
an der Feed-Sequenz, wie lange die FIQ-Routine dauert! Denn, der
Watchdog-Timer läuft, und wartet auf die Nachladung.
Wenn man entscheiden möchte, ob ein über Intrinsic-Funktion gesperrter
FIQ noch abgearbeitet oder für später (nach Freigabe hinter der Critical
Section) zurückgestellt wird, braucht man eben einen (zuschaltbaren)
Surprise-FIQ-Handler in Assembler, direkt am Interrupt-Vektor.
Bei FIQ-Sperrung über den VIC-Controller entstanden bei meinem
Watchdog-Problem absolut keinerlei Seiteneffekte mehr, auch keine so
genannten Spurious Interrupts, denn die betreffen den FIQ nicht. Alles
lief absolut sauber.
Damit wäre das für seltene Fälle im Zweifelsfall die bessere Lösung als
die Sperrung über Intrinsic-Funktionen.
In einem Header für globale Definitionen definierte ich 3 Makros:
// Für FIQ-Sperrung über den VIC-Controller:
#define VICFIQBIT (0x01 << 5) // Timer 1
#define DISABLE_FIQ {VICIntEnClr = (VICFIQBIT);}
#define ENABLE_FIQ {VICIntEnable = (VICFIQBIT);}
Oder, für FIQ-Sperrung über den ARM-Core:
#define DISABLE_FIQ {__disable_fiq();}
#define ENABLE_FIQ {__enable_fiq();}
Im gesamten Source-Code, egal welcher Größe, setzt man dann DISABLE_FIQ
und ENABLE_FIQ an die betreffenden Stellen ein.
So kann man die Art der Sperrung (VIC oder F-Bit im ARM-Core) über den
gesamten Sourcecode hinweg von einer zentralen Stelle aus vorbestimmen,
und etwas experimentieren.
Übrigens: Die Intrinsic-Funktionen können nur in Non-USER-Modes
verwendet werden, da sie im USER-Mode einfach keine Wirkung haben. Da
sind die Sperrungen über den VIC-Controller vielfältiger.
Den Default-Interrupt-Handler sollte man aber "immer" installiert haben,
wenn auch nur als leere Funktion. Denn ohne, auch wenn die Anwendung
wochenlang sauber läuft, und dann aber mal ein Spurious IRQ auftritt,
stürzt die Anwendung gnadenlos ab.
Gruß
Dietmar