Forum: Mikrocontroller und Digitale Elektronik AVR bleibt hängen/Stack Overflow?


von Christoph Söllner (Gast)


Lesenswert?

Hi *,

ich hab mit einem ATmega16 ein Problem. Ich benutze den CodeVision
C-Compiler. Ich habe 30 Bytes Globale Variablen. (740 Bytes frei für
Stack), einen USART receiver ISR, 3 Timer laufen und das
Hauptprogramm.
In jeder ISR steht vorne ein #asm("cli") und hinten ein
#asm("sei"); also sollte theoretisch jede ISR atomar ausgeführt
werden, und keine ist zeitkritisch, will eben nur eine Stack-Stapelei
vermeiden.

Timer0 dient fürs scrollen von Text auf dem LCD; die cvavr-lcd-lib
liest das ready-flag des LCD aus und wartet solange, bis das fertig ist
mit Schreiben.
Timer1 erzeugt ein 15kHz PWM Signal auf 6 Ausgängen:4x Motor,1x LCD
Kontrast, 1x LCD Brightness zum ein/ausfaden der LED Beleuchtung.
Timer2 zählt die empfangenen USART Frame-Errors pro Sekunde.
Der WDT ist aus.

Jetzt ist es so, dass wenn Timer0 läuft (also ScrollText angezeigt
wird), die Kiste regelmäßig nach einer gewissen Zeit hängen bleibt:
Der Scrolltext bleibt stehen und es werden keine Tastendrücke mehr
abgearbeitet; die PWM-Signale für die Motoren/LCD allerdings bleiben
erhalten.

Hat jemand mit Stack Overflow Erfahrung? Kann ich das irgendwie
debuggen? Was passiert bei einem StackOverflow (Reboot/Trap)?

Danke,
Christoph

von Stefan Kleinwort (Gast)


Lesenswert?

Hi Christoph,

lass das cli und sei weg, Du erreichst genau das Gegenteil von dem, was
Du willst:

Sobald ein Interrupt auftritt, wird das I-Bit gelöscht und damit alle
IRs gesperrt (Manual Seite 11). Das I-Bit wird beim Rücksprung durch
den Befehl reti automatisch wieder gesetzt.

Manipulierst Du während der IR-Routine wie beschrieben das I-Bit,
werden durch das Setzen des I-Bits am Schluss IRs wieder freigegeben -
und zwar bevor die IR-Routine verlassen wurde -> ein IR-Stacking wird
dadurch also erst möglich.

Ob das Dein Problem ist, kannst Du z.B. testen, indem Du in den
IR-Routinen den Stackpointer überprüfst.

Viele Grüße, Stefan

von Stefan Kleinwort (Gast)


Lesenswert?

Hi Christoph,

was ich gerade noch vergessen habe: Ich selbst benutze nicht
Codevision, sondern gcc. Dort gibt es 2 verschiedene Arten von
IR-Routinen: eine mit Freigabe anderer IR und eine ohne. Falls es in CV
ähnliches gibt: einfach den Aufruf ohne Freigabe anderer IR benutzen
...

Viele Grüße, Stefan

von cazy horse (Gast)


Lesenswert?

das cli und sei kannst du dir getrost sparen. Im Gegenteil, das kann zu
höherer stackbelastung und sogar erst zu deinem Problem über andere
Wege führen.
Hast du einen JTAG zur Verfügung? Damit findest du einen stack overflow
sehr schnell (breakpunkt auf ende stack setzen).
Ansonsten wäre noch interessant, wie du den data stack gesetzt hast,
die  stackend-marker sind auch ganz nützlich, falls du nur mit dem
Simulator arbeitest.
Ich glaube aber nicht an ein Stackproblem, nicht beim Mega16 mit deinem
Winzprogramm.

von Christoph Söllner (Gast)


Lesenswert?

Hi, danke euch beiden. Ich habe grade ein bisserl getestet. Es stimmt,
das cli/sei hat mit meinem Problem nichts zu tun, auch scheints nicht
der Stack zu sein, habe einfach in jeder ISR eingebaut, wenn der
Stackpointer > 700 ist PORTA.7=1.
Das leuchtet nicht, auch wenn die Kiste hängen bleibt. Der Stack
scheints also nicht zu sein.

