www.mikrocontroller.net

Forum: Compiler & IDEs Inline assembler


Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Frage an die GCC-Profis.

Ich hab jetzt mal versucht, schnelle Interrupts mit Inline-Assembler zu
schreiben.
Die Syntax ist zwar etwas gewöhnungsbedürftig, aber sonst klappt das
ganz prima.

Bloß leider wird trotzdem diese ganze PUSH/EOR/POP-Arie eingefügt, was
ja allein schon mal 15 Zyklen wegfrißt, also die Interruptzeit fast
verdoppelt.

Kann man denn garnichts dagegen tun ?

Warum wird auch ausgerechnet R1 als Null genommen und somit diese ganze
Arie erst notwendig (wegen MUL-Befehl). Jedes andere (R3..R15) ist doch
wesentlich besser geeignet.
Und wenn man schon ein Null-Register reserviert, dann könnte man auch
gleich eins fürs SREG sichern reservieren.
In Assembler habe ich das immer so gemacht und das bringt sogar weitaus
mehr als das Null-Register.

Damit würde sich nämlich die Interruptrahmenzeit von 25 auf 12 Zyklen
verringern !


Peter

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich hab jetzt mal versucht, schnelle Interrupts mit Inline-Assembler
> zu schreiben.

Warum dann nicht gleich komplett in Assembler?

> Kann man denn garnichts dagegen tun ?

__attribute__((naked)) kennst Du aber, oder?

> Warum wird auch ausgerechnet R1 als Null genommen...

Da mußt Du mal die Designer fragen, Denis und vielleicht auch Marek.
Möglicherweise haben sie diese Entscheidung getroffen, als es noch
keine AVRs mit Hardwaremultiplizierer gab.

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke Joerg,

"Warum dann nicht gleich komplett in Assembler?"

Ich will die #define und Variablen aus den C-Files mitverwenden und
nicht zusätzliche .equ definieren müssen.


"__attribute__((naked)) kennst Du aber, oder?"

Bisher noch nicht.
Ich hatte noch ne ältere signal.h, da war das EMPTY_INTERRUPT noch
nicht drin. Die jetzige ist vom 10.9.03 0:24Uhr, damit ergibt sich aber
folgender Fehler:

TEST.C:7: error: parse error before '{' token



Peter

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal in die signal.h:

#define EMPTY_INTERRUPT(signame)                \
void signame (void) __attribute__((naked)) ;           \
void signame (void) { _asm__ __volatile_ ("reti" ::); }

EMPTY_INTERRUPT ist also für leere Interrupthandler vorgesehen.
Probier's mal damit:

SIGNAL(SIG_OVERFLOW0) __attribute__((naked))
{
  ...
}

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> EST.C:7: error: parse error before '{' token

Ja, siehe Doku:

    Defines an empty interrupt handler function. This will not
    generate any prolog or epilog code and will only return from the
    ISR. Do not define a function body as this will define it for you.

Nein, Du brauchst eher sowas wie

SIGNAL(SIG_FOO) __attribute__((naked));

SIGNAL(SIG_FOO) {
  ...
  asm volatile("reti");
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Joerg, das hats gebracht.

Mit Assembler, Registervariablen und "Nacktheit" habe ich nun die
Interrupts 3* schneller gekriegt !
D.h. unter reinem C hätte ich einen 30MHz Quarz gebraucht.

Wie es scheint sind die Register R2..R13 unbenutzt, d.h. sie können für
Variablen genutzt werden. Leider gibt es aber keinen Linkerfehler, wenn
man ein schon anderweitig benutztes Register als Variable nimmt.


Peter

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie es scheint sind die Register R2..R13 unbenutzt, d.h. sie können
> für Variablen genutzt werden.

Der Compiler würde sie benutzen, wenn er Bedarf an Registern hat.

> Leider gibt es aber keinen Linkerfehler, wenn man ein schon
> anderweitig benutztes Register als Variable nimmt.

Das ist jenseits dessen, was der Linker zu sehen bekommt.

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.