Hallo !
Kennt jemand einen Link zu einer Checkliste, warum AVRs resetten ?
Ich bin mir 99.999%ig sicher, dass es ein Softwarefehler ist und nicht
an der Hardware bzw. Beschaltung liegt.
Habe ein recht umfangreiches Programm, dass bei einigen Berechnungen
(bin leider auf Fließkommazahlen angewiesen) und teilweise bei einer
i2c-Slave-Zeichen-empfangen Funktion resettet.
Für einen Tipp bin ich sehr dankbar !
Schönen Abend (Nacht) noch !
Hallo,
Checkliste hab ich keine, aber was öfter vorkommt ist zB.
- ein nicht geplanter aber aktivierter IRQ, der dann als Reset endet,
weil die ISR nicht vorhanden ist.
- es gibt keine Endlosschleife, dann läuft das Programm irgendwann bis
ans Ende des Flashs, und fängt wieder von vorne an -> Reset
- es werden mehr Daten aus dem Stack geholt, als hineingestellt wurden,
bei einem RET könnte das an der Adresse 0000 landen. Hab ich aber noch
nicht selber nachgeprüft.
Hallo!
Danke für die Antworten!
Wie kann ich das mit den ISR überprüfen? Ich habe halt einen Timer
laufen, sowie den IRQ für das TWI. Oft kommt ein Reset bei dem Aufruf
der ISR der mir die über i2c empfangenen Zeichen speichert.
Das wäre diese Funktion: (AvrLib, Pascal Stang)
[c]
void i2cSlaveReceiveService(u08 receiveDataLength, u08* receiveData)
{
newVal_flag = 1;
u08 i;
//Daten speichern...
for(i=0; i<receiveDataLength; i++)
{
localBuffer[i] = *receiveData++;
}
localBufferLength = receiveDataLength;
//Buffer analysieren... (Regelgrößen)
switch(localBuffer[0])
{
case 'A':
//p_1_soll_i2c = localBuffer[3];
x_soll_i2c =localBuffer[1];
//c_soll =localBuffer[2];
//p_1_soll_i2c =localBuffer[1];
//p_2_soll_i2c =localBuffer[2];
Erst mal rauskriegen, woher der Reset kam. Also beim Start MCUSR
anzeigen und auf 0 setzen. Dann ist schonmal klar, ob es überhaupt ein
Reset war, oder eher doch ein Sprung nach 0.
Sprung nach 0 beispielsweise:
- Interrupt A eingschaltet und ISR(B) definiert,
- Stacküberlauf,
- Buffer overflow bei lokaler Variable.
Hallo!
Danke für die Antworten!
Wie kann ich das mit den ISR überprüfen? Ich habe halt einen Timer
laufen, sowie den IRQ für das TWI. Oft kommt ein Reset bei dem Aufruf
der ISR der mir die über i2c empfangenen Zeichen speichert.
Das wäre diese Funktion: (AvrLib, Pascal Stang)
Mit diesen Code-Fragmenten kann man nichts anfangen. Wichtiger wäre
beispielsweise die Steuerung der Interrupt-Flags und die entsprechenden
Routinen, und der ganze Kram vom I2C, inklusive Pufferdefinitionen.
Wieviel RAM von wieviel ist denn belegt?
Während ich geschrieben habe kamen ja schon einige Antworten! Danke
dafür! Ich werds mal probieren und berichten.
Ach ja eins noch:
Wenn ich den localBuffer per USART sende, bleibt er erhalten, mache ich
dies nicht, wird er auf Anfangswert gesetzt. Ich hielt das bis dato für
einen Reset...
Woran kann das liegen? LocalBuffer ist global definiert.
Grüße !
Hans wrote:
> Program: 11954 bytes (73.0% Full)> Data: 799 bytes (78.0% Full)
200 Bytes Stack kann grad bei vielen lokalen Variablen und komplettem
printf oben drauf schon knapp werden. Wenn du hast, probier mal einen
Mega32 aus, der hat 2KB.
Hans wrote:
> Mach ich. Haben wir noch rumliegen.. langsam werd ich verrückt. Muss man> speziell aufpassen mit Division durch Null oder Ähnliches?
Keine Ahnung. Bei sowas ist ratsam, defensiv vorzugehen, und es garnicht
erst nicht darauf ankommen zu lassen.
Hallo ! Erstmal Danke für die Antworten! Also der Watchdog ist definitiv
aus. Also ich werde mal einen Mega32 probieren. Grad wegen dem Stack.
Was mir am komischten vorkommt ist das, was ich oben schrieb:
Wenn ich den localBuffer in main() immer wieder per USART sende, bleibt
er erhalten, mache ich
dies nicht, wird er auf Anfangswert gesetzt. Ich hielt das bis dato für
einen Reset...
Naja... weiter probieren. Das blöde ist nur, wenn man nicht wirklich
Ahnung von den Hardwareabläufen an sich hat ist diese Probiererei ein
Fass ohne Boden.....
> Wenn ich den localBuffer per USART sende, bleibt er erhalten, mache ich> dies nicht, wird er auf Anfangswert gesetzt. Ich hielt das bis dato für> einen Reset...
Was denn nun?
Passiert ein Reset oder passiert keiner?
Das wäre mal das erste was es herauszufinden gilt.
Du musst es dir zur Regel machen bei der Fehlersuche
nichts, aber auch gar nichts, als gesichert anzunehmen
(OK. Man kann mal davon ausgehen, dass der Compiler
keinen Fehler gemacht hat und dass die Systemlibrary
funktionieren wird).
Zweifle alles und jeden an, bis du durch Tests ausschliessen
kannst, dass da ein Fehler drinnen steckt. Man sollte nicht
für möglich halten, wieviele Leute Fehler in Berechnungen
suchen und sich nach Stunden herausstellt, dass schon
die Eingangswerte in diese Berechnung fehlerhaft sind und
die Berechnung an sich völlig in Ordnung ist.
Garbage in - Garbage out.
Das meine ich mit: Zweifle alles und jeden an und mag es noch
so banal sein. Keine Vermutungen, nur harte Fakten zählen.
Ich finde es irgendwo schon sträflichen Leichtsinn, dass
du bis jetzt nur vermutest, dass ein Reset gemacht wird
und das noch nicht abgetestet hast. Am Programmanfang eine
LED einschalten, die nur mit einem Tastendruck ausgeschaltet
werden kann und dann die Schaltung einfach mal Laufen lassen.
LED abschalten und warten. Wenn dein Fehler auftritt und die
LED brennt, dann war das ein Reset. Brennt die LED nicht, dann
ist auch kein Reset vorgekommen.
Oft sind solch seltsame Fehler wie deiner ein Zeichen dafür,
dass du zuviel Code auf einmal geschrieben hast ohne zwischen-
durch immer wieder extensive Tests durchzuführen. Man steht
dann mit einem Haufen Code da und weiss nicht wo man zu Suchen
anfangen soll.
Daraus ergibt sich unter Umständen aber auch folgende Strategie:
Code auskommentieren und zurückschrauben bis man in einem
funkionierenden Zustand ist. Dann nach und nach sukzessive
den auskommentierten Code wieder freigeben und jeweils umfangreiche
Tests machen, ob irgendetwas auffällt. Das geht am Besten, wenn
dein Code nicht Kraut und Rüben ist, sondern sauber in Module
aufgeteilt ist. Modulare Programmierung hat auch beim Testen
so seine Vorteile.
Das allerwichtigste beim Debuggen ist aber: Den Fehler
reproduzierbar machen. Du musst exakt wissen was du tun
musst um den Fehler zu forcieren. Solange du das nicht weist
ist alles andere ein Stochern im Nebel. Nur mit der Kenntnis
der Schrittfolge, die zum Fehler führt, hat man eine Chance
zielgerichtet nach einem Codeproblem zu suchen.
Ein bischen Glück und Intuition braucht man aber dann trotzdem.
Hallo Karl-Heinz!
Ersmal Danke für die umfangreiche Antwort!
Definitives kann ich nun sagen: Es handelte sich un Resets.
Plötzliche Resets wurden durch Senken der Baudrate von 34800 auf 9600
behoben.
Der Fehler mit diesem doofen localBuffer bleibt aber auch, nach
Auskommentieren von allem, außer den nötigen Grundfunktionen, um den
Fehler hervorzurufen. localBuffer als volatile hilft nicht! Vielleicht
weiß noch jemand etwas? das senden der Zeichen nervt und macht das
Programm unnötig langsamer...
Viele Grüße!
Das (rudimentäre)Programm:
Hallo Andreas !
Nein, momentan kommt nur : 'Abc$' über den Bus. Und das nur auf
Knopfdruck über eine MATLAB GUI.
Also kleiner als definiert.....
Viele Grüße !
Hans wrote:
> Definitives kann ich nun sagen: Es handelte sich un Resets.
Wenn du das so definitiv sagen kannst, dann kannst du uns ja an Hand
von MCUCSR auch noch sagen, welcher Reset es denn war. Vergiss
bitte nicht, die Bits dort nach dem Auswerten zu löschen, die
akkumulieren andernfalls bis in alle Ewigkeit.