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?
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).
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.
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.
Bezüglich den Timern. Es gibt beim mega16 mehrere Timer. Deshalb auch 0, 1, 2.
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).
Möglichwereise ein Stacküberlauf, falls du große Mengen an lokalen Variablen benutzt.
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.
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
> 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.
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.
> 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.
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)
Fang bitte einen neuen Thread an (und den im Elektronik- und µC-Forum), das hat mit dem Thema des Threads nichts zu tun.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.