Forum: Compiler & IDEs ATMega2560 Schnelle Interrupts in ASM aus C


von Franz (Gast)


Lesenswert?

HI !

Ich brauche einen dauernd laufenden seriellen I/O Strom und benutze 
dafür den USART1 des ATMega2560. Zum Programmieren benutze ich Atmel 
Studio.

Wenn ich meine Interruptroutine für USART Buffer empty direkt in C 
programmiere
ISR(xyx_vect)
{
}

dann funktionierts aber nur mit 250kHz da der Compiler fetten pro/epilog 
code macht der schon alle 60 Takte benutzt die ich für den Interrupt 
reserviert habe. Ich muss mit 1MHz raustakten und lesen und nebenbei 
noch einen zweiten UART bedienen.

Mit der directive "register unsigned char <var> asm("rxx");" blockier 
ich mir die register die ich in der Interruptroutine brauche und somit 
könnte ich die ganze push/pop action vergessen.

Soweit ok, aber wie sage ich jetzt dem compiler:
1) Häng mir einen Vector ein
  -> Habs mit .org Vector und jmp Vector probiert => wird ignoriert ?
2) Optimier mir nicht den INT Assemblercode weg ?

Kurz: Gesucht wird die Möglichkeit C/C++ code mit einer schnellen 
Interruptroutine in Assembler zu kombinieren ohne sich die Finger mit 
inline assembler zu brechen. Könnte mir jemand ein Beispiel zeigen 
(bitte nicht http://nongnu.org/avr-libc/user-manual/group__asmdemo.html) 
verlinken, da fehlt genau diese info :)

Thanks in advance
Franz

von Peter II (Gast)


Lesenswert?

Franz schrieb:
> ISR(xyx_vect)
> {
> }
>
> dann funktionierts aber nur mit 250kHz da der Compiler fetten pro/epilog
> code macht der schon alle 60 Takte benutzt die ich für den Interrupt
> reserviert habe.

das ist nur der fall wenn du in der ISR selber Funktionen aufrufst.

Zeigt uns bitte dafür ein Beispiel!

von holger (Gast)


Lesenswert?

>Ich muss mit 1MHz raustakten und lesen und nebenbei
>noch einen zweiten UART bedienen.

Kauf dir mal nen Arm. Irgendwo ist halt mal Schluss
mit lustig mit nem schlappen Atmega.

von Peter D. (peda)


Lesenswert?

Franz schrieb:
> Ich muss mit 1MHz raustakten

Das sind 128 Zyklen bei 16MHz, sollte auch in C leicht zu schaffen sein.

Du hast vermutlich Unterfunktionsaufrufe im Handler, die Dir den Code 
aufblähen.
Oder mehrfache Pointer-Indirektionen, die der AVR erst mühsam berechnen 
muß. Sowas ist nicht seine Stärke. Er mag flache Strukturen, am besten 
feste Adressen (LDS/STS).

von Oliver (Gast)


Lesenswert?

Franz schrieb:
> (bitte nicht http://nongnu.org/avr-libc/user-manual/group__asmdemo.html)
> verlinken, da fehlt genau diese info :)

In C über ISR_NAKED,

guugst du hier:
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Oder in Assembler, guggst du hier:
http://www.nongnu.org/avr-libc/user-manual/assembler.html

Wobei, wie schon gesagt wurde, der Compiler nur die Register rettet, die 
auch wirklich benötigt werden, solange du keinen Funktionsaufruf in der 
ISR benutzt. Wenn doch, dann muss der halt alle Register retten, und das 
dauert.

Oliver

von amateur (Gast)


Lesenswert?

@ Franz

Unter der von Dir abgelehnten Internetseite:
http://nongnu.org/avr-libc/user-manual/

gibt es einen Link:
"Example Projects"
unter dem Deine Problematik behandelt wird.

Ebenfalls auf der von Dir abgelehnten Seite findest Du unter:
"FAQ"
Informationen darüber, wie C mit den Registern umgeht.

Das sollte eigentlich ausreichend sein. Ist allerdings mit etwas Arbeit 
verbunden - leider.

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.