Forum: Compiler & IDEs Was muss bei einer Interrupt-Routine alles gerettet werden??


von Michi (Gast)


Lesenswert?

Hallo allerseits,

ich programmiere momentan gerade einen Atmel AT90S2313. In meinem
Programm möchte ich gerne eine Interrupt-Routine laufen lassen. Nun
stehe ich vor dem Problem, dass ich in der I-Routine eine
Programmverzweigung benötige.
Hierfür ist es doch erforderlich bestimmte Register per POP & PUSH zu
sichern, oder?? Kann mir jemand sagen, wie ich es hinbekomme, dass nach
dem Sprung das Programm an der richtigen Stelle abläuft??

Folgenden Code habe ich:

int0_handler:
in temp, pind
sbrc temp, 4
rcall rueck

vorwaerts:
adiw Messwertl, 1
rcall serout
reti

rueck:
sbiw Messwertl, 1
rcall serout
reti

Problem: Wenn das Unterprogramm rueck ausgeführt wird, wird nicht die
Interrupt-Routine verlassen, sondern bei vorwaerts eingesprungen.

Gruß Michi

von Volkmar (Gast)


Lesenswert?

Hallo Michi,

wenn Du in int0_handler einen cal auf rueck machst, dann springt der
ret aus rueck auch dorthin wieder zurück. Danach fehlt der reti um
wieder ins Hauptprogramm zurückzukehren.

Aber wenn ich das richtig verstehe, dann sollte ein rjmp rueck anstelle
rcall rueck das machen was Du möchtest.

Was retten:
Alles das was das Hauptprogramm nicht gewünscht beeinflußt. Also im
Detail:
- Das Statusregister (da i.d.R. Flags geändert werden)
- Alle Register die verwendet werden.

Volkmar

von Michi (Gast)


Lesenswert?

Super, vielen Dank. Es funzt.

Eine kleine frage habe ich noch. Wie rettet man das Statusregister??
Mit
POP SREG
ja wohl nicht.

Michi

von Volkmar (Gast)


Lesenswert?

Aus der Erinnerung heraus (habe schon lange nichts mehr mit Assembler
gemacht):

push r16
in r16, SREG
push r16

und dann zum Abschluß:
pop r16
out SREG, r16
pop r16
reti

Man muß ein Register dafür misbrauchen. Und dieses muß dann vorher
gesichert werden, da es verändert wird.

Volkmar

von Jens Renner (Gast)


Lesenswert?

Stimmt. Aber was hat das mit C zu tun? :-)

von Mach8 (Gast)


Lesenswert?

Macht GCC das mit dem Sichern von alleine? Und sichert der dann alles
oder nur was man benutzt hat?

von Volkmar (Gast)


Lesenswert?

GCC macht das alles alleine, soweit er davon weiß.

Volkmar

von Mach8 (Gast)


Lesenswert?

"Soweit er davon weiß" heisst auch, dass er nicht einfach alles
sichert(wie etwa Bascom)? Unter welchen Umständen merkt GCC denn nicht,
dass die Routine etwas verändert(inline Assembler?)?

von Volkmar (Gast)


Lesenswert?

Einfach alles sichern würde zuviel Performance kosten. "Soweit er davon
weiß" setze ich mit "Solange alles in C geschrieben ist" gleich. D.h.
das was GCC selber verursacht ist ihm bekannt und kann er auch sichern.

Wenn die ISR komplett in Assembler geschrieben ist, wird man es selber
machen müssen. Wenn Du inline Assembler in einer ISR benutzt, bin ich,
ehrlich gesagt, überfragt. Zur Not mit einem kleinen Testprogramm
selber ausprobieren ;-)

Volkmar

von Jörg Wunsch (Gast)


Lesenswert?

Ordentlich benutzter inline asm sollte dem Compiler kundtun, welche
Register alle benutzt werden, so daß er auch weiß, was zu retten ist.

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.