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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bernd E. (berecke)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (Firma: Thomas Eckmann Informationst.) (thomase)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.