Warning in C

Gast #5802647
Im Interrupt Systick Handler habe ich eine Variable debounceCounterLOCK
1
void SysTick_Handler(void)
2
{
3
  
4
  if(DiffAcValue.KEY1 > SWITCHING_THRESHOLD_LOCK_PRESSED)
5
  {
6
    debounceCounterLOCK++;
7
  }
8
}

Die Variable habe ich in einem c-file definiert:

volatile uint16_t debounceCounterLOCK = 0;

In einer Funktion im main mache ich Folgendes:
1
void handleTouchkeys(void)
2
{
3

4
    if((DiffAcValue.KEY1 <= SWITCHING_THRESHOLD_LOCK_UNPRESSED) & LockButtonPressed)
5
    {
6
        lockButtonPressed = false;
7
    }
8
    
9
    if(debounce(DiffAcValue.KEY1, MAXVALUE_DEBOUNCECOUNTER, SWITCHING_THRESHOLD_LOCK_PRESSED, &debounceCounterLOCK) & !lockButtonPressed)
10
    {
11
        lockButtonPressed = true;
12
    }

Der Funktionsprototyp sieht folgendermassen aus:
bool debounce(uint16_t sensorValue, uint16_t maxDebounceCounter, 
uint16_t switchingThreshold, uint16_t *debounceCounter);

Ich bekomme nun den Fehler:
../Src/main.c(165): warning:  #167-D: argument of type "volatile 
uint16_t *" is incompatible with parameter of type "uint16_t *"

Was ist das Problem? Ich verstehe nicht was hier gemeint ist.
Warum kann ich eine volatile Variable nicht per Pointer übergeben?
Gast
Fragender schrieb:
> Was ist das Problem? Ich verstehe nicht was hier gemeint ist.
> Warum kann ich eine volatile Variable nicht per Pointer übergeben?

Der Compiler sagt dir schon, dass uint16_t* und volatile uint16_t* 
verschiedene Typen sind. Die Vertrag deiner debounce() Funktion 
verwendet einen uint16_t*. Die Funktion darf also Zugriffe auf die 
referenzierte Adresse optimieren. Wenn du bspw. debounce() in einer 
Schleife aufrufen würdest und der Compiler die Funktion inlined, dann 
könnte er den eigentlichen LOAD des uint16_t nur einmal in der 
Schleifeninitialisierung machen und anschließend wird immer der alte 
(selbe) Wert genommen.

volatile schaltet diese Optimierungen aus, d.h. der Compiler weiß nun, 
dass immer in jedem Schleifendurchlauf der Speicher geladen werden muss. 
Deshalb sind z.B. Register-Aliase immer volatile, da sie ggf. von der 
Hardware geändert werden oder es andere Seiteneffekte gibt.

Eine mögliche Lösung: verwende einen volatile uint16_t*.
Alternativ könntest du statt dem volatile uint16_t* den uint16_t direkt 
übergeben. D.h. der Zählerwert (volatile) wird ausgelesen und eine Kopie 
(ohne volatile) davon an debounce() übergeben.
(Firma: privatfrickler.de)
Fragender schrieb:


> Ich bekomme nun den Fehler:
> ../Src/main.c(165): warning:  #167-D: argument of type "volatile
> uint16_t *" is incompatible with parameter of type "uint16_t *"
>
> Was ist das Problem? Ich verstehe nicht was hier gemeint ist.

das ist wirklich ein Problem, so exakte Fehlermeldungen sind nicht immer 
die Regel.

Die Meldung bedeutet, dass Argumente vom Typ s.o. nicht kompatibel zu 
Parametern vom Typ s.o. sind.

> Warum kann ich eine volatile Variable nicht per Pointer übergeben?

selbstverständlich kannst du das. Aber nicht für einen nicht volatile •.

Ersetze volatile mal durch const, ist zwar genau so ein Unsinn, aber 
dann siehst du vlt. besser, wo das Problem ist.

Viele liebe Grüße
Timm

Edit: zu langssm sry
Gast
Du übergibst die Variable debounceCounterLOCK an eine Funktion, dabei 
geht ihre Eigenschaft volatile verloren.
Klar debounceCounterLOCK wird nur einmal beim Aufruf der Funktion 
abgerufen und mit diesem Wert wird den ganzen Funktionsdurchlauf über 
gearbeitet.

Die Warnung soll Dich anregen, nachzugrübeln, ob das so gewollt ist.

Wenn Du das Verhalten so toll findest und die Warnung los werden willst, 
hilft ein Typecast beim Funktionsaufruf :
1
(uint16_t)debounceCounterLOCK

Ansonsten müsstest Du einen Zeiger auf eine volatile Variable an die 
Funktion übergeben, um den Zugriff auf das Original bei jeder Erwähnung 
beizubehalten.
Moderator Persönliche Seite
fop schrieb:
> Wenn Du das Verhalten so toll findest und die Warnung los werden willst,
> hilft ein Typecast beim Funktionsaufruf :(uint16_t)debounceCounterLOCK

Genauer:
1
(uint16_t *)&debounceCounterLOCK

Das drückt dem Compiler aus, dass du drüber nachgedacht hast und der 
Meinung bist, dass die "volatileness" der Variablen innerhalb der 
aufgerufenen Funktion nicht wesentlich ist.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.