Forum: Compiler & IDEs Unerwünschter Reset - wie Interrupt abfangen?


von Florian (Gast)


Lesenswert?

Ich habe in meinem Programm einen Wurm: Irgendwas löst einen Interrupt
aus, den ich wohl nicht abfange, was dann ja zu einem reset führt. Wie
kann ich denn eine allgmeine Funktion schreiben, die alles abfängt und
dann feststellen, was da quer schießt?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, eigentlich solltest du ja wissen, welche Interrupts du
alle einschaltest...

Ansonsten bleibt nur, individuelle Interruptvektoren einzeln zu
schreiben, die eine globale Variable (volatile!) mit einem
bestimmten Wert beschreiben.  Sowas kann man sich, wenn man eine
Scriptsprache auf dem Computer hat, automatisieren lassen (die
Namen aller Vektoren bezieht man dann aus dem ioXXX.h-File).

von thkais (Gast)


Lesenswert?

Ich hatte gerade eben einen ähnlichen Fall. Drei Tage gesucht nach einem
sporadischen Neustart. Ursache: Kondensatoren am Quarz fehlten.
Ich wollts echt nicht glauben, aber ich kann das Verhalten
reproduzieren.
Fazit: Nicht immer ist die Software schuld.

von Florian (Gast)


Lesenswert?

Doch, leider schon. Da bin ich sicher.
Bei den Interrupts stehe ich auch auf dem Schlauch. Eigentlich habe ich
nur einen UART und Timer. Beide fange ich ab. Aber beim 8-Bit Timer
blicke ich eh noch nicht durch. Auf dem mega16 stimmt rein gar nichts
überein. Lt. Datenblatt heißen die Register CS2x, im iom16.h ist es
CS0x und laufen tut's nur mit CS1x. Grr.

von stephan e (Gast)


Lesenswert?

Bezüglich den Timern.
Es gibt beim mega16 mehrere Timer.
Deshalb auch 0, 1, 2.

von Florian (Gast)


Lesenswert?

So, Problem gefunden:
Der Speicher war zu knapp. Obwohl beim compilieren nichts darauf hin
wies (wie ich finde):
Program:   13320 bytes (81.3% Full)
(.text + .data + .bootloader)

Data:        894 bytes (87.3% Full)
(.data + .bss + .noinit)

Aber ein paar Byte gespart und schon wurde die Sache wieder stabil, wie
gewohnt. Das soll einer verstehen... (tut er vielleicht auch, nur ich
eben nicht).

von Rolf Magnus (Gast)


Lesenswert?

Möglichwereise ein Stacküberlauf, falls du große Mengen an lokalen
Variablen benutzt.

von jayjay (Gast)


Lesenswert?

Verwendet man die avr-libc, so kann man einen default-IRQ-Handler wie
folgt definieren:

ISR(__vector_default)
{
// user code here
}

Alle nicht anderweitig definierten IRQ-Vektoren zeigen dann darauf.
Aber man kann auch nicht nachvollziehen, welcher Vektor jetzt genau
angesprungen wurde.

Ich hatte übrigens bis gestern exakt das gleiche Problem auf einem
AT90S2313. Der Code lief bis dahin problemlos, Flash-Belegung ca. 70%,
RAM ca. 60%. Dann eine einzige Zeile hinzugefügt, in der eine globale
Variable verändert wurde --> Reset-Endlosschleife. Mit obigem
default-Handler habe ich festgestellt, dass ein IRQ kommt, dann habe
ich für jeden IRQ einen eigenen Handler geschrieben wie von Jörg
angeregt, und konnte so den INT0 als Ursache ermitteln. Dieser IRQ wird
in meinem Hauptprogramm explizit noch einmal deaktiviert, d.h. obwohl
ich eigentlich wusste, welche IRQs aktiv waren, wurde einer der
inaktiven Vektoren benutzt. Dies führte zur Vermutung, dass es sich
nicht um einen "echten" IRQ, sondern eine kaputte Rücksprungadresse
auf dem Stack handeln könnte.

Grund für den zu kleinen Stack bzw. das zu volle RAM war die Definition
mehrerer Zeichenketten per "....". Da dies mein erstes
avr-libc-basiertes Projekt ist, wusste ich bis gestern noch nicht, dass
in diesem Fall die Strings im RAM angelegt werden. Umstieg auf
PSTR("....") und fputs_P() brachte dann auch eine deutliche
RAM-Entlastung, und seitdem läuft alles wieder stabil. Vorsorglich habe
ich jetzt noch ein paar lokale Variablen, sofern sinnvoll machbar,
"globalisiert", um den Stack-Bedarf zu reduzieren.

von Peter D. (peda)


Lesenswert?

Ja, den default-Handler sollte man unbedingt so schreiben, daß ein
Anspringen deutlich wird, z.B. alle LEDs an und dann ne
Endlosschleife.

Ich hab z.B. ne Weile gebraucht, und mich gewundert, warum mein
Programm so schnarchlahm war. Es hat ständig resettet und neu
initialisiert, darum wars so lahm.
Ursache war, ich hatte nen Compare1A-Handler geschrieben, aber
versehentlich Compare1B freigegeben.

Die default-Einstellung, ein Reset zu machen, ist also voll fürn Arsch,
da sie Fehler verschleiert, statt sie offensichtlich zu machen.
Eine Endlosschleife fällt dagegen recht schnell auf (CPU tot).


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Vorsorglich habe
> ich jetzt noch ein paar lokale Variablen, sofern sinnvoll machbar,
> "globalisiert", um den Stack-Bedarf zu reduzieren.

Bringt nicht wirklich viel, außer dass du es so vielleicht schon
zur Compilezeit siehst: du hast damit den zeitweisen RAM-Verbrauch
dafür gegen permanenten RAM-Verbrauch getauscht.

von jayjay (Gast)


Lesenswert?

Schon klar. Interessanterweise hat es aber auch den Flash-Bedarf
geringfügig reduziert, vermutlich weil der Prolog der betroffenen
Funktionen jetzt kürzer ist? Ich hatte gestern leider keine Zeit mehr,
mir die List-Files genauer anzusehen, muss ich heute abend mal
nachholen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Interessanterweise hat es aber auch den Flash-Bedarf
> geringfügig reduziert, vermutlich weil der Prolog der betroffenen
> Funktionen jetzt kürzer ist?

Ja, es muss ja kein Platz mehr auf dem Stack geschaffen werden.

von Michi (Gast)


Lesenswert?

Hi
Ist das hier noch aktuell?
Also ich hab grad auch ein Problem mit ständigem unregelmäßigem Reset.
Könnte es daran liegen, dass die Kondensatoren am Quarz zu klein sind?? 
(Laut Datenblatt (des Quarzes) sind 32pF nötig, mit 33pf hats nicht 
funktioniert, also hab ich 12pF verwendet, damit läuft es zwar, aber ich 
hab diese ständigen Resets.
(Hab leider keine anderen da sonst würde ich es schnell testen)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fang bitte einen neuen Thread an (und den im Elektronik- und µC-Forum),
das hat mit dem Thema des Threads nichts zu tun.

von Michi (Gast)


Lesenswert?

Ok, Danke, hast sich aber erledigt.
Musste nur die Fuse-Bits anders setzen.

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.