www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Debuggen: SREG Register überwachen?


Autor: John (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgendes Setup:
AVR Studio 4.18.700
AVR Dragon
ATmega128

Folgendes Problem:
Nach zufälliger Zeit (sofort bis nach ein paar Minuten) werden keine 
Interrupts mehr ausgeführt. Das Interrupt Enable Flag im SREG Register 
bleibt ungesetzt. Der Controller läuft aber noch (LED an Pin blinkt 
weiterhin). Der Timer läuft auch noch (Wert ist bei jedem Halt anders).
Das heraus zu finden hat schon einige Zeit gedauert, jetzt komme ich 
aber nicht weiter. Ich finde einfach nicht heraus, wo mir das Flag 
zuletzt gelöscht wird.

Kann ich vielleicht irgendwie beim Debuggen direkt auf das SREG Register 
triggern? Evtl. über Debug->New Breakpoint?
Andere Ideen? Über Hilfe würde ich mich freuen. Danke.

Schöne Grüße
John

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Flag kannst nur Du löschen oder ein gerade laufender Interrupt. 
Möglicherweise wird ein Interrupt nicht mehr verlassen bzw. startet 
sofort neu, so dass andere Interrupte nicht mehr zum Zug kommen.

Autor: John (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe versucht im Code nachzuvollziehen, wann da was schief laufen 
könnte.
Aber ich hatte die Hoffnung der Debugger könnte mir dabei helfen.

Dadurch, dass die LED weiter blinkt, glaube ich nicht, dass er irgendwo 
endlos fest hängt. Setze ich das Flag wieder, laufen die Interrupts auch 
wieder für unbestimmte Zeit, bis das Flag wieder hängen bleibt.

Mich wundert diese undefinierte Zeitspanne.

Was ich im Verdacht habe, sind meine Funktionen zum Deaktivieren der 
Interrupts für bestimmte Aktionen, aber bisher hatte ich eigentlich 
keine Probleme damit.
useStop und OldSreg sind volatile!
//stop interrupts, if not already stopped
void stopInt() {
  if (useStop) {
    useStop=0;
    OldSreg = SREG;
    cli();
  }
}

//---------------------------------------------------------
//restores old interrupt configuration
void enabInt() {
  SREG=OldSreg;
  useStop=1;
}

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es dir in einer ISR den Stack zerschiesst (warum auch immer), wird 
am Ende ein falscher SREG-Wert gepoppt.

Viel Spaß beim Suchen.

Oliver

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Wenn es dir in einer ISR den Stack zerschiesst (warum auch immer), wird
> am Ende ein falscher SREG-Wert gepoppt.

Danach wird aber das I-Bit durch den RETI wieder gesetzt. ;-)

Nein, direkt im Debugger überwachen kann man das nicht.  Dummerweise
kann dir auch ein wild gewordener Zeigerzugriff das SREG zerschießen,
da es ja ein IO-Register ist wie alle anderen.  Schreiben der
Adresse 0x5F bügelt dann das SREG ... den Fall könntest du vermutlich
mit einem data breakpoint im JTAG ICE noch erwischen, allerdings auch
nur den: wenn das SREG mittels separater Befehle oder via OUT modi-
fiziert wird, dann schlägt der data breakpoint jedoch nicht zu.

Autor: John (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es hat vermutlich auch etwas mit einer Kompileränderung zu tun.
Das Problem besteht seit einem Umstieg von WinAVR 2008 06 10 auf 2010 01 
10.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  OldSreg = SREG;
>  SREG=OldSreg;

Da könnte dir durch einen Stacküberlauf einfach OldSreg
zerschossen werden.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau Dir mal die atomic.h an.

Die garantiert, daß bei jedem Austritt der gewünschte Interruptstatus 
hergestellt ist.


Peter

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
John schrieb:
> Was ich im Verdacht habe, sind meine Funktionen zum Deaktivieren der
> Interrupts für bestimmte Aktionen
Eventuell übersehe ich ja was, aber du machst dir da meiner Meinung nach 
viel zu viel (fehlerträchtigen) Aufwand.
Was spricht dagegen einfach
cli();
sei();
 zu benutzen?
Die Interrupts stört es nicht "mehrfach" deaktiviert zu werden und du 
sparst dir das "sichern" von SREG, wo du ggf. auch noch ein paar Flags 
mitnimmst und dir später wieder überschreibst was möglicherweise dann 
andere Probleme aufwirft.

Autor: Thomas O. (kosmos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du könntest zu debug-Zwecken Ausgaben vor und nach die Interruptroutinen 
setzen um zu beobachten nach welchem Interrupt das Problem auftritt.

z.B. An den Anfang der Interrupt-Routine1 läßt du einen LED 1x kurz 
blinken am Ende der Routine 1x lang so weist du dann wo das Programm 
aussteigt und kannst es im Simulator nochmals durchspielen.

Eine andere Möglichkeit wäre in der Hauptschleife den Stackpointer zu 
vergleichen. Angenommen der Stack ist 1024 Byte groß, programmierst du 
einen Vergleich wenn Stack>1000 Programm stoppen, also kurz vor dem 
Überlauf.

Ich denke aber ganz einfach das deine Interruptroutinen nicht wieder 
beendet werden sondern das du einfach weiter verzweigst und irgendwann 
läuft der Stack über und dein Programm macht dort weiter wo es gar nicht 
gewollt ist.

Autor: John (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Vorschläge.

Bisher war der Stackpointer beim Anhalten mit dem Debugger immer sehr 
groß (0x10F5), was ja auf einen sehr kleinen Stack schließen lässt. 
Eigentlich kommt er mir zu klein vor. Allerdings kann sich das ja 
dynamisch kurzzeitig auch ändern.

Ich habe noch herausgefunden, dass es ohne meine Displayroutinen stabil 
zu laufen scheint. Aber den weiteren Zusammenhang konnte ich noch nicht 
erkennen.

Gruß
John

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.