Forum: Mikrocontroller und Digitale Elektronik Wohin stürzt ein MC ab?


von nobody0 (Gast)


Lesenswert?

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?

von Joern Gerhard (Gast)


Lesenswert?

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

von nobody0 (Gast)


Lesenswert?

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.

von Jens-Erwin (Gast)


Lesenswert?

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....

von nobody0 (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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

von nobody0 (Gast)


Lesenswert?

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.

von Frank Linde (Gast)


Lesenswert?

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

von nobody0 (Gast)


Lesenswert?

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.

von Frank Linde (Gast)


Lesenswert?

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

von Jens-Erwin (Gast)


Lesenswert?

Hallo,

wenn Watchdog aktiviert ist, braucht man nicht die einzelnen Interrupts
abzuarbeiten - dafür ist ja Wacthdog da, immer wieder bei 0000 - reset
anzufangen.

von nobody0 (Gast)


Lesenswert?

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.

von OldBug (Gast)


Lesenswert?

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...

von Joern Gerhard (Gast)


Lesenswert?

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

von OldBug (Gast)


Lesenswert?

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...

von Christof Krüger (Gast)


Lesenswert?

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.

von nobody0 (Gast)


Lesenswert?

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.

von OldBug (Gast)


Lesenswert?

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...

von Christof Krüger (Gast)


Lesenswert?

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!

von ---- (Gast)


Lesenswert?

>  (*(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).

von nobody0 (Gast)


Lesenswert?

>>  (*(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.

von nobody0 (Gast)


Lesenswert?

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.

von Eckhard (Gast)


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

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

von Christof Krüger (Gast)


Lesenswert?

Gutes Beispiel ;)

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
Noch kein Account? Hier anmelden.