AVR-GCC warning: return type defaults to 'int' + ISR_NAKED

Gast #5779256
Lesenswert?

Hallo,

ich versuche, eine enge und schnelle Interrupt Routine zu bauen - nur 
einen Wert auf ein IO-Register nageln.
1
#include <avr/interrupt.h>
2
ISR(TCC4_CCB_vect)
3
{
4
       VPORT2.DIR = portd_dir_mpx_drive;
5
}
Paßt soweit, erzeugt aber Standardprolog und -epilog (push Status, push 
R1 , ...).

Baue ich das als ISR_NAKED (dann mit inline asm)
1
ISR(TCC4_OVF_vect, ISR_NAKED) 
2
{
3
    asm volatile(
4
        "push   r24"  ); 
5
    asm volatile(
6
        "out    %0, %1"      "\n\t"
7
        :
8
        : "i" (_SFR_IO_ADDR(VPORT2.DIR)), "r" (portd_dir_mpx_drive) 
9
        :               // no clobber here
10
        );
11
    asm volatile(
12
        "pop  r24"         "\n\t"
13
        "reti"               "\n\t"
14
        );
15
}
bekomme ich zwar den gewünschte knappen Code (Status register muß ich ja 
nicht pushen, lds und out verändert da nichts), aber auch die Warnung:
Warning    type of '__vector_12' defaults to 'int' [-Wimplicit-int]

Wie bekomme ich diese warning weg?

Viele Grüße Wolfgang
Moderator Persönliche Seite #5779275
Lesenswert?

Hmm, ich habe deinen Code mal mit
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
uint8_t portd_dir_mpx_drive;

ergänzt und mit -Os -mmcu=atxmega32e5 -Wall -Wextra compiliert – ohne 
jegliche Warnungen und mit dem gewünschten Ergebnis.

Davon abgesehen, wäre es hier nicht einfacher, das gleich in eine 
.S-Datei auszulagern, wenn du die ISR sowieso letztlich komplett als 
Assemblercode hinlegst?
Gast #5779482
Lesenswert?

Hallo,

mein Fehler. Ich hatte die ursprüngliche ISR (halt ohne das Keywort ISR) 
gleich dahinter nochmal stehen, und eigentlich hat der Compiler dort 
gemeckert.

Richtig, es ist ein xmega e5, ürsprünglich wollte ich das Thema mit 
Comparechannels lösen. Nur hat Atmel/Microchip den Prozessor kastriert - 
Auf Port D gibt es keinen Timer für die Ports 0..3. Okay, dann halt mit 
DMA - grml, dieser EDMA (E soll enhanced bedeutet) is eher ein RDMA 
(reduced): Trigger des DMA geht im Peripheral-Mode nur aus ausgewählten, 
wenigen Quellen und im Standardmode sind es nur 2 Channels. Also 
Interrupt. Zu viel Jitter, zu lange Totzeit.

Dann quasi der letzte Rettungsanker: asm. Wegen der paar Zeile wollte 
ich jetzt kein extra Modul bauen, das ins make/git packen usw.

Danke nochmal

Wolfgang
Persönliche Seite #5830706
Lesenswert?

Wolfgang schrieb:
> erzeugt aber Standardprolog und -epilog (push Status, push R1 , ...).

Schon mal eine aktuelle Compilerversion versucht (v8 oder neuer)?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3

4
volatile uint8_t portd_dir_mpx_drive;
5

6
ISR (TCC4_CCB_vect)
7
{
8
    VPORT2.DIR = portd_dir_mpx_drive;
9
}

erzeugt etwa (-Os -mmcu=atxmega32e5):
1
000000ce <__vector_15>:
2
  ce:  8f 93         push  r24
3
  d0:  80 91 00 20   lds  r24, 0x2000
4
  d4:  88 bb         out  0x18, r24
5
  d6:  8f 91         pop  r24
6
  d8:  18 95         reti

Wolfgang schrieb:
> Dann quasi der letzte Rettungsanker: asm.

Dann aber korrekt, zum Beispiel so (dass dein Code wie gewünscht 
übersetzt wird bedeutet nicht, dass die Quelle korrekt ist :-))
1
ISR (TCC4_OVF_vect, ISR_NAKED) 
2
{
3
    asm volatile (
4
        "push  r24"         "\n\t" 
5
        "lds   r24, %1"     "\n\t"
6
        "out   %i0, r24"    "\n\t"
7
        "pop   r24"         "\n\t"
8
        "reti"
9
        :
10
        : "n" (&VPORT2.DIR), "i" (&portd_dir_mpx_drive)
11
        : "r24", "memory");

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren