Forum: Compiler & IDEs ungewollte Optimierung in Nebenläufigkeit


von Manuel (Gast)


Lesenswert?

Hallo zusammen!

Bin gerade dabei mich etwas mit freeRTOS auf dem ATMega32 zu 
beschäftigen.
Dazu habe ich einen Task erstellt, der eine LED ständig ein- und 
ausschalten soll, indem er auf die entsprechende Position im 
PINx-Register eine 1 schreibt.
(Datenblatt: Writing a logic one to PINxn toggles the value of PORTxn, 
independent on the value of DDRxn.)

Der Task sieht dementsprechend so aus:

void prvLEDTest(void *pvParameters )
{
  while(1) {
    PIND = (1<<5);
    vTaskDelay(100);
  }
}

Das Problem ist, dass der Compiler dieses wegen "Unsinnigkeit" 
wegoptimiert.
PIND ist wie folgt definiert: #define PIND    _SFR_IO8(0x10)

Dementsprechend kann ich hier soviel, ich weiß auch nicht mit 'volatile' 
arbeiten...


Ich bin euch für jeden Tip und Ratschlag zur Lösung dieses Problems 
dankbar und hoffe dass ihr mir hier weiterhelfen könnt.


Gruß
Manu

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


Lesenswert?

Manuel wrote:

> Das Problem ist, dass der Compiler dieses wegen "Unsinnigkeit"
> wegoptimiert.

> PIND ist wie folgt definiert: #define PIND    _SFR_IO8(0x10)

...und _SFR_IO8 markiert das Register als volatile.  Daran liegt es
also nicht.

Kann es sein, dass du ihn irgendwie auf aggressive Optimierung
gestellt hast und dass er die komplette Funktion eliminiert, weil er
nicht erkennen kann, dass sie irgendwo benutzt wird?  Dagegen würde
ggf. ein __attribute__((used)) helfen.

von Andreas K. (a-k)


Lesenswert?

> (Datenblatt: Writing a logic one to PINxn toggles the value of PORTxn,
> independent on the value of DDRxn.)

Aus dem Datasheet vom Mega32 wirst du das Zitat kaum haben. Diese 
Funktionalität ist das erste Mal beim deutlich neueren Tiny2313 in 
Erscheinung getreten, davor war PINx readonly, was im Datasheet vom 
Mega32 auch so drinsteht.

Könnte es sein, dass genau dies dein Problem ist? Vermuteter 
Compilerfehler weil Programm verhält sich nicht so wie erwartet?

von Uhu U. (uhu)


Lesenswert?

Wie immer in solchen Fällen hilft ein kurzer Blick in das ASM-Listing 
des Compilers oder das Disassembly-Fenster des Debuggers.

von Rolf Magnus (Gast)


Lesenswert?

> Kann es sein, dass du ihn irgendwie auf aggressive Optimierung
> gestellt hast und dass er die komplette Funktion eliminiert, weil er
> nicht erkennen kann, dass sie irgendwo benutzt wird?

Kann eigentlich nicht sein. Es wird ja ein Zeiger auf die Funktion 
gebildet, über den sie dann aufgerufen wird. Das reicht, um solche 
Optimierungen zu verhindern.

> Wie immer in solchen Fällen hilft ein kurzer Blick in das ASM-Listing
> des Compilers oder das Disassembly-Fenster des Debuggers.

Es hilft zumindest bei der Feststellung, ob irgendwas wegoptimiert wird.

von Andreas K. (a-k)


Lesenswert?

> Kann eigentlich nicht sein. Es wird ja ein Zeiger auf die Funktion
> gebildet, über den sie dann aufgerufen wird. Das reicht, um solche
> Optimierungen zu verhindern.

Zumal ein Compiler, der wie gcc jedes Quellfile einzeln übersetzt, bei 
einer Funktion, die nicht als "static" deklariert wurde, annehmen muss, 
dass sie anderswo gebraucht wird. Wenn man also nicht pro Funktion eine 
eigene Section verwendet und so dem Linker die Entscheidung überlässt, 
sind solche Funktionen immer drin. Nur der Aufruf wird u.U. wegoptimiert 
weil inlined.

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


Lesenswert?

Andreas Kaiser wrote:

> Zumal ein Compiler, der wie gcc jedes Quellfile einzeln übersetzt, bei
> einer Funktion, die nicht als "static" deklariert wurde, annehmen muss,
> dass sie anderswo gebraucht wird. Wenn man also nicht pro Funktion eine
> eigene Section verwendet ...

Daher schrieb ich auch von ,,aggressiver Optimierungseinstellung''.
Das bezog sich also schon auf Dinge wie -ffunction-sections/ +
--gc-sections und -fwhole-program.

von bombastix (Gast)


Lesenswert?

Hallo Manuel,

bei mir (ATTINY2313) optimiert er da nichts weg - super Trick, wieder 4 
Byte(gegen ^=) gespart.

Ich hoffe, du findest die Ursache.

Viel Erfolg,

Bombastix

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.