Wohin stürzt ein MC bei einem Absturz z. B. durch eine kräftige elektrostatische Entladung in der Nähe, in der Regel ab? Ich meine irgendeine Instruktion führt die CPU doch aus und sofern die nicht von selbstmodifizierendem Code stammt sollte es doch immer eine Adresse des gerade ausgeführten Codes geben und bei irgendeiner (oder irgendwelchen) muß der MC dann doch "hängen", oder?
Wenn er auf dem Tisch lag, dann vermutlich auf den Boden! ;-) Nee, was ist schon ein Absturz? Entweder ein Programmierfehler des Herstellers (dein Programm wartet z.B. auf ein nicht eintreffendes Ereignis = hängt sich auf). Durch ESD passiert eigentlich dasselbe, nur dass es nicht direkt ein vorhersagbarer Fehlerzustand ist. Z.B. ist normalerweise eine Variable null, nun ist sie es plötzlich nicht mehr und dein Programm erwartet das aber, also passiert irgendwas. Ne andere Möglichkeit ist, dass dein Programm-Counter (PC) plötzlich springt, wie ein jump irgendwohin. Das Programm wird von dort weitere ausgeführt, nur eben evtl. mit falschen Registern, Stack und RAM-Inhalten, da so ein Sprung normalerweise nicht passieren kann. Wenn du das Proggi sicherer machen willst (z.B. für Kernkraftwerk) dann baust du überall "sinnlose" Zeilen ein, die alles checken (was eigentlich sowieso klar ist), setzt ständig die Variablen neu, obwohl sie eigentlich noch den Wert (z.B. 0 haben sollten), setzt die Register, obwohl sie nach dem Reset normal per default gesetzt sein sollten und lauter so ein Zeugs. Zudem auch noch "Auffangabfragen" im Code, der zufällige Hopser (jump) auffangen kann (zumindest bei kritischen Stellen). (Z.B. etwas ins RAM speichern und danach immer wieder abfragen, ob das auch dort ist, wo du es erwartest.) Zuletzt gibt es auch noch Hardware-"Abstürze", wie Latch-Up und so. Da hilft normal nur noch ein Reset z.B. durch Watchdog (wenn nichts kaputt gegangen ist). Ach ja und natürlich Prävention, Schutzdioden, ABschirmung, Serienwiderstände, sauberes Layout, ... cu joern
Naja, es würde schon etwas helfen in den "ungenutzten" ISRs einen Reset einzubauen, also sowas void interrupt foo(foo_vector) // should never happe { _dint(); // do only one thing WDTCTL = 0xDEAD; // reset request for(;;); // wait for reset return; } Ich werde mal damit anfangen.
Hallo, aber, was passiert genau? z.B. durch einen Funken bei einem Relais im Programm. Sollte der Programmcounter springen? Wohin denn? Einfach so? Wenn das Programm in Ordnung ist und Watchdog aktiviert und trotzdem komische Sachen passieren, dann ist es nach meiner Erfahrung lediglich ein Eingangssignal an den Pins, was bestimmte Sachen auslöst. Wenn man z.B. Schalter am Eingang hat. Werden eben diese durch Funken u.a. zum Auslösen gebracht usw....
Ja, es kann sein, das ein IRQ durch eine Spannungsspitze ausgelöst wird, für den keine ISR vorhanden ist. Den Fall werde ich in Zukunft mit Reset beantworten, denn die ISR hat ja keinen Rücksprungpunkt und longjmp erscheint mir wenig sinnvoll, zumindest wenn der MC problemlos resetet werden kann. Der meiste Code berücksichtigt ja sowas nicht. Aber eigentlich sollte es zumind. beim MSP430 meist automatisch drinn sein, denn nach dem mass erase sollte bei den ungenutzten IVs 0xffff stehen und von 0xffff sollte resetet werden, oder übersehe ich da etwas? Wie ist es bei anderen Prozessoren?
Im 8052 Forum war kürzlich ein ähnlicher Thread. Es macht nicht den geringsten Sinn zu versuchen gegen Störungen zu "programmieren", sondern man muß die Ursache suchen und dann verhindern, daß überhaupt Störungen eindringen, wie z.B. Layout, Stützkondis, Serienwiderstände, Suppressordioden, Optokoppler usw. das üblich also, je nachdem wie stark störverseucht Deine Anwendung eben ist. Software hilft nicht gegen Störungen des Mikrokontrollers sondern höchstens gegen Programmierfehler. Störungen bewirken nämlich nicht die Abarbeitung eines falschen Befehls, sondern jeder FF im Mikrokontroller kann umkippen und so auch einen verbotenen Zustand einnehmen aus dem es kein Zurück gibt. Z.B. sind die allerersten AVRs komplett hängen geblieben, wenn die VCC zu langsam anstieg. Nicht mal ein Reset konnte sie aus diesem Zustand erlösen. Software hilft aber gegen Störungen auf den Eingangssignalen (Entprellsoftware) solange diese vorher auf die zulässige Werte begrenzt wurden. Peter
Ja, aber wenn jeder Cent gespart werden muß und der MC bei einer Störfestigkeits-Prüfung hängenbleibt, dann wünscht der Chef eine Software-Lösung und keinen (teuren) Watchdog. Bei vorhandenre Hardware kann man ja auch nur an der Software etwas ändern.
Hhm, Dein Chef setzt also per Beschluß die Physik außer Kraft? Ein etwas bedenkliches Verfahren zur Schadensvermeidung/-begrenzung... Peter hat völlig recht. Natürlich ist es nicht verkehrt, wenn man alle Interrupts geordnet abhandelt, auch wenn man sie nicht verwendet, weil es möglich ist, dass ein "Absturz" zufällig einen IRQ auslöst. Aber eine Lösung der grundsätzlichen Problematik ist das nicht und eine andere Softwarelösung kann dies ebenfalls nicht leisten. Diese kann nur schaltungstechnisch erfolgen; die Gründe hat Peter dargelegt. Gruß, Frank
Ja, aber als Entwickler ist man nicht Entscheider; wohin das führt sieht man ja z. B. bei TollCollect. Übrigens hab' ich nachgesehen: Beim MSP430 ist bei 0xffff die obere Hälfte des WD-IVs, d. h. ist nicht der Reset-Vektor.
Ja, ja, Geiz frisst Hirn. Eine inzwischen leider bereits weit verbreitete Seuche. Die Auswirkungen dieser Einstellung sieht man allenthalben. Ach, was rege ich mich auf! Ich werde jetzt erst mal mit drei Meter Kabel die in fünf Meter Entfernung vom Schalter befindliche Lampe an den Schalter anschließen. Irgendwo muß man ja schließlich anfangen zu sparen... Gruß, Frank
Hallo, wenn Watchdog aktiviert ist, braucht man nicht die einzelnen Interrupts abzuarbeiten - dafür ist ja Wacthdog da, immer wieder bei 0000 - reset anzufangen.
Also der interne Watchdog dient doch praktisch immer als Uhr (RTC) und der hilft z. B. nicht bei Unterspannung. Die neueren MSPs haben auch nur unzureichenden Brounout-Detector. Es geht sicher nur mit einem externen Watchdog, auch weil bem Absturz der interne Watchdog abgeschaltet werden kann.
Das ist quatsch! Ein Watchdog ist kein allheilmittel und man sollte sich überlegen, was man denn wirklich will! Wenn das Programm denn trotzdem weiterarbeiten soll, macht es nur Sinn, in die ungenutzten Interruptvektoren einfach ein "Return from Interrupt" einzubauen. Wenn man stattdessen resetten möchte, dann baut man sich eine ISR, die alle ungewünschten Interrupte auffängt, vielleicht noch nen "printf-dump" via RS232 macht und dann schön artig beispielsweise mit ausgeschalteten Interrupts den Watchdog einschalten und blockierend warten. Dann trägt man in die ungewünschten Interruptvektoren die Sprungadresse dieser ISR ein und - voila - dump und reset! Für den msp430-gcc gibts da überigens schon Vorbereitungen für (bei den AVRs würde ich das jetzt auch mal als gegeben hinnehmen - siehe avr-libc): [Zitat] 4.7. Controlling interrupt processing [..] #include <signal.h> void UNEXPECTED(void); You may declare your own version of the "UNEXPECTED()" function to override the default handling of unexpected interrupts (i.e. ones for which no specific interrupt service routine has been defined). [/Zitat] Demnach kann man dann sowas ähnliches Programmieren: #include <signal.h> void UNEXPECTED(void) { volatile int rst = 1; printf("*** FATAL ERROR: Unexpected Interrupt occured" " -- reset system!\n"); dint(); WDTCTL = WDT_ARST_1000; /* Reset after 1sec */ while(rst) ; /* Dead-loop */ } Man könnte aber auch irgendwas anderes hier machen: System anhalten, irgendwelche Variablen ausgeben - was auch immer...
Wieso immer IRQ? Jedes Bit könnte kippen! Da hilft bei Hochsicherheitsanwendungen auch nicht suaberes Design wirklich weiter (EMV, ESD), denn es braucht ja nur ein Alphateilchen dahergeflogen zu kommen und zack fliegt ein Byte durcheinander. Ionisierende Strahlung ist da immer etwas kritisch. Im Grunde würde bei solchen Anwendungen dann sogar ROM statt Flash genommen werden müssen, denn die dünnen Barrieren im Flash sind nicht unüberbrückbar. Wie gesagt, passt man bei sowas auch immer darauf auf, sich nicht auf "alte" Variableninhalte zu verlassen (z.B. ein "default_wert = 12;" am Anfang des Programms und dann tagelang sich wärend der Laufzeit des Controllers darauf verlassen, dass dort weiterhin 12 drin sein wird, denn: "ich ändere den Wert ja nicht". cu joern
IRQ deshalb, weil diese auftreten können, und man das recht einfach abfangen kann. Zu Deinen Alphateilchen ;) Ein Alphateilchen besteht aus zwei Protonen und zwei Neutronen, also einem Helium-4 Kern. Wie allgemein aus dem Strahlenschutz bekannt, reicht ein Blatt Papier aus, um alpha-Strahlung abzuschirmen. Demnach würde das Teilchen an der äusseren Hülle des Gehäuses jedes ICs stecken bleiben. Bei beta-Strahlung sieht das schon anders aus, sollte aber auch noch nicht die Probleme bereiten. Gefährlicher wirds dann bei gamma-Strahlen. Die lassen sich gar nicht abschirmen, nur abschwächen. Allerdings wage ich mal zu bezweifeln, daß ausreichend gamma-Strahlung auftreten wird, um ein Bit zu kippen. Voraussetzung: Die Schaltung wird nicht neben einem bekannten (Künstlichen) Strahler betrieben - oder auch im Weltraum. So, jetzt aber zurück zum Thema, denn worum es mir eigentlich ging: Wenn ein unerwarteter Interrupt auftritt, muss man nicht gleich alles resetten...
Wenn aber schon ein IRQ falsch ausgelöst wurde, kann es doch auch sein, dass im SRAM auch Bits gekippt sind. Bei unkritischen Anwendungen wäre da ein Reset besser, da das Programm ansonsten evtl. mit falschen Daten Amok-Läuft.
Ja, sehe ich auch so und deshalb packe ich in die ungenutzten ISRs nur (*(void(**)(void))(0xfffe))(); um direkt zu resetten; das Warten auf den WDT-Timeout ist mir nämlich a) zu aufwendig (auch von der Code-Größe) und b) dauert zu lange.
Ich wollte niemanden dazu verleiten, viel zu aufwendigen Code zu schreiben ;-) Aber die Diskussion hier hat ja nach einem gewissen Vorlauf den Weg des "was wäre wenn" durchgemacht. Und das waren eben meine Einwürfe... Vielleicht kommt ja jemand mit ner ähnlichen Frage und hat genau danach gesucht, eben nicht immer zu resetten... [BULLSHITMODE ON] Man kann nämlich auch notfalls noch nen Transistor zum Treiben eines Relais im Versorgungspfad ansteuern, falls mal ein unerwarteter Interrupt auftritt...
Eben, es könnte ja jemand nach sowas suchen und etwas Diversität in den Meinungen tut sicherlich immer gut! Es will sicherlich niemand behaupten, dass unbedingtes Resetten immer die beste wahl ist! Sollte mal ein Bit im SRAM kippen, könnte das Programm ja irgendwie Amok laufen, da sich ein Wert geändert hat. Daher müsste man in diesem Fall vor der Verwendung eines Wertes prüfen, ob er sich in einem erwarteten Bereich befindet, in dem sichergestellt werden kann, dass das Programm nicht gänzlich Amok läuft. Also eine Art Plausibilitätsprüfung. Aber selbst dann ist man nicht komplett sicher, da es immer noch passieren könnte, dass ein Bit just zwischen Prüfung und Verwendung eines Wertes kippt. Das ganze ist aber rein theoretischer Natur. Sollte ein Chip in einer solch widrigen Umgebung eingesetzt werden müssen, dann muss er eben entsprechend gegen solche Einflüsse geschützt werden. In diesem Fall wäre ein kurzes Loggen des Fehlers vor dem Reset sicherlich sinnvoll, denn sonst merkt man den Fehler nicht. Solte sich das Häufen, war die Abschirmung oder was auch immer schlecht beschaffen. Die Folge daraus ist aber nicht die Entwicklung einer besseren Auffangroutine, sondern eine Revision der Hardware!
> (*(void(**)(void))(0xfffe))(); ist ungleich einem Reset durch Watchdog. Mit deiner Methode wird nämlich kein einziges Register auf Default/Resetwerte zurückgesetzt. (D.h. du müsstest das grundsätzlich und unbedingt beim Hochlauf/im Init machen...). Hinzu kommt noch, daß ein durchschnittlicher C-Programmierer deinen Ausdruck nicht verstehen wird. :-/ > zu aufwendig (auch von der Code-Größe) naja, ein while(1); dürfte mit wenigen Bytes erschlagen sein. Und so ein Satz aus deinem Munde, der am liebsten alles mit einem embedded Linux erschlägt ;-) (<- smiley) ----, (QuadDash).
>> (*(void(**)(void))(0xfffe))(); >ist ungleich einem Reset durch Watchdog. Mit deiner Methode wird >nämlich kein einziges Register auf Default/Resetwerte zurückgesetzt. >(D.h. du müsstest das grundsätzlich und unbedingt beim Hochlauf/im >Init >machen...). >Hinzu kommt noch, daß ein durchschnittlicher C-Programmierer deinen >Ausdruck nicht verstehen wird. :-/ Also wieso soll (*(void(**)(void))(0xfffe))(); beim MSP430 nicht resetten? Beim MSP430 wird so resetet. Und wieso soll das kein durchschnittlicher C-Programmierer verstehen? In der MSP430-Usergroup versteht das jeder (bisher hat noch keiner etwas gegenteiliges behauptet u. man sieht solchen Code dort praktisch jeden Monat). Außderdem gibt's noch den ANSI-C-Standard, den man als ernsthafter Programmierer gelesen haben sollte.
Außerdem ist ein ein while(1) schlechter Stil, der von einem Voll-Compiler wie dem gcc mit einer korrekten Warnung bemängelt wird. Ein while(1) sollte man durch for(;;) ersetzen.
Hallo, also ist schon komisch das ganze. Ich kenne das eigentlich so das der MC wenn man Ihm das sagt iin folgenden Fällen einen Reset macht. Low Voltage, Illegal Opcode und Illegal Adress. Einen watchdog gibts eigentlich auch immer. Einen Nicht benutzten Opcode in den freien Speicher zu programmieren ist ja nicht das Drama. Ansonsten sollte man immer alle Interruptvektoren füllen, man spart sich eine menge Ärger. Wenn ein MC keine Möglichkeit hat auf entsprechende ereignisse gescheit zu reagieren, dann tuts ggf wirklich nur der Externe Watchhdog oder aber man sieht sich mal bei einem anderenn hersteller uum. Eckhard
Hi @nobody0 Also die von mir eingesetzten GCC's haben sich noch nie über while(1){....} beschwert. Warum sollte er auch? @Christof Krüger Eine Revision der Hardware mag Sinn machen. Ist bei einer Hardware die sich im geostationären Orbit befindet oder auf dem Mars rumfährt alles andere als trivial ;-) (Ja, solche Hardware ist von vorneherein sehr resistent gegen externe Störungen von Strahlung und Elmag-Feldern.) Matthias
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.