Warning in C

Gast #5802647
Lesenswert?

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 #5802659
Lesenswert?

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) #5802666
Lesenswert?

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 #5802672
Lesenswert?

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 #5802743
Lesenswert?

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

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