Forum: Mikrocontroller und Digitale Elektronik Atmel Studio 7 hier: Warnung function with qualified void return type called


von Bernd E. (berecke)


Lesenswert?

Ich bekomme in einer Interruptroutine in einem Programmteil:
1
// receiver interrupt
2
ISR(RX_INT_VEC) {
3
    unsigned char data = RF01_RDFIFO(); // read received data
4
    sei(); // stop blocking interrupt
5
    // handle data without having to wait
6
    (*dataReceiverPtr)(data) // <--- genau hier;

die folgende Warnung: "function with qualified void return type called".

Nur an den folgenden Stellen taucht im Programm noch "dataReceiverPtr" 
auf:
1
// pointers voor data handling functions
2
volatile void (*dataReceiverPtr)(unsigned char);
3
4
// set the function to call when the receiver has a new byte
5
void setDataReceiver(void (*dataReceiver)(unsigned char) ) {
6
    dataReceiverPtr = (volatile void (*)(unsigned char))dataReceiver;
7
}

Ich tue mich mit Pointer und hier vermutlich Funktions-Pointern schwer. 
Kann mir jemand kurz die Bedeutung erläutern und wie ich die Warnung 
abstellen kann.

von Curby23523 N. (Gast)


Lesenswert?

Warum gibst du in einem Interrupt mit sei(); die Interrupts überhaupt 
erst frei? Wie willst du da reinkommen, wenn die Interrupts zuvor global 
gesperrt sind?

Was ist "dataReceiverPtr"?

von Dr. Sommer (Gast)


Lesenswert?

Der Rückgabetyp deines Funktionszeigers ist "volatile void". Das macht 
wenig Sinn. Vermutlich meintest du, dass die Variable die den 
Funktionszeiger enthält selber volatile sein soll? Das geht so:
1
void (*volatile dataReceiverPtr)(unsigned char);
Dann ist auch der cast in setDataReceiver nicht mehr nötig.

Mithilfe von Type-Aliasen geht das einfacher & übersichtlicher:
1
typedef void (*funPtr)(unsigned char);
2
3
volatile funPtr dataReceiverPtr;
4
5
void setDataReceiver(funPtr dataReceiver) {
6
    dataReceiverPtr = dataReceiver;
7
}

von Bernd E. (berecke)


Lesenswert?

Nils H. schrieb:
> Warum gibst du in einem Interrupt mit sei(); die Interrupts überhaupt
> erst frei? Wie willst du da reinkommen, wenn die Interrupts zuvor global
> gesperrt sind?

Das Programm ist nicht von mir und ich versuche mich dort einzuarbeiten. 
Danke für den Hinweis mit "sei()", das ist sicherlich falsch und sollte 
vermutlich cli() heißen.

Nils H. schrieb:
> Was ist "dataReceiverPtr"?

Ich denke, dass das ein Zeiger auf eine Funktion ist, die die Daten vom 
Receiver abholt.

Dr. Sommer schrieb:
> Der Rückgabetyp deines Funktionszeigers ist "volatile void". Das macht
> wenig Sinn. Vermutlich meintest du, dass die Variable die den
> Funktionszeiger enthält selber volatile sein soll?

Danke für die schnell Antwort, aber den Teil muss ich mir erstmal durch 
den Kopf gehen lassen. Der erste schnell Aufschlag hat noch nicht 
funktioniert und weitere Fehlermeldungen verursacht. Aber ich meine 
auch, dass hier die Herausforderung liegt.

von Dr. Sommer (Gast)


Lesenswert?

Bernd E. schrieb:
> Danke für den Hinweis mit "sei()", das ist sicherlich falsch und sollte
> vermutlich cli() heißen.
Das wäre noch sinnloser. Bei Aufruf einer ISR werden die Interrupts 
automatisch gesperrt, beim Verlassen wieder aktiviert ("reti" 
Instruktion).
Man kann die mit sei() wieder aktivieren, um verschachtelte Interrupts 
zu ermöglichen, was aber diverse Probleme mit sich bringt wenn ich mich 
recht erinnere.

Bernd E. schrieb:
> Der erste schnell Aufschlag hat noch nicht
> funktioniert und weitere Fehlermeldungen verursacht.
Also bei mir kompiliert meine Version. Dann ist bei dir vermutlich noch 
mehr falsch. Ich glaube kaum, dass die Original-Version korrekt ist. 
"volatile void" ist halt sinnlos, was soll das sein - ein Wert bei dem 
man die Zugriffe nicht wegoptimeren darf, aber auf den man gar nicht 
zugreifen kann weils ein void ist?

von Thomas E. (thomase)


Lesenswert?

Bernd E. schrieb:
> Danke für den Hinweis mit "sei()", das ist sicherlich falsch und sollte
> vermutlich cli() heißen.

Die globalen Interrupts sind während der Abarbeitung der ISR gesperrt 
und werden beim Verlassen wieder freigegeben. Das sei() an dieser Stelle 
macht die ISR dagegen für andere Interrupts unterbrechbar. Ein cli() 
wäre hier Blödsinn, da die Interrupts ohnehin gesperrt sind.

: Bearbeitet durch User
von Bernd E. (berecke)


Lesenswert?

Dr. Sommer schrieb:
> Das wäre noch sinnloser. Bei Aufruf einer ISR werden die Interrupts
> automatisch gesperrt, beim Verlassen wieder aktiviert ("reti"
> Instruktion).

Stimmt! Ist Quark. Leider besteht das Projekt aus 14 Einzeldateien und 
da muss ich mich erst einmal durch arbeiten. Der Befehl "sei()" ist aber 
vordergründig nicht die Ursache der Warnung. Den nehme ich mir später 
vor.

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.