Forum: Mikrocontroller und Digitale Elektronik STM32: Problem mit return-Funktion


von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe in meinem Projekt eine Software-Entprellung, die mittels
1
if( hw.semaDebounce->get_And_Reset_If_Larger(10) )
aller 5ms (Zeitbasis sind hier 500µs) eine Tasterauswertung laufen lässt 
und am Ende den Entprellzustand zurück gibt.
Seltsam war aber, dass der Code viel schneller als in 5ms Abständen 
ausgeführt wurde. Nach einer Weile rumprobieren blieb übrig, dass in der 
"return"-Variante anscheinend das Delay übersprungen wird. Denn als ich 
die Funktion testweise mal als "void" setzte, lief das alles 
erwartungsgemäß.
Anbei hab ich mal den AssemblyCode beider Varianten gegenübergestellt 
und dort sieht man, dass die Zeilen 7 bis 9 in der return-Variante 
fehlen. Das ist nämlich genau der Funktionsteil der Delay-Funktion.
(Dort habe ich den Delay so gesetzt, dass ich 1-Sekunden printouts 
bekomme.)

Was für Ideen habt ihr zu diesem Problem und wie kann ich das beheben?

Danke schon mal im Voraus.
Hannes

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


Lesenswert?

Johannes H. schrieb:
> Was für Ideen habt ihr zu diesem Problem und wie kann ich das beheben?

Dass das ohne Kenntnis von zumindest den beiden Funktionen im Ganzen 
kaum zu finden sein dürfte.

von Johannes (menschenskind)


Angehängte Dateien:

Lesenswert?

Hi Jörg,

Ok, ich dachte da gibt's vielleicht nen schnellen Tipp zum Starten...

Also die Entprellfunktion hatte ich dann auf das hier reduziert:
1
PressStates PushButton::debouncePB(void)
2
{  
3
  if(hw.semaDebounce->get_And_Reset_If_Larger(1000) ){ //repeated after 100ms
4
    printf("\n 1second");
5
    return this->pressState;
6
  }
7
}
und
1
void PushButton::debouncePB(void)
2
{  
3
  if(hw.semaDebounce->get_And_Reset_If_Larger(1000) ){ //repeated after 100ms
4
    printf("\n 1second");
5
  }
6
}
Also quasi fast leere Funktionen.

Die Datei mit den Semaphoren habe ich angehängt.

von Εrnst B. (ernst)


Lesenswert?

Und der Code läuft in einer ISR, und kann immer wieder aufgerufen 
werden, während der vorherige Aufruf noch in seinem printf steckt?

von Christian F. (cfrey)


Lesenswert?

Johannes H. schrieb:
1
PressStates PushButton::debouncePB(void)
2
{
3
  if(hw.semaDebounce->get_And_Reset_If_Larger(1000) ){ //repeated after 100ms
4
    printf("\n 1second");
5
    return this->pressState;
6
  }
7
}

Hier fehlt ein return-Statement falls die Bedingung nicht erfüllt ist. 
Das ist "Undefined Behavior".

von Stefan F. (Gast)


Lesenswert?

Aktiviere mal alle Warnungen des Compiler (-Wall), könnte helfen.

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


Lesenswert?

Εrnst B. schrieb:
> Und der Code läuft in einer ISR, und kann immer wieder aufgerufen
> werden, während der vorherige Aufruf noch in seinem printf steckt?

Naja, das printf wird ja hoffentlich keine Sekunde brauchen. ;-) Ich 
hätte aber da auch lieber 'ne LED blinken lassen.

Johannes H. schrieb:
> Also die Entprellfunktion hatte ich dann auf das hier reduziert:

Kannst du nicht doch irgendwie was mehr posten? In deiner Disassembly da 
oben fehlen beispielsweise die Adressen, sodass ich keine Idee habe, 
wohin einzelne der Sprünge da gehen. Vermutlich fehlen da auch noch 
relevante Teile des Codes, da sie außerhalb deines kleinen Ausschnitts 
sind. Kannst du vielleicht die zugehörigen .o-Dateien posten?

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


Lesenswert?

Christian F. schrieb:
> Das ist "Undefined Behavior".

Das allein könnte natürlich bereits Ungemach erklären. ;-)

von Johannes (menschenskind)


Lesenswert?

Christian F. schrieb:
> Hier fehlt ein return-Statement falls die Bedingung nicht erfüllt ist.
> Das ist "Undefined Behavior".
Ohje... Es lag tatsächlich daran.

@Stefan
Die Option war bereits aktiviert und ich hatte dort am Ende der Funktion 
auch eine Warnung eingeblendet:
> control reaches end of non-void function [-Wreturn-type]
Aber nicht gedacht, dass das ein Problem sein könnte. Jetzt bin ich 
schlauer.

Also vielen Dank fürs korrekte Draufzeigen.

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.