www.mikrocontroller.net

Forum: Compiler & IDEs OHNE(!) Optimierung gehts nichts mehr


Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

entgegen der üblichen Optimierungsprobleme ist es bei mit genau 
umgekehrt: Bei höchster (-Os) Optimierung tritt selten fehlerhaftes 
Verhalten auf. Bei geringerer wird zwar noch die main aufgerufen, aber 
ohne (-O0) Optimierung wird nicht einmal die erste Zeile in main() 
ausgeführt.

Ich hatte die Bootstrap Routine AT91boot... in verdacht, doch sie hat 
allen Tests standgehalten und funktioniert.

Was kann das sein?

ARM9, codesourcery arm-none-eabi-toolchain

Viele Grüße
Daniel Gering

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- RAM/Stack läuft über
- Programm passt nicht in Flash
- Timing stimmt nicht mehr (ISRs, etc)

Johann

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt C-Konstruktionen im GCC, die ohne Optimierung einfach nicht 
laufen. Beispielsweise inb() und outb() und Konsorten unter Linux.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile vergessen.

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

nein, alles das kann ich ausschließen. Ich suche schon viele Wochen nach 
diesem Fehler und hatte hier schon mal gepostet. Habe schon so viel 
getestet und probiert...

Stackpointer sind in allen Modi initialisiert, Programm nicht 
zeitkritisch, passt definitiv in Flash, von RAM groß genug, inb() und 
outb() nutze ich nicht und es läuft kein OS (bare metal) und die 
vergessenen volatiles sind längst drinnen.

Sogar verschiedene Toolchains habe ich versucht. Aber vor allem: warum 
wird nicht mal die erste main() Zeile ausgeführt?

Ich hoffe Ihr habt noch Ideen, ich verzweifele (schon seit langem)!

Viele Grüße
Daniel Gering

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen 
funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen 
ohne Optimierung nicht.

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin ein bissl unwissend:
>Genaugenommen
funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
ohne Optimierung nicht.<

Was hrißt das?

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven P. schrieb:
> Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen
> funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
> ohne Optimierung nicht.

Also unter Inline Funktionen verstehe ich Codeteile die durch den 
Compiler oder preprozessor eingesetzt werden anstatt zu einer Funktion 
zu springen.

inb() und outb() sind doch von Linux bereitgestellte funktionen die ich 
nicht habe weil kein linux läuft (überhaupt kein BS). Oder sehe ich da 
was falsch?

Grüße
DG

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein ich meine mehr im zusammenhang

alleinstehend
optimierung

ansonsten inline ich auch wie ein weltmeister.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:
> Sven P. schrieb:
>> Ich sagte, dass inb() und outb() nur Beispiele sind. Genaugenommen
>> funktionieren sämtliche Aufrufe von alleinstehenden Inline-Funktionen
>> ohne Optimierung nicht.
>
> Also unter Inline Funktionen verstehe ich Codeteile die durch den
> Compiler oder preprozessor eingesetzt werden anstatt zu einer Funktion
> zu springen.
Richtig. Das impliziert dann logischerweise, dass der Funktionsrumpf 
auch im Header definiert sein muss, denn sonst sieht der Compiler ja 
nicht, was er denn direkt einbauen soll.

> inb() und outb() sind doch von Linux bereitgestellte funktionen die ich
> nicht habe weil kein linux läuft (überhaupt kein BS). Oder sehe ich da
> was falsch?
Jein, inb() und outb() sind Inline-Funktionen, die halt nur in den 
Headern liegen und nicht in irgendeiner Bibliothek landen, die 
dazugelinkt wird. Wär ja auch Käse, inb() und Konsorten sind unterm 
Strich nur 'Makros', da wird bestenfalls ein einzelner Assembler-Befehl 
verpackt.

Wenn du nun ohne Optimierung übersetzt, führt der Compiler auch keine 
Inlines aus, sondern setzt dort Verweise in die Wildnis ein (wie bei 
jedem anderen Funktionsaufruf auch) und reicht das an den Linker weiter, 
damit der die Verweise auf die richtigen Funktionen und Bibliotheken 
verbiegt.

Blöderweise liegen so Dinger wie etwa inb() eben nirgendwo, d.h. die 
Verweise landen im Sand.
Wenn man allerdings die Optimierung wieder einschaltet, baut der 
Compiler die Funktionen direkt ein und das Problem mit der Linkerei 
stellt sich erst garnicht.


Warum möchtest du überhaupt die Optimierung abstellen?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Blöderweise liegen so Dinger wie etwa inb() eben nirgendwo, d.h. die
> Verweise landen im Sand.

