mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Unterprogrammaufruf in Service-Routine


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich wollte mich hier gerade mal absichern, ob ich nicht doch einen 
Denkfehler habe. Egal ob folgender Code sinn macht oder nicht, gibt es 
einen effektiven Unterschied oder ist es völlig egal wie ich es 
schreibe?

Version 1 (die wohl sinnvolle und übliche Schreibweise):


sr:  push   r16
  in    r16, SREG
  push  r16

  //Serviceroutine in der mit r16 gearbeitet wird

  pop    r16
  out    SREG, r16
  pop   r16
  reti

Version 2:



sr:  rcall  up
  reti

up:  push   r16
  in    r16, SREG
  push  r16

  //Unterprogramm in dem mit r16 gearbeitet wird

  pop    r16
  out    SREG, r16
  pop   r16
  ret

Zusammengefasst: ist es egal ob ich meine Register/SREG vor dem ersten 
UP oder in diesem aufrufe?

Vielen Dank für euer Reindenken!

Gruß,
Andreas

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ob ich nicht doch einen Denkfehler habe.

Was denkst Du denn?

>sinnvolle und übliche Schreibweise
Welcher Sinn?

>ist es egal ob ich meine Register/SREG vor dem ersten
>UP oder in diesem aufrufe?

In welcher Hinsicht?

Ein Blick auf die Beschreibung des Prozessors und der Befehle sollte Dir 
helfen Deine Frage neu zu formulieren.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Zusammengefasst: ist es egal ob ich meine Register/SREG vor dem ersten
>UP oder in diesem aufrufe?

Ich meine natürlich "sichere" anstatt "aufrufe".

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin der Meinung, das beide Schreibweisen das absolut gleiche 
bewirken. Es also egal ist, ob ich die Register erst im up auf den 
Stapel lege/später rette, oder schon in der Service-Routine.
Oder anders gefragt, hat ein einfacher Unterprogrammaufruf (über rcall 
oder call und ein logisch später folgender Rücksprung ret) eine 
auswirkung auf das SREG-Register bzw. sonstige Register? Ich würde sagen 
nein! Habe ich da recht oder nicht??? Und mit den Rücksprungadressen 
(durch die SR bzw. UP) dürfte es doch da auch keine Konflickte im 
Programmablauf geben, oder?

Ich arbeite mit einem Atmega 32, wobei das bei dieser Frage relativ 
unerheblich sein dürfte, oder habe ich unrecht?

Gruß,
Andreas

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
bin zwar nit wirklich fit mehr und habe es auch nur im Kopf schnell 
überflogen, wie der Stack arbeitet.
Aber ich behaupte einfach mal beides geht(warum testest du das nit 
selber im Avr-Studio ?).
Wobei die erste Version schon besser zu lesen war ;-)

Gruß

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas schrieb:
> Ich bin der Meinung, das beide Schreibweisen das absolut gleiche
> bewirken. Es also egal ist, ob ich die Register erst im up auf den
> Stapel lege/später rette, oder schon in der Service-Routine.

Hallo,

die Frage lautet: ändert ein Call irgendein Register ausser dem 
Programmzähler? Wenn nein, ist es egal. Es gibt einfache Prozessoren, 
bei denen der Programmspeicher segmentiert ist und bei denen daher ein 
long call ein Pointerregister verändert (oder ohne eine solche Änderung 
unmöglich ist), aber deiner gehört meines Wissens nicht dazu.

RTFM: irgendwo muss es eine Beschreibung geben, in der für jeden Befehl 
steht, was er verändert.

Gruss Reinhard

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

Bewertung
0 lesenswert
nicht lesenswert
Es muß immer nur das gerettet werden, was zwischen dem Einsprung in die 
ISR und dem 'reti' verwendet wird. Ob zwischendurch noch eine 
Unterroutine aufgerufen wird, ist völlig egal. Hauptsache, es ist alles 
gesichert und wird später, vor dem 'reti', vom Stack wieder abgeholt. 
Abgesehen davon sollte man Interrupt-Service-Routinen zeitlich so kurz 
wie möglich gestalten, also auch unnötige Sprünge vermeiden, um die 
Hauptschleife nicht zu lange zu blockieren.

Autor: Route_66 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ganz trivial ist die Frage nicht abzutun. Die zweite Variante verbraucht 
mehr Stack-Speicher!!! Bei vielen MC liegen die 
Interrupt-Einsprungstellen an definierten Adressen. Es kann durchaus 
Sinn machen, die ganze Interruptroutine nicht dort unterzubringen. Dann 
sollte man aber mit einem JUMP (evtl. relativ SJMP RJMP JR... -je nach 
Prozessor) zur eigentlichen Routine SPRINGEN und dort nicht mit RET 
sondern mit RETI beenden.
Das ist z.B. bei ATTinys mit begrenztem (Hardware-)Stack 
überlebenswichtig.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ein Unterprogramm macht nur dann Sinn, wenn die Routine mehrfach im 
Programm benötigt wird. Wenn der Aufruf auch aus dem Programm erfolgt, 
ist das Sichern von SREG um Unterprogramm sinnlos. Und da das Sichern 
von SREG (meist) notwendiger Bestandteil einer ISR ist, sollte es auch 
dort erfolgen.

MfG Spess

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ein paar weitere Betrachtungspunkte:

Die ISR soll kurz und schnell sein.

Der AVR hat 32 Register, von denen viele Beginner nur die oberen 16 
verwenden, da sie mit den unteren 16 nix anzufangen wissen. ;-(
Es lohnt sich daher, ein unteres Register exklusiv für die 
SREG-Sicherung zu benutzen.
*IN r2,sreg* / *out sreg,r2*

Ein Unterprogrammaufruf in der ISR ist nur dann sinnvoll, wenn dieses 
Unterprogramm auch von anderen Stellen des Programms aufgerufen wird. 
Ansonsten verplempert der Aufruf lediglich 7 Prozessortakte. Das ist 
erstmal nicht viel, aber es läppert sich zusammen, da ISRs meist recht 
oft aufgerufen werden können. Bei einer Timer-ISR mit 10ms Intervall ist 
das unwichtig, bei Intervallen im µs-Bereich zählt aber jeder Takt.

Viele Aufgaben lassen sich auch außerhalb der ISR erledigen. In der ISR 
werden dann nur flüchtige Werte gesichert und ein Merker gesetzt, der 
von der Mainloop zum bedingten Aufruf eines Jobs ausgewertet wird. 
Dieser Job löscht dann auch den Merker wieder. Sorgt man dafür, dass die 
Jobs kurz und schnell bleiben, dann gibt es keine Probleme (verpasste 
Jobs). Unvermeidliche lange Jobs können ja an geeigneter Stelle die 
Merker der kleinen, oft auftretenden Jobs zusätzlich prüfen und diese 
Jobs mal schnell zwischendurch erledigen.

Mega32...
Nunja, das suggeriert Reserven. Denn das Ding hat viel Flash, 
ausreichend RAM und auch etwas EEP. Das alles verführt dazu, möglichst 
viele Funktionen unterzubringen, aber auch dazu, ineffizient zu 
programmieren. Und betreffs Rechenleistung hat der Mega32 keinerlei 
Vorteile gegenüber kleineren AVRs.

...

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

Bewertung
0 lesenswert
nicht lesenswert
Grüß Dich, Hannes ;-)

Autor: Andreas Heyl (entenkind)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Zahlreichen sinnvollen Antworten. Meine Zweifel sind 
damit endgültig behoben!

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.