Hallo! Hat jemand mal nen Tipp, wie man beim Realview Compiler ne "Critical Section" programmiert? Also was ich beim 8051er einfach in globales Interrupt-Sperren eingeklammert habe EA = 0; // critical section EA = 1; funktioniert ja hier beim ARM, insbesondere dem Realview Compiler nicht, da er mir im Inline Assembler keinen Zugriff auf die entsprechenden Register gewährt. Muß ich da nen "echten" kleinen Assembler-Schnipsel programmieren und den dann aus "C" aufrufen? Grüße, Frank
Ok, hat sich erledigt. Habs selbst gefunden... Sind als Intrinsic-Functions implementiert: void __disable_irq(void); void __enable_irq(void); void __disable_fiq(void); void __enable_fiq(void); ... falls es noch jemanden interessiert ;-)
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
Wow! Vielen Dank für die superausführliche Antwort! Muß das erstmal sacken lassen... Und du hast richtig geraten: ARM7 (LPC23xx) und Keil (RealView) ;-)
Hallo Leute! Ich selbst habe ein paar CARM-Projekte auf Realview umgestellt. Dabei habe ich mit dem SWI herumhantiert, weil ich teilweise IRQs sperren musste. Zuerst musste man dort im statup.s-file "IMPORT SWI_Handler" eingtragen. Danach das SWI.s inkludieren und in diesem File die einzelnen SWI-Funktionen eintragen. Also total aufwändig. Als ich euren Beitrag las, war ich positiv überrascht. Dazu habe ich aus meinem aktuellen Projekt das SWI.S-File rausgeworfen und den Eintrag im startup.s-File gelöscht. Danach habe ich die SWI-funktionen so umgeschrieben, dass die nachfolgenden Funkionen zur Anwendung kommen können: void __disable_irq(void); void __enable_irq(void); void __disable_fiq(void); void __enable_fiq(void); Leider lässt sich der IRQ dadurch nicht sperren. Das Programm kann compiliert und in den Prozessor gespielt werden, aber die IRQs werden nicht gesperrt. Was kann ich falsch gemacht haben? Muss man noch etwas Zusätzliches beachten? Danke für eure Antworten. Tschüss Martin
Manche Startups halten es für nützlich, das Hauptprogramm im User-Modus laufen zu lassen. Dann lassen sich Interrupts nur via SWI sperren.
Ich habe gerade im Reference Guide gelesen, dass die Sperrung nur im privileg-mode funktioniert. Wie kann ich vom user-mode auf den privileg-mode umschalten und wo liegen die Unterschiede? Danke für eure Hilfe. Tschüss Martin
Hallo Leute! Danke, habs schon geschafft. Der Mode muss lediglich im Startup-File umgestellt werden. Das PSR-Register muss mit dem entsprechenden Wert versehen werden. Nur, wozu dient dieser Modus? Welche Vorteile bzw. Nachteile oder Einschränkungen habe ich damit? Danke für eure Antworten. Tschüss Martin
Martin wrote: > Welche Vorteile bzw. Nachteile oder Einschränkungen habe ich > damit? Auf ARM7 bietet der User Mode fast keine zusätzliche Sicherheit.
Ich habe jetzt im Datenblatt nachgesehen. Leider habe ich keine Hinweise auf verschiedene User-Modes gefunden. Es ist auch das Register PSR nicht zu finden. Was meinst du damit, der User Mode bietet fast keine zusätzliche Sicherheit? Besteht eine irgendeine Gefahr, wenn ich den Privileg-Mode in Zukunft verwende? Welche Vorteile bzw. Nachteile entstehen dadurch für mich? Dieser hat den Init-Wert: 0x1F Mich verwirren die verschienden Modi. Tschüss Martin
Sieht so aus, also ob dir die entscheidene Lektüre fehlt: Das ARM ARM (ARM Architecture Reference Manual). Gibt's auf www.arm.com zum Download.
Hast du mal 'nen Link zum ARM ARM? Außer das blaue Buch zum Kaufen finde ich keinen kostenlosen Download.
Diesen Link kriegst du von mir gratis: http://www.amazon.com/ARM-Architecture-Reference-Manual-2nd/dp/0201737191/ref=pd_bbs_sr_3?ie=UTF8&s=books&qid=1207047658&sr=8-3 Mich an deiner Stelle auf arm.com suchen lassen kostet jedoch etwas. Sind ca. 3 Clicks, alle naheliegend.
Grrrr, Andreas! ;-) Ich bin wirklich nicht der dümmste und schon gar nicht der faulste Googler bzw. Internet-Sucher. Aber ich find das "DDI-0100" nicht auf der ARM-Seite. Ums verrecken...
Och neee. Über die Online-Hilfe bin ich natürlich schon 100x drüber. Aber dass sich da drin dann nur ein PDF-Link befindet, kann ja keiner ahnen... Danke :-)
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.