Forum: Compiler & IDEs AVR-GCC warning: return type defaults to 'int' + ISR_NAKED


von Wolfgang (Gast)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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?

von Wolfgang (Gast)


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

von Johann L. (gjlayde) Benutzerseite


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");

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.