Hallo,
ich habe das Problem, dass alle Compileroptimierungen ( O1 bis O3 und
Os) mein Programm nicht mehr richtig funktionieren lassen, sonst aber
der Code nicht mehr in den Speicher passt....
Jetzt meine Frage: Kann man die Optimierungen für bestimmte Codeblöcke,
von denen ich weiß dass sie durch die Optimierungen kaputt gemacht
werden, per Precompiler Befehl oder durch etwas anderes ausschalten?
Grüße,
Philip
Nerb schrieb:> Jetzt meine Frage: Kann man die Optimierungen für bestimmte Codeblöcke,> von denen ich weiß dass sie durch die Optimierungen kaputt gemacht> werden, per Precompiler Befehl oder durch etwas anderes ausschalten?
Wenn der Optimierer Dein Programm derart ändert, dass Dein Programm
nicht mehr wunschgemäß funktioniert, kannst Du in über 90% der Fälle
davon ausgehen, dass der Fehler im Programm ist und nicht im Optimierer
des Compilers.
Zeig doch mal Deine "bestimmten Codeblöcke".
Ich nehme mal an, daß du von GCC sprichst. GCC hat ab Version 4.4
Pragmas mit denen man funktionsgenau die Optimierung steuern kann, man
kann die Optimierungsoptionen auch als Funktionsattribute anhängen:
http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html
Wenn dein Programm allerdings bei Einsatz des Optimierers nicht mehr
funktioniert, dann ist in 99.9% der Fälle nicht der Optimierer schuld,
sondern der Programmierer, der sich einen Nachmittag lang mal hinsetzen
sollte um das hier zu lesen:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
Der beste Weg ist immer noch, zunächst mal fehlerfreien Programmcode zu
schreiben. Code, der durch die Optimierung "kaputt gemacht" wird, ist
nun mal nicht fehlerfrei.
Oliver
Hallo,
danke für die vielen Antworten. Die Links habe ich mir durchgelesen, da
steht vieles Nützliche drin. Bevor ich aber für unterschiedliche
Funktionen den Optimierungsgrad ändere, suche ich doch lieber nach der
Ursache im Code, damit ich später alles einheitlich habe. Gefunden habe
ich folgendes:
Mein Programm:
global.h
1
externuint8_tglobaleVariable;
global.c
1
uint8_tglobaleVariable=0;
transceive.c
1
#include"global.h"
2
if(globaleVariable==1)
3
{
4
DieserCodewirdnichtaufgefuehrt,wennichoptimiere.
5
}
So, nehme ich aber jetzt aber das "extern" in global.h weg, dann geht
mein Programm. Da aber von verschiedenen anderen .c Dateien auf die
Variable zugegriffen wird, brauche ich das extern aber. Wisst ihr, wo da
der Wurm drin steckt?
Grüße,
Philip
Nerb schrieb:> Wisst ihr, wo da> der Wurm drin steckt?
In dem Teil, den du nicht zeigst. Such mal in allen Source-Files nach
"globaleVariable", vermutlich ist die irgendwo ein zweites mal
deklariert.
Hi,
sie ist nirgends zweimal deklariert, sondern nur einmal in global.c.
Wenn die variable in transceive.c abgefragt wird, hat sie noch keinen
Wert zugewiesen bekommen (ist 0, aber nicht wegen der Zuweisung in
global.c, sondern weil Avr Studio 6 und gcc Variablen automatisch 0
setzen). Hat jemand noch eine Idee? Ich finde den Fehler nicht, finde es
aber komisch, dass es ohne das extern geht.
Grüße,
Philip
Klaus schrieb:> Ich setzte all mein Geld auf volatile
Mit anderen Worten: Könnte es vielleicht sein, daß auf globaleVariable
auch aus einer ISR heraus zugegriffen wird und das dann nötige volatile
fehlt?
Hi,
ja, die if-Abfrage sitzt in einer ISR, nur funktioniert das
Schlüsselwort volatile auch nicht. Ich habe mal die Werte der Variable
geändert, daraus ergab sich, dass in der ISR immer eine neue Variable
mit diesem Namen erzeugt wird. Wenn ich extern wegnehme, dann
funktioniert ja alles. Ich schätze, das fügt der Compiler dann zusammen
und macht es dann aber richtig, obwohl das nicht c-konform ist...
Grüße,
Philip
Nerb schrieb:> Hi,>> ja, die if-Abfrage sitzt in einer ISR, nur funktioniert das> Schlüsselwort volatile auch nicht.
Es kann natürlich sein, dass da jetzt mehrere Probleme zusammenspielen.
> Ich habe mal die Werte der Variable> geändert, daraus ergab sich, dass in der ISR immer eine neue Variable> mit diesem Namen erzeugt wird.
Ganz sicher nicht.
Wenn das eine globale Variable ist, dann gibt es sie auch nur 1 mal.
> Wenn ich extern wegnehme, dann> funktioniert ja alles.
Irgendwie klingt das für mich als ob du nach dem Muster "Ich probier
einfach so lang rum, bis ich was habe, das so aussieht, als ob es
funktioniert" arbeitest.
Das hat noch nie funktioniert und das wird auch nie funktionieren. Gut
gelerntes C, bei dem man auch im Detail weiß, was die Anweisungen
bewirken, warum es sie gibt und wie die Regeln zu ihrer Verwendung sind,
ist durch nichts zu ersetzen.
Das das nicht von heute auf morgen geht, ist auch klar. Es dauert nun
mal Jahre, bis man das Zusammenspiel auch in den Details versteht.
Optimierer abschalten versteckt nur die Probleme (in den meisten Fällen.
Natürlich gibt es auch Fehler im Compiler bzw. Optimierer. Die sind aber
selten).
> Ich schätze, das fügt der Compiler dann zusammen> und macht es dann aber richtig, obwohl das nicht c-konform ist...
Auf eines kannst du wetten: Auch wenn nicht alle Compiler zu 100%
Standard-konfoem sind - sie verstehen immer noch mehr von Konformität
zum C-Standard als mehr als 80% aller C-Programmierer. Vor allen Dingen
diejenige, die nie systematisch durch den zu erlernenden Sprachumfang
geführt wurden, diejenigen die meinen mit einem windigen Tutorial würde
das schon reichen, vor allem die zeichnen sich regelmässig durch
unglaublich große Wissenslücken aus. Kein Mensch weiß alles, aber das
Wissensgefälle ist schon augenscheinlich.
Zeig doch mal etwas mehr Code - mehr Details. Dann findet sicher auch
hier im Forum jemand die problematischen Dinge.
Schuss ins Blaue
global.h
1
externvolatileuint8_tglobaleVariable;
global.c
1
volatileuint8_tglobaleVariable=0;
Und dann darauf achten, dass dein Makefile in Ordnung ist und
tatsächlich auch wirklich alles neu compiliert wird.
Karl Heinz Buchegger schrieb:> Zeig doch mal etwas mehr Code - mehr Details. Dann findet sicher auch> hier im Forum jemand die problematischen Dinge.
Ich tipp drauf dass:
Nerb schrieb:> transceive.c> #include "global.h"> if(globaleVariable == 1)> {> Dieser Code wird nicht aufgefuehrt, wenn ich optimiere.> }
sowas ist:
Hi,
es tritt genau das Verhalten auf, das Ernst B beschrieben hat, in der
ISR wird eine neue Variable erzeugt, die uninitialisiert bleibt. Nur
habe ich die global.h vor dem ISR Block eingefügt.
Mehr vom Code zu zeigen, würde nicht viel helfen, der ist schon 6k loc
lang. Das gezeigte Beispiel beschreibt das Problem ganz gut.
Momentan sieht mein Programm so aus (etwas verfeinert)
global.h
@ Nerb (Gast)
>es tritt genau das Verhalten auf, das Ernst B beschrieben hat, in der>ISR wird eine neue Variable erzeugt, die uninitialisiert bleibt. Nur>habe ich die global.h vor dem ISR Block eingefügt.
Dan stimmen deine Definitionen nicht.
>Mehr vom Code zu zeigen, würde nicht viel helfen,
Du musst es wissen.
> der ist schon 6k loc>lang.
Es gibt die Funktion, das als Anhang zu sendne.
> Das gezeigte Beispiel beschreibt das Problem ganz gut.
Und ist nur eine unzulängliche Kopie. Fail, wie es so schön auf
Neudeutsch heißt.
http://www.mikrocontroller.net/articles/Netiquette#.C3.84u.C3.9Fere_Form
"Quelltext nie abtippen, sonder immer das direkt kopierte Original
posten, anderenfalls schleichen sich neue Fehler ein oder die
existierenden werden nicht abgeschrieben."
xfr schrieb:> Versuch es in global.c mal mit:volatile char globaleVariable = 'h';
Obwohl, optimiert wird ja in den anderen Dateien, die nur das
Header-File sehen. Das ist es also wahrscheinlich nicht. Schaden würde
es aber trotzdem ist.
Nerb schrieb:> Mehr vom Code zu zeigen, würde nicht viel helfen, der ist schon 6k loc> lang.
:-)
Aha. Die wesentlich wahrscheinlichere Variante ist allerdings, dass in
deinen 6k loc irgendwo anders ein Fehler ist und du dir die globale
Variable über den Haufen schiesst (so zu sagen).
Aber bitte. Wenn du nicht herzeigen willst, dann eben nicht.
Such weiter deinen Fehler an einer Stelle, an der kein Fehler ist.
Was du siehst, ist das Symptom.
Die Ursache kann aber ganz woanders im Code sitzen.
Woher weißt Du, dass der Code bei Optimierung nicht ausgeführt wird?
Steht dort etwas, dass mit Sicherheit auf Variablen (oder Register)
zugreift, die bestimmt nicht wegoptimiert werden? Hast Du mal in die
Assembler-Listings mit Optimierung im Vergleich zu ohne Optimierung
verglichen?