Hallo, auf meinem Board (ATMEGA32) werden zufällige Resets ausgelöst. Jetzt würde ich gerne die Ursache herausfinden. Dazu - so dachte ich - wäre es schlau, bei Adresse 0x00 im Flash einen Breakpoint zu setzen und dann ins MCUCSR register zu schauen. Leider ist das Register 0x00! Sprich, es ist kein Bit gesetzt dass auf einen bestimmten Reset-Auslöser schließen ließe. In einem anderen Thread habe ich gelesen, dass eine nicht gesetzte CKOPT-Fuse eine Ursache sein kann. Das kann ich aber ausschließen, CKOPT ist programmiert. Gibts noch eine Idee wie ich herausfinden könnte, warum der Reset ausgelöst wird? Gruß, Daniel
>Gibts noch eine Idee wie ich herausfinden könnte, warum der Reset >ausgelöst wird? Dein Quellcode? Resets werden z.B. ausgeführt wenn ein Interrupt enabled wird, aber keine ISR dafür vorhanden ist.
holger schrieb: > Dein Quellcode? > Resets werden z.B. ausgeführt wenn ein Interrupt > enabled wird, aber keine ISR dafür vorhanden ist. Und da das dann kein echter Hardwarereset ist, sondern nur ein Sprung zur Adresse 0, gibt es in dem Fall auch nichts Interessantes in MCUCSR zu sehen. ;-)
Hallo, gibt es eine Möglichkeit zu sehen, welches die zuletzt abgearbeitete Stelle im Code vor dem Reset war? Bei TI µCs kann man direkt nach dem Reset die letzte Adresse aus dem Link Register auslesen. Gruß, Daniel
Lies einfach den Stackpointer aus. Wenn er 0 ist, dann war es ein Reset. Ansonsten zeigt er auf den SRAM, der die letzte Returnadresse enthält. Peter
>gibt es eine Möglichkeit zu sehen, welches die zuletzt abgearbeitete >Stelle im Code vor dem Reset war? Per SingleStep duch den Code gehen? >Bei TI µCs kann man direkt nach dem Reset die letzte Adresse aus dem >Link Register auslesen. Hast du es noch nicht geschnallt? Es muss kein echter Reset sein. Es könnte auch ein Jump to Zero sein. Ausgelöst durch eine fehlende Interruptroutine. Oder ein Stacküberlauf.
Hallo, für alle 20 Interrupt-Vektoren existiert ein Handler nach folgendem Schema: ISR(<vector1..20>) { lastIRQ = <vectornummer>; ... } Es scheint kein richtiger Reset zu sein da A) nichts im MCUCSR steht und B) da der Stackpointer einen Wert ungleich 0 hat. Allerdings hat der Stackpointer leider keinen konstanten Wert, sondern er zeigt auf eine zufällige Adresse im Flash (aber auf plausible), mal in einer ISR, mal im normalen Code. Und dort werden unterschiedliche Operationen. Das interessante ist, dass ich von allen drei Timern die Ausgangspins nutze. Wenn ich an diese Ausgänge nicht verbinde tritt dieses Problem nicht auf. Sobald ich jedoch die Pins mit Eingängen eines anderen ICs verbinde tritt das Problem sehr schnell auf. Komische Sache das...
>Das interessante ist, dass ich von allen drei Timern die Ausgangspins >nutze. Wenn ich an diese Ausgänge nicht verbinde tritt dieses Problem >nicht auf. Sobald ich jedoch die Pins mit Eingängen eines anderen ICs >verbinde tritt das Problem sehr schnell auf. Dann hast du ein Schaltungsproblem. Ich bin jetzt aber zu müde dir den Arsch aufzureissen weil du wichtige Informationen unterschlagen hast. Gute Nacht ;)
Vielleicht fehlt irgendwo ein "ret" mit der Zeit addiert es sich und der Stackpointer läuft über, dann gehts auch wieder bei 0 los.
Peter Dannegger schrieb: > Lies einfach den Stackpointer aus. > Wenn er 0 ist, dann war es ein Reset. Bei den neueren AVRs steht er nach einem Reset übrigens auf der obersten RAM-Adresse.
Bei avr-gcc laufen Interrupts, für die keine ISR definiert ist, über __bad_interrupt (das ist der Default-Vektor). Wenn Du einen Breakpoint dahin setzt, weißt Du sicher, ob so etwas vorliegt. Falls ja, kannst Du Breakpoints auf "verdächtige" Interrupt-Vektoren setzen und Dich so nähern.
Hallo alle, vorab: - alle nicht benutzten Eingänge sind auf Masse - alle benutzten Pins sind mit 100nF versorgt, der Reset-Pin mit 1k gegen Masse und 100nF - die Pegel schwanken nicht (mit Oszi an allen belegten Pins nachgemessen) Da das MCUCSR Register kein Bit setzt wird wohl gewollter Reset passieren. Holger sagt "Schaltungsproblem" - das klingt ja plausibel, aber welches elektrische Problem hat Einfluss auf den µC und bringt ihn dazu, bei Adresse 0x00 anzufangen ohne einen Reset auszulösen? Wenn ich das Datenblatt richtig verstehe dann gibt es keinen v. extern ausgelösten Reset der nicht im MCUCSR stehen müsste. Stimmts? Hallo Holger, das scheint mir auch zu schmerzhaft. Hallo Thomas, das fehlende "ret" müsste dann der Kompiler verursacht haben (programmiere in C) - Optimierungsgrad 0. Wäre aber technisch denkbar, aber ich halte das für höchst unwahrscheinlich. Ein Bugfix wäre dann auch nur schwer möglich. :) Hallo Hazeh, ich werde nochmal Breakpoints in den BADISR legen und sicherstellen, ob dieser nicht angefahren wird. Gruß und Dank, Daniel
Hallo nochmal, der Interrupthandler für BADISR_vect wird nicht angesprungen.
Hazeh Zimmerer schrieb:
> Das Ding heißt __bad_interrupt (mit zwei __ vorne).
Der Interrupt Handler heißt BADISR_vect, das stimmt schon so.
1 | ISR(BADISR_vect) |
2 | {
|
3 | ...
|
4 | }
|
Hallo Hazeh, "__bad_interrupt" habe ich in WinAVR-20081205 gesucht aber nicht gefunden. In der avr-libc Referenz steht Folgendes: Catch-all interrupt vector If an unexpected interrupt occurs (interrupt is enabled and no handler is installed, which usually indicates a bug), then the default action is to reset the device by jumping to the reset vector. You can override this by supplying a function named BADISR_vect which should be defined with ISR() as such. (The name BADISR_vect is actually an alias for __vector_default. The latter must be used inside assembly code in case <avr/interrupt.h> is not included.) #include <avr/interrupt.h> ISR(BADISR_vect) { // user code here } Das dürfte der Vektor sein den du meintest. Wird leider nicht aufgerufen. :(
Den meinte ich zwar nicht, aber nach der obigen Beschreibung sollte das auch gehen (ich hätte halt einfach 'b __bad_interrupt' im gdb eingegeben und gesehen, dass es den gibt. Es ist eine weak reference für die Jumps im Vektorbereich, die aber wahrscheinlich nicht mehr vorhanden ist, wenn Du einen BADISR_vect hast). Was aber gar nicht passt, ist, dass MCUCSR 0 ist. Das sollte nach jedem Reset mindestens ein Bit gesetzt haben. Bist Du sicher, dass Du es Dir auf der richtigen Adresse anschaust (->I/O-Bereich, also nicht 0x34, sondern 0x54)? Wenn es 0 ist, muss Dich Software nach 0x0 geschickt haben.
daniel schrieb: > Da das MCUCSR Register kein Bit setzt wird wohl gewollter Reset > passieren. Nö, ich würde erstmal das MCUCSR in ein 'nomales' Register retten, das wird nämlich zurückgesezt wenn man es nicht schnell genug ausliest das Problem gabs hier meine ich schonmal im Zusammenhang mit einem watchdog reset.
MCUCSR muss nach dem Starten und auslesen auch zurückgesetzt werden.
>Holger sagt "Schaltungsproblem" - das klingt ja plausibel, aber welches >elektrische Problem hat Einfluss auf den µC und bringt ihn dazu, bei >Adresse 0x00 anzufangen ohne einen Reset auszulösen? Wenn ich das >Datenblatt richtig verstehe dann gibt es keinen v. extern ausgelösten >Reset der nicht im MCUCSR stehen müsste. Stimmts? Erstmal Entschuldigung für die etwas rüde Ansprache gestern Abend :( Da du ja nur Probleme hast wenn an den Pins etwas angeschlossen ist, muss es ja ein Schaltungsproblem sein. Vorstellbar ist z.B. ein Spannungseinbruch. Da kann der uC schon Mist bauen wenn er gerade noch so Saft hat. Um den Fall abzudecken solltest du den Brown-Out Reset aktivieren. Andererseits können auch hohe Peaks auf Vcc den uC aus dem Tritt bringen. Z.B. ein Relais ohne Freilaufdiode. Oder, wie schon oft hier berichtet wurde, wenn du irgendeine induktive Last mit 230V schaltest. Dann hilft ein Snubber. Interessant wäre also was du an den Pins angeschlossen hast und was damit geschaltet wird.
Läubi .. schrieb: > Nö, ich würde erstmal das MCUCSR in ein 'nomales' Register retten, das > wird nämlich zurückgesezt wenn man es nicht schnell genug ausliest Nö. MCUCSR wird nur bei Spannungsausfall (Power-On Reset) gelöscht - und das ist erkennbar, denn danach ist das dafür zuständige Bit (PORF) gesetzt. In allen anderen Fällen muss vom Programm explizit gelöscht werden (d.h. die Bits bleiben sonst stehen).
Hallo, @Hazeh: Beim ersten Einschalten ist das Power-On Flag im MCUCSR natürlich gesetzt. Aber ich setze in der main als erstes das MCUCSR auf 0x00, um ev. getriggerte Interrupts zu erkennen. Allerdings war noch nie ein Bit gesetzt, und ich bin mir inzwischen 100% sicher dass es kein getriggerter Reset ist, da die Register weiterhin gesetzt sind (z.B. TIMSK, die OCRx, usw.). Zum eigentlichen Anwendungsfall: Beim AVR (es ist ein ATMEGA32) werden nur die 3 Timer-Compare-Ausgänge benutzt. Jeder Ausgang geht zu einem L297 auf einer extra Platine. Mit den Timer-Compare-Pins erzeuge ich die Schrittfrequenz, die die L297/L298 Kombination und den dahinter hängenden Schrittmotor steuert. Das Interessante ist: wenn zwei, einer oder kein Motor angeschlossen ist, läuft das Programm ohne eine Unterbrechung. Sobald aber alle drei Motoren angeschlossen sind, bricht das Programm unglaublich schnell ab und springt auf 0x0. Das klingt jetzt zwar nach Versorgungsspannung, aber ich habs so oft auf dem Oszi mitgemessen, und die Spannung nach dem 7805 ist glatt wie ein Babypopo. Außerdem hab ich testhalber die BOD angeschalten und auf 4V eingestellt - schlägt aber nicht an. Passt also dazu dass nichts im MCUCSR gesetzt wird.
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.