Habe dann durch Zufall folgendes herausgefunden: Ich habe 2
Stromkreise, einen 5V für die MCU und einen 12V für die Motoren. Ich
verwende zwei LB1641 Motortreiber, die mit PORTA.0/PORTA.1 und A2/A3
verbunden sind ohne Zwischenbeschaltung.
Wenn ich die 12V für die Motortreiber abklemme, tritt kein Freeze auf.
Und das perplexe ist: Wenn die Kiste hängt und ich klemme die 12V ab,
läuft es weiter, als wäre nichts gewesen. Meine Vermutung muss somit
dahin gehen, dass hier elektrische Phänomene eine Rolle spielen, also
vielleicht sind die LB1651 Eingänge nicht hochohmig und ziehen zu viel
Strom. Werde das gleich mal testen...
Danke nochmal für die Antwort.

von cazy horse (Gast)


Lesenswert?

stell mal deine Schaltung rein, aber komplett (nicht: habe ich
weggelassen, weil selbstverständlich).
Auch das Layout könnte dafür verantwortlich sein, insbesondere die
Masseführung.

von Christoph Söllner (Gast)


Lesenswert?

@horse: Oje, ich habe das auf einem Steckbrett und auf einem STK500
aufgebaut. Da ist noch nicht viel mit Masseführung.

Aber Update:
- Ich habe zwei Netzteile (McVoice 15V/2A).
- Eins versorgt mit 12V das STK
- Das andere mit 12V die Motortreiber.
- Die Massen der Netzteile sind verbunden, sonst
  bekomme ich ja kein gleiches Potential für die
  Motortreiber, und später soll 1 12V Trafo alles
  versorgen: Motoren nativ mit 12V, MCU über 7805
  (mit großem Kühlkörper ^^).
- Es hat nicht an den Eingängen des Motortreibers gelegen.

Die MCU bleibt auch hängen, wenn ich das Motornetzteil
von Anfang an ausgeschaltet habe (nur GND verbunden).
Wenn ich dieses dann, ohne (+) zu verbinden, einschalte,
läuft die MCU weiter. Ich habe leider kein Oszi und kann
mir die Pegel auf der Stromversorgung nicht anschauen,
aber ich vermute mal ganz stark, dass trotz Filter an
der STK-500 Stromversorgung die Spannung, die da rauskommt,
nicht gut für den AVR ist. Warum der dann aber nicht hängen
bleibt (die PWM für die Motoren läuft weiter, TIMER1!),
sondern nur drei Interrupts (T0,T2,UART) ausschaltet, das
weiß der Geier.
In diesem Sinne.

von AxelR. (Gast)


Lesenswert?

Das STK500 hat vorn einen Brückengleichrichter drinne, (bei mir nicht
mehr). Da hast Du einen "Masseversatz"...

von Christoph Söllner (Gast)


Lesenswert?

hm, ich habe die Massen hinter dem STK verbunden (also direkt auf dem
Steckbrett), kann es daran liegen?

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

also ich lese das so das du in einer Timer-ISR auf das Display
schreibst und das auch noch per Warten auf das Busy-Bit. Das ist keine
gute Idee. Eine ISR sollte man so schnell wie möglich wieder verlassen.
Nimm mal die Displayansteuerung aus der ISR. Bleibt das System dann
immer noch stehen.

Matthias

von Christoph Söllner (Gast)


Lesenswert?

Nein, wie gesagt, wenn das der Timer0 (Scroller) gleich am Anfang wieder
verlassen wird ("scr_enabled==0"), bleibt der nicht stehen.
Aber daran sollte es nicht liegen, da ja kein stackoverflow auftritt,
und der PWM Interrupt (und nur der) wie gewohnt weiterläuft. Und sehr
komishc ist eben die Geschichte mit dem Netzteil, die zum Weiterlaufen
des Programms führt, als wäre nichts gewesen.
Da soll mich doch einer ^^, ich erwarte diese Woche ein Ocsi, dann
kann ich mehr sagen... Christoph

von Thomas O. (Gast)


Lesenswert?

mach mal nen Filter(Tiefpass) an die Stromversorgung des AVR so wie es
auch für den ADC im Datenblatt steht, das hilft schon etwas falls die
Störungen durch die Motoren kommen. Ich habe hier einen Motor leigen
der hat zw. + und - einen Kerko hängen also ne Einfache entstörung,
vielleicht hilft das an deinen Motoren ja auch.

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
Noch kein Account? Hier anmelden.