Wie kommst du darauf? Entweder sind sie als Makros definiert, dann löst 
sie der Präprozessor nach wie vor auf, oder es sind Funktionen, dann 
werden sie halt nicht mehr inline ausgeführt, sondern als 
Funktionsaufruf. Selbstverständlich muß der Compiler auch ohne 
Optimierung korrekten Code produzieren. Aufrufen aber dann einfach 
weglassen darf er die Funktion nicht.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann mir auch nict vorstellen, das Inline oder Makro nicht gehen 
soll wenn man keine Optimierung eingeschaltet hat. Normalerweise debuggt 
man ja code ohne Optimierung und dabei ist mir noch die etwas 
untergekommen was ohne optimierung nicht geht.

Da die Header datei ja eh durch das include in der gleichen Datei wie 
auch der C code steht, ist es egal ob die Funktion in der header oder in 
der C datei steht, für den Linker ändert das nichts.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Linux-Manualseite zu inb():

> You compile with -O or -O2 or similar. The functions are defined as
> inline macros, and will not be substituted in without optimization
> enabled, causing unresolved references at link time.

Anders kann ich mir das nich erklären, heißt natürlich nicht, dass ich 
auch danebenliegen kann.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, steht da tatsächlich. Dann würde mich aber mal wirklich 
interessieren, wie man das hinbekommt. Eigentlich geht sowas gar nicht.

Autor: Bernhard R. (barnyhh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz am Anfang - als eine der ersten Aktionen nach Einschalten oder 
RESET - wird der Stackpointer initialisiert. Wenn jetzt der Prolog (vor 
main) zu früh (vor Initialisierung des Stackpointers) Funktionsaufrufe 
durchführt, dann kann folgendes geschehen:
- Ohne Optimierung werden Calls auf diese Funktionen durchgeführt, die 
spätestens beim Return ins Nirwana abgleiten
- Mit Optimierung geschieht Code-Inlining, also kein Call, kein Nirwana

Das paßt zu den Symptomen.

Bernhard

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem kann ausgelöst werden durch anderes Timing, zB bei 
aktiviertem Watchdog, oder wenn Teile des Startup-Codes in der 
Applikation in C geschrieben sind. Dazu gehören Konstruktoren in C++, 
Funktionen mit __attribute__((constructor)) (GNU-C) und Code in 
speziellen init-Sections, der nicht in Assembler geschrieben ist.

Johann

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard R. schrieb:
> Ganz am Anfang - als eine der ersten Aktionen nach Einschalten oder
> RESET - wird der Stackpointer initialisiert. Wenn jetzt der Prolog (vor
> main) zu früh (vor Initialisierung des Stackpointers) Funktionsaufrufe
> durchführt, dann kann folgendes geschehen:
> - Ohne Optimierung werden Calls auf diese Funktionen durchgeführt, die
> spätestens beim Return ins Nirwana abgleiten
> - Mit Optimierung geschieht Code-Inlining, also kein Call, kein Nirwana
>
> Das paßt zu den Symptomen.
>
> Bernhard

C-Code wird erst aufgerufen wenn alle Stackpointer initialisiert sind.

Für den Startup-Code in Assembler ist es egal welche Optimierungsstufe 
gewählt ist. Nur für C-Code muss mindestens -O1 eingeschaltet sein.

Und wie gesagt, ohne Optimierung wird nicht mal die erste Zeile des 
C-Programms ausgeführt.

Watchdog ist aus, C++ nutze ich nicht, __attribute__((constructor)) auch 
nicht.

Ich habe nicht eine Funktion die als inline gekennzeichnet ist. Und auch 
nur eine Library Funtion nutze ich: memcpy()

Was kann das nur sein???

Autor: Cpt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Ich hatte letztens ein ähnliches Problem mit dem AVR32. Bei mir war es 
das Flash und genauer gesagt das Flash Timing. Ich hatte übersehen, daß 
wenn man den Prozessor mit 60 MHz betreiben will, der Flash Controller 
ein Waitstate beim Zugriff braucht ... Das Verhalten war in etwa gleich. 
Längerer Code wurde nur mit höchster Optimierung ordentlich ausgeführt. 
Nur mal als Denkanstoß in eine andere Richtung. Hat mich viel Zeit 
gekostet das Problem zu finden.

Viele Grüße!

Cpt

Autor: Daniel G. (motello)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Ich habe mein Problem nach laaaaaaaanger Zeit ebenfalls heute lösen 
können. Hier nachzulesen:

Beitrag "Merkwürdiges Verhalten bei Variablen und for-schleifen"

Stackpointer war nicht aligned.

Viele Grüße
Daniel Gering

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.