Hallo, Ich habe das Problem, dass mein (ziemlich großes) Programm hin und wieder abstürzt und von vorne beginnt (reset). Gibt es eine Möglichkeit, den Ort des Absturzes festzustellen, ohne dass ich alles durchsteppen muss? Ich verwende den Mega168 mit AVR-Studio (aktuelle Version) + JTAGICE-mkII im debugWIRE-Modus. THX und lg Andy
So ein Absturz kann viele Ursachen haben, zb ein aktivierter Interrupt für den es keinen Handler gibt. Aber du kannst ja mal folgendes versuchen. An 'strategisch günstigen' Stellen, schreibst du jeweils eine andere Zahl an eine bestimmte Stelle im EEPROM. Nach dem Absturz liest du das EEPROM aus und die Zahl verrät dir, was der µC zuletzt gemacht hat (natürlich darf er dann nicht mehr hochfahren bzw. die musst diese Mitschreiben abstellen). Auf die Art kannst du mit ein bischen Glück den Code eingrenzen. (Wenn du eine UART hast, kannst du dasselbe ja auch mit Ausgaben auf ein Terminal machen. Das Program protokolliert dann an einem Terminal mit, was es gerade tut) Besonderes Augenmerk muss man natürlich darauf legen, dass sich durch dieses Logging das Timing des Programs verändert. Das kann ein Problem sein. Daher sollte man da auch nicht elendslange Texte ausgeben lassen, sondern nur kurze Kennungen. Die können ruhig kryptisch sein, solange sie dir als Entwickler nur den Hinweis geben, wo das Programm gerade war/ist.
Andy schrieb: > Ich habe das Problem, dass mein (ziemlich großes) Programm hin und > wieder abstürzt und von vorne beginnt (reset). Gibt es eine Möglichkeit, > den Ort des Absturzes festzustellen, ohne dass ich alles durchsteppen > muss? > Ich verwende den Mega168 mit AVR-Studio (aktuelle Version) + > JTAGICE-mkII im debugWIRE-Modus. Wo ist das Problem, wenn Du nen Debugger hast? Setze einfach nen Brechpunkt an 0x0000. Und dann schau Dir den SP an, wohin der zeigt und das MCUSR, obs wirklich ein Reset war. Peter P.S.: Du hast selbstverständlich auch nen BADISR_vect Handler aufgesetzt.
Karl Heinz Methode geht auch relativ gut über einen UART, falls vorhanden.
Danke für die Antworten. Hab mir schon sowas in der Richtung gedacht! Noch was: Gibt es eine Möglichkeit, die ISR beim Debuggen auszuschalten. Der Timer soll aber trotzdem weiterlaufen und den Code beim Überlauf ausführen. Ich will nur nicht, dass bei jedem 2. Step der Debugger in die Timer-Routine hüpft. THX Andy
avarice kennt --ignore-intr. Keine Ahnung, ob dass passt, denn Du hast nicht gesagt, womit Du debuggst.
> "Absturzstelle" ermitteln da wo's brennt und viele verstreute teile rumliegen ;) ich hab bei meinen projekten immer irgendwo eine LED am controller, die man für solche tests gut gebrauchen kann. vielleicht gibts bei dir sowas auch? die idee mit dem UART ist aber auch gut, der controller muß es aber dann trotz crash noch schaffen diese daten zu senden. ein reset ist aber eher untypisch für einen crash, meistens hängt der controller einfach. oder wird er vom watchdog zurückgesetzt? und in welchen zeitlichen abständen crasht der controller. läuft das proggi erst tagelang durch bis es dann irgendwann mal crasht oder passiert das quasi sofort?
Hi!
>Programm hin und wieder abstürzt und von vorne beginnt (reset)
Ich bevorzuge eigentlich auch die UART Metode.
Um die Debugzeiten kurz zu halten einfach einer Variable an def. Stellen
einen def. Wert übergeben und bei Reset über UART ausgeben.
255 Prüfwerte passen in ein einziges Byte, da kommt man schon recht
weit.
Die Stackadressen sind auch sehr aufschlussreich.(push/pop lässt
grüssen).
Einfach mit ausgeben.(natürlich vor einem Init erstmal retten)
Viel Erfolg, Uwe
Ben schrieb: > die idee mit dem UART ist aber auch gut, der controller muß es > aber dann trotz crash noch schaffen diese daten zu senden. Es geht doch nicht darum, die Daten trotz crash noch zu senden, sondern zu sehen, was kurz vor dem crash ausgeführt wurde. > ein reset ist aber eher untypisch für einen crash, meistens hängt der > controller einfach. oder wird er vom watchdog zurückgesetzt? Außer es ist ein nicht initialisierter Int-Vektor, der angesprungen wird. Der Program Counter läuft dann durch eine Reihe NOPs zum Programmanfang und alles sieht nach einem Reset aus. Spontanes hängen gibt es nur, wenn zufälltig eine Endlosschleife entstanden ist oder du eine programmiert hast, aus der nichts rausführt. Oft rennt der Prozessor auch in nicht initialisierten (also mit zufälligen Daten gefüllt) Flash-Bereich. Da kommt es dann drauf an, wie der Prozessor das interpretiert (zB als Sprung nach 0x0000). Ich weiß jetzt nicht, ob man an den SP des AVR drankommt. Wenn ja, diesen (und den Zellinhalt auf dem dieser zeigt) bei einem Reset (also am Programmanfang) auf den UART ausgeben. Wenn es ein echter Reset ist, steht der SP auf der größten RAM-Adresse (weiß ich auch nicht ganz genau), ansonsten irgendwo anders. Der Zellinhalt ist die Adresse, von der aus der "Reset" ausgelöst wird.
Danke für eure Antworten - habt mir sehr geholfen. Ich werd das mal mit der UART probieren. Weiß sonst irgendjemand, ob man das Ausführen der ISR während des Debuggens abschalten kann (nur das zwingende durchsteppen - Funktion soll erhalten bleiben)? lg
-Sind HW-Fehler 100% ausgeschlossen? RAM=? -WENN der SW-Fehler näher bekannt wäre, könntE man evtl. auch versuchen ein Programm schreiben "was sich selber hilft".
Hab den Fehler schon gefunden. Ich bin an der Grenze des Speichers angelangt und habe anscheinend irgendwas überschrieben. Wenn ich ein paar Funktionen und Variablen rausnehme, läuft das Prog einwandfrei. Wie gesagt, jetzt würd mich noch das Deaktivieren der ISR beim Debuggen interessieren. lg
OK, aber ganz versteh ich mein Problem noch nicht! Wenn ich ein paar Variablen weglasse, dann hab ich bei Data 73% des Speichers belegt und das Programm funktioniert. Schließe ich jedoch diese Variablen wieder mit ein, so hab ich bei Data 80% belegt und das Programm funktioniert nicht (Symptome wie oben - reset ca alle 2sek.). Das komische ist aber, dass diese Variablen gar nicht benutzt werden. Was ist da los? lg
Andy schrieb >> OK, aber ganz versteh ich mein Problem noch nicht! Wenn ich ein paar >> Variablen weglasse, dann hab ich bei Data 73% des Speichers belegt und >> das Programm funktioniert. Schließe ich jedoch diese Variablen wieder >> mit ein, so hab ich bei Data 80% belegt und das Programm funktioniert >> nicht (Symptome wie oben - reset ca alle 2sek.). Das komische ist aber, >> dass diese Variablen gar nicht benutzt werden. Was ist da los? >> >> lg Stack-Overflow! Willkommen im Club! Bernhard
Du hast keine 20% frei, sondern 80% von Variablen belegt. Der Stack braucht je nach Komplexheit des Programms auch noch Platz. Was dabei passiert, ist einfach. Der Stack überschreibt Deine Variablen und fängt irgendwann wieder von oben an. Dann überschreibt sich der Stack selber. Funktionsrücksprünge führen an falsche Stellen. Lokale Variablen stimmen nicht mehr. Auch überschreiben Deine Variablen wiederum den Stack.
das letzte ist das was ich glaube, seine variablen überschreiben den stack. der nächste ret oder iret schießt das ding dann ins nirvana. übrigens ist das mit dem UART daten senden gar nicht so simpel. der µC core ist deutlich schneller als der UART und er crasht daher auch deutlich schneller. beim crash/reset kann der UART dann zurückgesetzt werden obwohl noch nicht alles übertragen war, vor allem wenn man mehrere zeichen interrupt-gesteuert übertragen wollte. für eine absolut genaue auswertung müßte man den abschluß des sendens abwarten bevor man das programm fortsetzt. bei meinen programmen hab ich auch keine uninitialisierten ints. unbenutzte ints setz ich auf eine fehlerausgabe - im einfachsten fall halt einen LED-blinker oder so. dann weiß man wenigstens was passiert ist.
>hab ich bei Data 73% des Speichers belegt >Ich hab doch noch 20% frei?? >Du hast keine 20% frei, sondern 80% von Variablen belegt. Sagt Data nicht eher was über den Flash aus? Es läuft wohl eher der RAM über. Selbst wenn Du nur 3 % Flash belegt hast, kann Dir zur Laufzeit der RAM ausgehen (Rekursive Aufrufe, Nested Interrupts, riesige Variablen wie ein Array etc.). Der Stack ist ja im RAM. Aber wie Peter ganz am Anfang schon schrieb: 1.) Du hast JTAG 2.) Nutze MCUSR um die Richtung des Problems zu finden (Watchdog, Brownout etc.) und checke auf nicht abgefangene Interrupts bzw. verhindere sie mit einem "Allescatcher" a la BADISR_vect Handler
Hi, Hat vielleicht noch jemand eine Ahnung, ob sich die ISR beim Debuggen deaktivieren lassen?? lg
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.