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