Forum: Compiler & IDEs SREG in ISR speichern


von Thomas S. (magicsmoke)


Lesenswert?

Hallo,

wir haben hier im Kollegium ein etwas undurchsichtiges Problem.

Innerhalb des "normalen" Programms (Atmega1280 mit winAVR) wird ein 
Vergleich von zwei uint16 durchgeführt. sporadisch wird aber 512>680 als 
true erkannt und dann die entsprechende Routine ausgeführt.

Da für den Vergleich intern ja das C-Flag benutzt wird, könnte ich mir 
vorstellen, dass das SREG von einer der vielen ISR verbröselt wird.

Und hier beginnt der Glaubenskrieg. Sollte man das SREG in der ISR 
zwischenspeichern um es am Ende der ISR wieder unverändert zu haben?

Gruß Thomas

von (prx) A. K. (prx)


Lesenswert?

Wenn die ISR in C geschrieben ist, dann macht das der Compiler selbst. 
Das ist nur nötig, wenn die ISR in Assembler geschrieben ist.

Es könnte also eher sein, dass der Inhalt des Speichers 
(Register,Stack), in dem das SREG vom Compiler gesichert wird, dank 
irgendeines Programmfehlers zerstört wird.

von Thomas S. (magicsmoke)


Lesenswert?

ist in C geschrieben

Im Listing sehe ich eine Menge Register die auf den Stack geschoben 
werden, aber keine Sicherung von SREG

von (prx) A. K. (prx)


Lesenswert?

Dann zeig mal diesen Code - Quelle und Listing.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas Schulz wrote:

> sporadisch wird aber 512>680 als
> true erkannt ...

Meine Glaskugel meint, dass du den Vergleich selbst nicht gegen das
Eindringen eines Interrupts ,,in die Mitte des Vergleichs'' abgesichert
hast.

Schau dir mal den Header <util/atomic.h> an.

http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

von Klaus (Gast)


Lesenswert?

Die SPannende Frage ist: werden die Variablen, die du vergleichst in der 
ISR benutzt?

Wenn ja, könnte ein Interrupt "Mitten im Vergleich" die Ursache sein. 
Außerdem sollten die Variablen dann als volatile deklarier sein.

von Björn G. (tueftler)


Lesenswert?

Hallo und vielen Dank für den richtigen Denkanstoss!

Die Ursache konnte heute gefunden werden:
Scheinbar hat wirklich die ADC-ISR in mitten des Vergleiches die Werte 
geändert.
Dadurch konnte mit einem Breakpoint ->nach<- diesem Vergleich auch nur 
noch den nun wieder neuen Wert angezeigt werden - der alte war 
mittlerweile schon wieder in der Variable überschriben worden.

Durch ein cli()/sei() in dieser Funktion konnte schonmal der richtige 
Wert angezeigt werden, der für den Einsprung in die if/then 
verantwortlich war.

Nachdem das schonmal geklärt wurde, ist nun nur der ADC-Interrupt 
kurzzeitig ausgeschaltet worden und alles läuft wieder wie es sollte.

Die Suche danach war wirklich sehr mühsam, da man zudem noch den 
Optimizer aus schalten mußte um richtig Debuggen zu können...

Viele Grüße
Björn

von Falk B. (falk)


Lesenswert?

Gewusst wie hätte man sich das erspart, siehe Interrupt.

MFG
Falk

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.