Forum: Mikrocontroller und Digitale Elektronik Warning in C


von Fragender (Gast)


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?

von Thomas (Gast)


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.

von Timm R. (Firma: privatfrickler.de) (treinisch)


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

von fop (Gast)


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.

von leo (Gast)


Lesenswert?

Fragender schrieb:
> & LockButtonPressed

weiters meinst du wahscheinlich "logisches und" &&.

leo

von Fragender (Gast)


Lesenswert?

leo schrieb:
> Fragender schrieb:
>> & LockButtonPressed
>
> weiters meinst du wahscheinlich "logisches und" &&.
>
> leo

ähmm jopp, danke für den Hinweis ;)

Danke auch allen anderen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

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.