Forum: Mikrocontroller und Digitale Elektronik Interrupt, Stackaufbau


von Peter S. (Gast)


Lesenswert?

Hallo Leute,

ich verwende einen 8051 Mikrocontroller, welcher in C per Keil Compiler 
kompiliert wird.

Mich würde interessieren, was alles in den Stack gesichert wird wenn 
eine Interrupt Service Routine aufgerufen wird. Mir ist aufgefallen, 
dass unterschiedlich viel Bytes im Stack abgelegt werden (mehr als durch 
Parameter und Funktionsaufrufe zu erwarten wäre). Ist der Aufbau des 
Stacks beim Aufruf eines Interrupts irgendwie genormt oder soetwas? Wann 
z.B. werden Register im Stack gesichert und wann nicht?

Es geht mir darum, dass ich den Stack in der Interrupt Service Routine 
so manipulieren möchte, dass ich an eine andere Stelle im Code springen 
kann (zur Realisierung eines preämptiven Multitaskingsystems). Das 
Manipulieren des Stacks innerhalb von normalen Unterprogrammen klappt 
einwandfrei. Allerdings verhält sich der Stack bei Interrupts scheinbar 
anders...

Vielen Dank für eure Hilfe!

von Forzo (Gast)


Lesenswert?

Naja. Man kann sich das ASM Listing geben lassen und dann nachschauen 
was der Complier effektiv macht. Dann wird man fuer ein Realtime System 
den Timer Interrupt von Hand in ASM schreiben muessen.
Mir scheint aber das Wissen sei etwas auf der geringen Seite um gleich 
mit einem preemptiven System loslegen zu wollen. Ich wuerd erst mal ein 
kooperatives System vorziehen, da einfacher.

von dummschwaetzer (Gast)


Lesenswert?

Am besten im assembler-listing prüfen.
In der Regel:
Interupt ausgelöst:
Auf den Stack:
Programm Counter
ander Register,je nach dem, ob sie im Interrupt verwendet werden
Status register der CPU

Siehe Dokumentation Compiler
Siehe Dokumentation Controler

von Hans Peter B. (Gast)


Lesenswert?

Hast du die folgende Seite schon besucht
http://www.keil.com/support/man/docs/c51/c51_le_interruptfuncs.htm
Hans Peter

von Peter S. (Gast)


Lesenswert?

Vielen Dank für die Infos, die haben mir bereits sehr geholfen!

Ich habe mir den ASM Code angesehen, der beim Aufruf der ISR 
durchgeführt wird. Abhängig von dem Code innerhalb der Interrupt Service 
Routine werden unterschiedlich viele Register gesichert (je nach dem ob 
diese in der ISR benutzt werden oder nicht).

Dieses Verhalten gefällt mir allerdings absolut nicht, denn sobald etwas 
im Code der ISR geändert wird, muss meistens auch der "Stack 
Manipulations Code" geändert werden. Außerdem wäre der gesamte Code sehr 
vom verwendeten Compiler und von der verwendeten 
Codeoptimierungseinstellung des Compilers abhängig.

Abhilfe sollte doch eigentlich das Keyword "using" schaffen, oder? Ich 
habe mir den oben geposteten Link durchgesehen und auch noch ein 
bisschen tiefer in die Seite hineingestöbert. So wie ich das verstanden 
habe, sollte doch ein Wechsel auf eine andere Registerbank verhindern, 
dass ACC etc. im Stack gesichert werden müssen.
Dies habe ich ausprobiert und leider ist es nicht so wie erwartet. Es 
wird zwar das PSW auf die durch using angegebene Registerbank 
umgestellt, ACC etc. werden allerdings trotzdem in den Stack 
gesichert...
Was mache ich hier falsch? Warum muss ACC und Konsorten trotzdem 
gesichert werden?

von Hans Peter B. (Gast)


Lesenswert?

Der Acc und das PSW sind ja nur einmal vohanden. Sie müssen daher, wenn 
in der ISR der Acc gebraucht wird oder eine Reg-Bank-Umschaltung 
vorgenommen wird, in jedem Fall auf dem  Stack gesichert werden. Wird in 
der ISR eine using-Direktive verwendet, dann werden nur die Register 
R0...R7, aus der vor der Interruptauslösung aktiven Reg-Bank,  nicht 
gesichert. Die in der ISR verwendeten Reg-Bank darf allerdings im 
übrigen Programm nicht verwendet werden, wenn der Interrupt freigeben 
ist
Hans Peter

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.