Attribute und pointer-type

OP Persönliche Seite #425653
Lesenswert?

Hallo zusammen!

Ich habe da ein kleines Verständnisproblem mit den GCC-Attributen für 
Typen.
Ich möchte eine Callbackfunktion auf einem AT91SAM7S64 ins RAM 
verlagern, wobei ich folgendes Makro verwende:
1
#define __ramfunc __attribute__ ((long_call, section (".fastrun")))

Das "Event" wird in die Timeoutqueue eines kleinen, aber sehr 
nützlichen, Tools von Jörg Wunsch (das Bier hast Du Dir wirklich 
verdient ;) wie folgt eingelassen:
1
  /* Enable displayclock: */
2
  timeout(1000, showclock, (union timeoutarg) NULL);

Die Implementation der Callbackfunktion sieht so aus:
1
/* Callback function for the clock: */
2
__ramfunc void
3
showclock(union timeoutarg targ)
4
{
5
        time_t timer;
6
        struct tm *ltime;
7

8
        /* retrigger displayclock: */
9
        timeout(1000, showclock, (union timeoutarg)NULL);
10

11
        timer = lt_copy + (clock()/1000);
12
        ltime = localtime(&timer);
13

14
        /* fancy clock - this should get a prompt one day ;-) */
15
        rprintf(" [%02d:%02d:%02d] %u:/>\r", ltime->tm_hour, ltime->tm_min, ltime->tm_sec, dmxStartAddress);
16
}

Die Warnung des Compilers dann so:
1
main.c:325: warning: passing argument 2 of 'timeout' from incompatible pointer type

Meine Fragen:

  1. Wo gehört "__attribute__" hin?
     - vor den Prototypen
     - hinter den Prototypen
     - vor den Funktionsrumpf
     - hinter die schliessende Klammer der Argumentliste
     - vor/hinter Prototyp und Funktionsrumpf
  2. Warum verändert es den Pointertypen?
  3. Wäre ein Cast hier richtig?
Moderator Persönliche Seite #425661
Lesenswert?

Patrick Dohmen wrote:

>   1. Wo gehört "__attribute__" hin?
>      - vor den Prototypen
>      - hinter den Prototypen
>      - vor den Funktionsrumpf
>      - hinter die schliessende Klammer der Argumentliste
>      - vor/hinter Prototyp und Funktionsrumpf

Hmm, ich mache es immer so:
1
rettype myfunc(arglist) __attribute__((...));
2
rettype
3
myfunc(arglist)
4
{
5
  /* implementation */
6
}
Ich bin mich nicht sicher, welche Wege es noch gäbe.

>   2. Warum verändert es den Pointertypen?

"Das ist eben so." :-)

Naja, auch derjenige, der die Callback-Funktion ruft, muss ja
u. U. darüber etwas wissen.  Wenn ich das richtig sehe (kenne mich mit
ARM nicht aus), verlässt du ja damit den normalen Weg, wie der
Compiler einen indirekten Funktionsaufruf zusammenbasteln würde.
Damit muss er natürlich auch innerhalb des Timeout-Handlers wissen,
dass er anderen Code generieren soll.

>   3. Wäre ein Cast hier richtig?

Erst einmal nicht.  Richtig wäre es, die Attribute auch in der
Timerqueue sauber mitzuführen.  Ob der Cast tolerierbar wäre, hängt
letztlich davon ab, ob meine bei 2. genannten Ausführungen tatsächlich
Auswirkungen auf den generierten Code haben oder nicht.
OP Persönliche Seite #425689
Lesenswert?

Jörg Wunsch wrote:

>>   3. Wäre ein Cast hier richtig?
>
> Erst einmal nicht.  Richtig wäre es, die Attribute auch in der
> Timerqueue sauber mitzuführen.  Ob der Cast tolerierbar wäre, hängt
> letztlich davon ab, ob meine bei 2. genannten Ausführungen tatsächlich
> Auswirkungen auf den generierten Code haben oder nicht.

Das heist also, ich müsste den Funktionsprototypen aus "timer.h" 
umbauen...
1
/* the action function itself */
2
typedef void (*timeout_t)(union timeoutarg);

...wird zu:
1
/* the action function itself */
2
typedef void (*timeout_t)(union timeoutarg) __ramfunc;

Ich werd's mal ausprobieren!
OP Persönliche Seite #429422
Lesenswert?

So funktioniert es:

1. Funktionspointer
1
/* the action function itself */
2
typedef __attribute__ ((long_call)) void (*timeout_t)(union timeoutarg);

2. Funktionsprototyp für callback Implementation
1
/* callback functions */
2
__ramfunc void showclock(union timeoutarg targ);

3. Funktionsdeklaration
1
__ramfunc void
2
showclock(union timeoutarg targ)
3
{
4
    [...]
5
}

Stelle ich die Attribute ans Ende, wird immer wieder 'redeclaration' 
bemängelt.
Seltsame Sache...

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