mikrocontroller.net

Forum: Compiler & IDEs naked ISR + register inc. SREG speichern ?


Autor: Frank Roch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe eine counter Variable die bei mir in Register r2:r3 liegt.
Diese wird bei einem "timer compare interrupt" um 1 erhöht.

Da dieser Interrupt häufig aufgerufen wird versuche ich den
Interrupt-Aufruf 'abzuspecken' (naked interrupt).

register uint16_t counter asm("r2");

__attribute__((naked)) ISR(TIM1_COMPA_vect)
{
  counter++;
  asm volatile ( "reti" );
}

Da counter in einem Register liegt brauche ich die standard Interrupt
Pro,Eplioge ja vorrauss. nicht. Sehe ich das richtig ?

Muss ich evtl. doch Register speichern (SREG für Carry) ?

Danke..

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst alles sichern, was du kaputt machst.  SREG gehört dazu,
ja.

__attribute__((naked)) und ISR() sind gemeinsam sinnlos: hinter
ISR steht ja weiter nichts als __attribute__((signal)), und das
will etwas anderes tun als __attribute__((naked)).

Eigentlich kommst du besser, wenn du die ganze ISR gleich in eine
separate Assemblerdatei legst, statt dich im Compilerverbiegen und
inline-Assemblieren zu üben.  Das Ergebnis dürfte allemal
übersichtlicher sein.

Autor: Frank Roch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die antwort ..

habe gerade bemerkt dass die verlegung des counters in ein register
schon automatisch die ISR optimiert :)

//////////////// von counter im RAM:

ISR(TIM1_COMPA_vect)
{
 ae2:  1f 92         push  r1
 ae4:  0f 92         push  r0
 ae6:  0f b6         in  r0, 0x3f  ; 63
 ae8:  0f 92         push  r0
 aea:  11 24         eor  r1, r1
 aec:  8f 93         push  r24
 aee:  9f 93         push  r25
  counter++;
 af0:  80 91 83 00   lds  r24, 0x0083
 af4:  90 91 84 00   lds  r25, 0x0084
 af8:  01 96         adiw  r24, 0x01  ; 1
 afa:  90 93 84 00   sts  0x0084, r25
 afe:  80 93 83 00   sts  0x0083, r24
 b02:  9f 91         pop  r25
 b04:  8f 91         pop  r24
 b06:  0f 90         pop  r0
 b08:  0f be         out  0x3f, r0  ; 63
 b0a:  0f 90         pop  r0
 b0c:  1f 90         pop  r1
 b0e:  18 95         reti

//////////////// auf counter im REG:

ISR(TIM1_COMPA_vect)
{
 ac6:  1f 92         push  r1
 ac8:  0f 92         push  r0
 aca:  0f b6         in  r0, 0x3f  ; 63
 acc:  0f 92         push  r0
 ace:  11 24         eor  r1, r1
  counter++;
 ad0:  08 94         sec
 ad2:  21 1c         adc  r2, r1
 ad4:  31 1c         adc  r3, r1
 ad6:  0f 90         pop  r0
 ad8:  0f be         out  0x3f, r0  ; 63
 ada:  0f 90         pop  r0
 adc:  1f 90         pop  r1
 ade:  18 95         reti

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist trotzdem seltsam, wieso in der zweiten Version nicht auch ein "adiw" 
genutzt wird, so würde die ISR noch viel kürzer...?

//////////////// auf counter im REG:

ISR(TIM1_COMPA_vect)
{
    push  r0
    in   r0, 0x3f  ; 63
    push  r0
    adiw  r2, 0x01  ; 1 //   counter++;
    pop   r0
    out   0x3f, r0  ; 63
    pop   r0
    reti
}

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oups, alles klar!

"adiw" geht ja nur mit r24, r26, r28 und r30

Und diese Register sollten nicht ständig mit dem Counter-Wert besetzt 
sein!





Autor: Frank Roch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte man theoretisch das innerste push und pop für r0 weglassen ?
Kommt mir irgendwie sinnlos vor...

ISR(TIM1_COMPA_vect)
{
 ac6:  1f 92         push  r1
 ac8:  0f 92         push  r0
 aca:  0f b6         in  r0, 0x3f  ; 63
 ace:  11 24         eor  r1, r1
  counter++;
 ad0:  08 94         sec
 ad2:  21 1c         adc  r2, r1
 ad4:  31 1c         adc  r3, r1
 ad8:  0f be         out  0x3f, r0  ; 63
 ada:  0f 90         pop  r0
 adc:  1f 90         pop  r1
 ade:  18 95         reti

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Könnte man theoretisch das innerste push und pop für r0 weglassen?

Nö, damit würdest du ja jedem anderen das r0 klauen, der es gerade
in Beschlag hat.

Das push/pop und xor von r1 könnte man im Prinzip weglassen -- wenn
es nicht die leidige Multiplikation gäbe, die dieses Register
verändert.  Ansonsten ist es im Compiler immer gleich 0.

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.