Hallo zusammen,
vor einigen Tagen ist mir ein Fehlverhalten (Kurioses Debugging eines
IF-THEN-ELSE-Konstruktes: Codeteile sowohl im THEN, als auch im ELSE
Zweig werden ausgeführt) in meinem Programm aufgefallen. Mein Programm
(kompiliert mittels Code Composer Studio 6 mit MSPGCC für einen
MSP430F5438 auf einem olimex-Board mit dem olimex-JTAG-TINY
v1-Programmieradapter) war zu diesem Zeitpunkt schon etwas größer (ca.
26kB) und der Fehler trat in einem Teil auf, der in meinen Augen
eigentlich schon stabil lief und deswegen längere Zeit nicht getestet
wurde. Da ich zu dieser Zeit auch noch sehr viel an anderen Baustellen
gearbeitet habe, fiel es mir sehr schwer die Ursache genauer
einzugrenzen.
Ich habe daher angefangen, dass Programm Stück für Stück von null an neu
zusammenzusetzen, damit ich den Fehler besser lokalisieren kann.
Ich denke, das Problem liegt an einer ftoa-Funktion, welche ich hier aus
dem Forum habe. Entweder die Funktion hat einen Fehler oder ich benutze
sie falsch - oder es liegt an etwas ganz anderem...
Die Funktion sieht so aus:
Das char-Array ist 14 Zeichen lang, da mein LCD-Display pro Zeile 14
Zeichen anzeigen kann. Die Variable value kann Werte zwischen 9.0,
9.5,...13 annehmen und wird formatiert beispielsweise so ausgegeben:
"0009.500"
Wir sind also bei deutlich unter 14 Zeichen - beziehungsweise deutlich
unter 13 Zeichen, wenn man das Abschlusszeichen '\0' berücksichtigt.
Kann es dennoch sein, das Problem an der Benutzung dieser Funktion
liegt? Seht ihr an dieser Stelle etwas auffälliges?
Ich freue mich über jeden Denkanstoß :-)
Viele Grüße,
Roland
>> p sollte wenigstens irgendwo sinnvoll hinzeigen :/
Hallo,
wie gesagt sind die Funktionen ftoa (welche wiederrum ltoa aufruft)
Teile einer fertigen "Bibliothek" hier aus dem Forum, daher habe ich
diese für funktionierend angenommen und mir nicht im Detail angeschaut.
Es funktioniert ja auch - meine Zahl kommt richtig formatiert als String
bei mir an. Allerdings kann ich im Moment nicht wirklich ausschließen,
dass Teile dieser Funktionen (oder wie ich diese Funktionen benutze)
meinen Stack zerstören...
Roland M. schrieb:> Das char-Array ist 14 Zeichen lang, da mein LCD-Display pro Zeile 14> Zeichen anzeigen kann.
Wenn du String Funktionen nutzen willst muss dein char Array aber 14 + 1
Zeichen lang sein, sonst passt kein abschliessendes \0 Zeichen mehr
rein.
Wenn ich mir deinen Code anschaue, dann gehst du bei geschachtelten
if/else und while Konstrukten sehr sparsam mit geschweiften Klammern um.
Das führt bei Erweiterungen oder mal schnell einer Debug Ausgabe oder
einem weiteren else ganz schnell zu völlig anderem(falschem) Verhalten.
Sobald man schachtelt und else benutzt ist es meiner Meinung nach sehr
sinnvoll konsequent immer geschweifte Klammern zu setzen. Nur die
Einrückung macht den Code weder korrekt noch kümmert es im Zweifel den
Compiler.
Die fehlende Bereichsüberprüfung für den Parameter 'd' von ftoa kann Dir
auch auch die Füße fallen, dann nämlich, wenn der Wert kleiner 0 oder
größer 6 ist ...
Da Du "char" statt uint8_t verwendest, ist nicht völlig ausgeschlossen,
daß der Wert negativ werden kann.
Udo Schmitt schrieb:> Roland M. schrieb:>> Das char-Array ist 14 Zeichen lang, da mein LCD-Display pro Zeile 14>> Zeichen anzeigen kann.>> Wenn du String Funktionen nutzen willst muss dein char Array aber 14 + 1> Zeichen lang sein, sonst passt kein abschliessendes \0 Zeichen mehr> rein.>> Wenn ich mir deinen Code anschaue, dann gehst du bei geschachtelten> if/else und while Konstrukten sehr sparsam mit geschweiften Klammern um.> Das führt bei Erweiterungen oder mal schnell einer Debug Ausgabe oder> einem weiteren else ganz schnell zu völlig anderem(falschem) Verhalten.>> Sobald man schachtelt und else benutzt ist es meiner Meinung nach sehr> sinnvoll konsequent immer geschweifte Klammern zu setzen. Nur die> Einrückung macht den Code weder korrekt noch kümmert es im Zweifel den> Compiler.
Wie bereits gesagt ist das eine Bibliothek hier aus dem Forum. In meinem
Code arbeite ich grundsätzlich immer mit geschweiften Klammern, da ich
dies auch sehr viel leserlicher finde...
Packen wir das Problem mal anders an: Kann mir jemand eine entsprechende
Bibliothek empfehlen, welche auf jeden Fall funktioniert? Sie muss auch
gar nicht soviele Möglichkeiten zur Formatierung enthalten, sondern soll
lediglich die (Komma-)Zahl zu einem Text formatieren können...
Der 'F5438 hat 256 kB Flash-ROM, Du kannst also einfach das mit dem
Compiler mitgelieferte sprintf verwenden.
Was bringt es Dir, bei 26 kB Codegröße Speicher zu sparen? Von TI
bekommst Du kein Geld zurück, wenn Du den Rest des Flash-ROMs nicht
verwendest.
Roland M. schrieb:> Packen wir das Problem mal anders an: Kann mir jemand eine entsprechende> Bibliothek empfehlen, welche auf jeden Fall funktioniert?
Wie soll das denn gehen?
Wenn eine Funktion (wie ftoa()) einen Buffer als Argument bekommt aber
sonst keine weitere Information vorhanden ist, wie groß denn der Buffer
in der aufrufenden Funktion überhaupt ist, bekomme ich das Ding immer
zum Crash.[1] Ich brauche nur einen ungültigen Pointer oder einen zu
kleinen Buffer runterzugeben.
Prüfe doch erst mal, ob Dein Buffer nicht zu klein ist.
[1] Es gäbe noch die Möglichkeit, die Buffergröße mit runterzugeben. Die
Standardfunktionen ftoa(), ltoa() sehen das aber in ihrem Interface
nicht vor. Machs doch einfach selber. Die Quellen hast Du ja.
Roland M. schrieb:> Sie muss auch> gar nicht soviele Möglichkeiten zur Formatierung enthalten, sondern soll> lediglich die (Komma-)Zahl zu einem Text formatieren können...
Du weisst doch im Moment gar nicht wo dein Fehler steckt.
Wenn du so einen Fehler finden willst dann speck dein Programm ab bis
der fehler nicht mehr auftritt, oder anders baue ein Minimalprogramm bis
du den Fehler nachvollziehen kannst.
Ob die Bibliothek funktioniert oder nicht kannst du auch herausfinden
indem due in minimalprogramm mit den Werten die zu dem Fehler geführt
haben debuggst und schaust was in den registern passiert.
Einfach eine andere Bibliothek nehmen wird dein Fehler sehr
wahrscheinlich nicht lösen weil er in dem Code steckt, den du hier nicht
zeigst.
Hallo zusammen!
Erstmal danke für die zahlreichen und vorallem zügigen Antworten.
Zum Thema Minimalprogramm zur Fehlereingrenzung:
Wie bereits im Eingangspost geschrieben, habe ich mein Programm bereits
von null auf wieder komplett von vorne aufgebaut und dabei immer
nachgeschaut, wann der Fehler auftritt. Daher bin ich ja auch zu dem
fast sicheren Schluss gekommen, dass das Problem an den Funktionen
ftoa/ltoa, beziehungsweise wie ich diese Funktionen benutze, liegen
muss.
Ich denke ich werde den Vorschlag von Rufus T. Firefly testen und das
normale sprintf testweise benutzen. Sollte ich dann keinen Fehler
reproduzieren können, so habe ich eine Bestätigung für meine derzeitige
Vermutung.
Aaaaallerdings ist jetzt erstmal Feierabend und Zeit für ein Bier :-D
Ich werde morgen früh damit anfangen und euch dann berichten.
Nochmals: Dankeschön für eure Kommentare und Denkanstöße --> morgen
werden wir mehr wissen ;-)
Roland M. schrieb:> Packen wir das Problem mal anders an: Kann mir jemand eine entsprechende> Bibliothek empfehlen, welche auf jeden Fall funktioniert? Sie muss auch> gar nicht soviele Möglichkeiten zur Formatierung enthalten, sondern soll> lediglich die (Komma-)Zahl zu einem Text formatieren können...
Im Arduino-Forum habe ich mal jemandem eine ähnliche
Formatierungsfunktion gemacht. Allerdings wollte der in seinem Programm
komplett auf Gleitkommazahlen verzichten und Integerwerte so auf einem
Display ausgeben als wären es Werte mit ein oder zwei Nachkommastellen.
Formatiert wurde auch mit führenden Leerzeichen.
Aber das müßte sich leicht so umstellen lassen, dass es mit "long" statt
"int" funktioniert und mit frei wählbarem "padchar".
Aufrufkonvention wäre dann so ungefähr:
Roland M. schrieb:> Wie bereits im Eingangspost geschrieben, habe ich mein Programm bereits> von null auf wieder komplett von vorne aufgebaut und dabei immer> nachgeschaut, wann der Fehler auftritt. Daher bin ich ja auch zu dem> fast sicheren Schluss gekommen, dass das Problem an den Funktionen> ftoa/ltoa, beziehungsweise wie ich diese Funktionen benutze, liegen> muss.
Der nächste Schritt wäre jetzt, alles andere wegzulassen und nur das
ftoa allein, so wie du es im Programm testest, zu verwenden.
Bis jetzt ist der Schluss, den du da ziehst, nicht zwingend. Denn
niemand sagt dir, dass das ftoa nur der Symptomüberbringer ist. Der
Fehler also schon früher eingebaut war und nur nicht sichtbar war.
Genau das ist die Krux beim Fehlersuchen. Nur weil sich kein Fehler an
der Oberfläche zeigt, bedeutet das nicht, dass keiner vorhanden ist.
Hallo zusammen,
schweren Herzens muss ich euch leider Recht geben. Die Funktion ftoa war
nicht das eigentliche Problem. Das Springen im Quelltext ist leider
immer noch anzutreffen.
Ich gebe euch mal einen tieferen Einblick in mein Programm:
main.c
1
intmain(void)
2
{
3
Init();
4
while(1)
5
{
6
CheckJoystick(P1IN);
7
if(m_ChangeVoltage!=-1)
8
{
9
DoSimulation();
10
}
11
12
Menu_Update();
13
}
14
}
Das Problem tritt in der Funktion Menu_Update() auf, welche sich um die
Menüführung auf dem LCD kümmert.
Sie sieht ungefähr so aus:
LCD.c
1
voidMenu_Update(void)
2
{
3
if(m_CurrentAction==0)
4
{
5
// Hier wird die Menüstruktur auf dem LCD-Display ausgegeben
6
DisplayMenu();
7
8
if(currentNode.Parent==-1)
9
{
10
LCD_Set_Position(0,5);
11
// Hier wird der aktuelle Status der SD-Karte ausgegeben
Kurz zur Orientierung: Die Funktion ftoa, über die wir davor gesprochen
haben, wird in der Funktion DisplaySelectValue aufgerufen.
Beim Debugging habe ich nun festgestellt, dass die mit XXX markierte
Zeile quasi immer aufgerufen wird - unabhängig von m_CurrentAction.
Konkret habe ich es für die Fälle m_CurrentAction == 0 und 20 <=
m_CurrentAction < 30 getestet und in beiden Fällen wird bei der Schritt
für Schritt Ausführung vorm Rücksprung aus der Funktion die markierte
Anweisung ausgeführt...
Ich bin jetzt relativ unsicher, wie ich vorgehen soll um den Fehler
weiter eingrenzen zu können... Habt ihr noch weitere Vorschläge oder
braucht Ihr vielleicht noch mehr Informationen?
Sollte man an dieser Stelle vielleicht vorne, also bei DisplayMenu(),
anfangen?
Fehler dieser Art können durch mehrere Dinge ausgelöst werden.
Der wohl häufigste Fall ist der 'Array out of Bounds'.
Also irgendwas in der Art
1
inta[4];
2
3
a[4]=8;
bei dem auf ein nicht vorhandenes Array Element geschieben wird und man
sich dadurch im Speicher irgendwelche anderen Dinge überschreibt. Das
ist besonders heimtückisch, wenn das Array lokal in einer Funktion ist
und man sich durch den out of bounds Zugriff die Rücksprungadresse der
Funktion zerschiesst.
Auch die Situation 'Ende des SRAM ist erreicht' sollte nicht ausser acht
gelassen werden. Wird das SRAM knapp, dann wandert der Stack in den
Variablenbereich hinein und durch beschreiben der (regulären) Variable
zerschiesst man sich wieder den Returnstack. Genau aus dem Grund sollte
man in der µC Programmierung auf den kleinen µC eine Grundregel der
Programmierung auch mal ausser acht lassen und relativ viel als globale
Variablen anlegen. Gerade mal Dinge wie Schleifenzähler oder kleinere
Speicherverbraucher können in den Funktionen bleiben, aber den Rest will
man global haben, damit Compiler/Linker den Speicherverbrauch
feststellen können und man einen Hinweis hat, wenn der Speicher knapp
werden könnte. Ganz exakt kann man das sowieso nie feststellen, weil es
dann von der genauen Aufrufreihenfolge der Funktionen abhängt, wieviel
Speicher dann noch zur Leufzeit benötigt wird. Aber zumindest einen
Eindruck kann man schon kriegen, ob man eher knapp unterwegs ist oder
nicht.
Hallo zusammen,
ich habe einige Neuigkeiten für euch...
In den Optimierungseigenschaften gibt es mehrere Level zur Auswahl:
1) Leeres Feld
2) None (-O0)
3) Optimize (-01)
4) Optimize more (-O2)
5) Optimize most (-O3)
Außerdem gibt es dann noch einige Checkboxes, eine von denen heißt:
Optimize for space rather than speed (-Os)
Es ist nun so, dass sich diese Checkbox auf den Buildvorgang auswirkt -
und zwar unabhängig ob ich Option 1 (Leeres Feld) oder Option 2 (None)
gewählt habe.
Sobald diese Checkbox gesetzt ist, fängt das seltsame Verhalten wieder
von Vorne an (es werden zwei Switch-Cases sowie zwei Else-Zweige
angesprungen).
Da das Ergebnis für mich jedoch stets richtig war und auch alles
funktioniert und ich damals im Studium gelernt habe, dass Compiler
ziemlich intelligente Programme sind, wird das schon alles so seine
Richtigkeit haben... Oder etwa nicht? :-D
PS: Netter Nebeneffekt: Wenn die Checkbox gesetzt ist, läuft mein
Programm trotz Optimierung der Codegröße gefühlt sehr viel schneller ab
(sodass es mich dazu verleitet meine Debouncing-Grenzwerte zu
erhöhen...).
Roland M. schrieb:> Sobald diese Checkbox gesetzt ist, fängt das seltsame Verhalten wieder> von Vorne an (es werden zwei Switch-Cases sowie zwei Else-Zweige> angesprungen).
Ganz ehrlich.
Du solltest deinen Programmfehler suchen und nicht mit
Optimierungseinstellungen rumspielen.
Es ist schon richtig, dass sich Optimierungseinstellungen darauf
auswirken, was der Compiler produziert. Das ändert aber nichts daran,
dass du einen Fehler im Code hast. Das eine mal wirkt der sich eben
nicht aus und/oder der Compiler nutzt ein mögiche Optimierung eben
nicht, wodurch sich der Fehler nicht zeigt. Vorhanden ist er aber
trotzdem.
Ich weiss schon. Es ist verführerisch, den Compiler für etwas
verantwortlich zu machen. Fakt ist aber, dass in 99 von 100 Fällen, das
Problem im Programm bzw. beim Programmierer liegt und nicht beim
Compiler. Ehe ich nicht im produzierten Assemblercode dem Compiler nicht
100%-ig nachweisen kann, dass er gültigen und eindeutig definierten C
Code falsch umgesetzt hat, würde ich dem Compiler erst mal immer
freisprechen und als Arbeitshypothese "Ich habe einen Bug im Code"
annehmen.
Karl Heinz schrieb:> Roland M. schrieb:>>> Sobald diese Checkbox gesetzt ist, fängt das seltsame Verhalten wieder>> von Vorne an (es werden zwei Switch-Cases sowie zwei Else-Zweige>> angesprungen).>> Ganz ehrlich.> Du solltest deinen Programmfehler suchen und nicht mit> Optimierungseinstellungen rumspielen.>> Es ist schon richtig, dass sich Optimierungseinstellungen darauf> auswirken, was der Compiler produziert. Das ändert aber nichts daran,> dass du einen Fehler im Code hast. Das eine mal wirkt der sich eben> nicht aus und/oder der Compiler nutzt ein mögiche Optimierung eben> nicht, wodurch sich der Fehler nicht zeigt. Vorhanden ist er aber> trotzdem.>> Ich weiss schon. Es ist verführerisch, den Compiler für etwas> verantwortlich zu machen. Fakt ist aber, dass in 99 von 100 Fällen, das> Problem im Programm bzw. beim Programmierer liegt und nicht beim> Compiler. Ehe ich nicht im produzierten Assemblercode dem Compiler nicht> 100%-ig nachweisen kann, dass er gültigen und eindeutig definierten C> Code falsch umgesetzt hat, würde ich dem Compiler erst mal immer> freisprechen und als Arbeitshypothese "Ich habe einen Bug im Code"> annehmen.
Hallo Karl Heinz,
vielleicht habe ich mich ja nicht deutlich ausgedrückt, aber es ist so,
dass mein Programm bei deaktivierter Optimierung (Option 1: leeres Feld
in der DropDownListe) und allen DEaktivierten Checkboxes endlich so
läuft, wie es in meinem Code steht (keine doppelten ELSE-/Case-Zweige).
Ist das nicht der eindeutige Beweis dafür, dass ich gar keinen Fehler in
meinem Programm versteckt habe?
Hallo,
wenn du vernünftig debuggen willst solltest du, sofern Platz vorhanden,
die Optimierung ausschalten.
Deine LCD_Update Funktion wird wenn ich mich nicht verlesen habe in
jedem Zweig aufgerufen, nur mit anderen Parametern.
Schau mal im disassembly nach, ob die übergebenen Werte stimmen.
Wenn die Optimierung zu hoch eingestellt ist ist für diese Funktion
unabhängig, wo sie aufgerufen wird nur einmal Symbolinfo vorhanden, d.h.
er zeigt in der übergeordneten Funktion nur das letzte Vorkommen der
aufgerufenen Funktion an.
Grüße
Peter
Roland M. schrieb:> Ist das nicht der eindeutige Beweis dafür, dass ich gar keinen Fehler in> meinem Programm versteckt habe?
Nein.
Es ist nur der Beweis dafür, dass sich der Fehler nicht auswirkt.
Karl Heinz schrieb:> Roland M. schrieb:>>> Ist das nicht der eindeutige Beweis dafür, dass ich gar keinen Fehler in>> meinem Programm versteckt habe?>> Nein.> Es ist nur der Beweis dafür, dass sich der Fehler nicht auswirkt.
Gemeint ist: das er sich nicht mehr in der "zuvor beobachteten Form"
auswirkt. Es kann sogar sein, dass überhaupt keine Anomalie mehr
wahrnehmbar ist. Allerdings ist das immer ungut. Denn der Fehler ist ja
nicht beseitigt worden und wartet nur darauf, an anderer Stelle erneut
zuzuschlagen. Durchaus auch erst bei der nächsten Programmerweiterung.
Karl Heinz schrieb:> Karl Heinz schrieb:>> Roland M. schrieb:>>>>> Ist das nicht der eindeutige Beweis dafür, dass ich gar keinen Fehler in>>> meinem Programm versteckt habe?>>>> Nein.>> Es ist nur der Beweis dafür, dass sich der Fehler nicht auswirkt.>> Gemeint ist: das er sich nicht mehr in der "zuvor beobachteten Form"> auswirkt. Es kann sogar sein, dass überhaupt keine Anomalie mehr> wahrnehmbar ist. Allerdings ist das immer ungut. Denn der Fehler ist ja> nicht beseitigt worden und wartet nur darauf, an anderer Stelle erneut> zuzuschlagen. Durchaus auch erst bei der nächsten Programmerweiterung.
Hallo Karl-Keinz,
wobei, wenn ich so sehe was beschrieben wurde und wie sichs auswirkt
würde ich eher auf Optimierung tippen.
Da fehlt mir noch die Info die ich oben mal nachgefragt hatte.
grüße
Peter
Peter W. schrieb:> Hallo Karl-Keinz,> wobei, wenn ich so sehe was beschrieben wurde und wie sichs auswirkt> würde ich eher auf Optimierung tippen.
Kann sein.
Kann aber auch sein, dass er irgendwo undefiniertes Verhalten im C Code
hat und der Optimizer das gnadenlos ausnutzt.
Was ich aber niemandem empfehlen würde: die Sache einfach zu ignorieren
und zu sagen: Ich stell den Optimizer einfach ab und gut ists.
Genaueres weiß man leider erst dann, wenn man das Problem im Detail
identifiziert, verstanden und beseitigt hat.
> Hallo Karl-Keinz,> wobei, wenn ich so sehe was beschrieben wurde und wie sichs auswirkt> würde ich eher auf Optimierung tippen.>> Da fehlt mir noch die Info die ich oben mal nachgefragt hatte.>> grüße> Peter
Entschuldige bitte, welche Informationen benötigst du noch?
> Gemeint ist: das er sich nicht mehr in der "zuvor beobachteten Form"> auswirkt. Es kann sogar sein, dass überhaupt keine Anomalie mehr> wahrnehmbar ist. Allerdings ist das immer ungut. Denn der Fehler ist ja> nicht beseitigt worden und wartet nur darauf, an anderer Stelle erneut> zuzuschlagen. Durchaus auch erst bei der nächsten Programmerweiterung.
Ich habe gesagt, dass das Debugging sich komisch verhält (mehrfache
Sprünge in ELSE-/CASE-Verzweigungen). Das produktive Ergebnis war aber
eigentlich immer richtig.
Ein Beispiel: Mit eingeschalteter Checkbox war ich beim Debugging immer
verwirrt, dass sowohl der richtige switch-Case, als auch nachfolgend
Zeile "DisplaySelectValue(m_OffTime, "ms", MIN_OFF_TIME, MAX_OFF_TIME);"
ausgeführt worden ist. Zumindest hat der Debugger mir das so suggeriert.
Auf dem LCD-Display stand jedoch immer das richtige Resultat (zu
erkennen am Wertebereich sowie der Endung ("ms" != "mV").
Roland M. schrieb:> Ich habe gesagt, dass das Debugging sich komisch verhält (mehrfache> Sprünge in ELSE-/CASE-Verzweigungen). Das produktive Ergebnis war aber> eigentlich immer richtig.
Ah. Moment
Das ist jetzt aber eine neue Information.
Denn das ist durchaus normal, dass sich bei eingeschaltetem Optimizer im
Debugger andere Reihenfolgen ergeben.
Ein Optimizer kann durchaus auch Codereihenfolgen umdrehen. Kurz und
gut: Der Code, der nach dem Optimizer raus kommt und der dann
tatsächlich auf dem µC läuft, hat nur noch eine sehr lockere Bindung zu
dem, was du geschrieben hast. EIn Optimizer darf alles umdrehen, solange
sich das extern beobachtbare Verhalten des Programmes nicht verändert.
Oft ist es überhaupt nicht mehr möglich, einzelne Assemblerabschnitte
einer bestimmten C-Code Zeile zuzuordnen. Was soll der Debugger dann
machen?
Roland M. schrieb:> Ich habe gesagt, dass das Debugging sich komisch verhält (mehrfache> Sprünge in ELSE-/CASE-Verzweigungen).
Je nach Build/Debugging System darfst du zum Debuggen nicht optimieren,
da sonst nur Blödsinn herauskommt, weil der Debugger den Sourcecode dem
optimierten Binärfile nicht mehr korrekt zuordnen kann.
Es ist wahrscheinlich so, daß man jede Optimiereung abschalten muß,
damit genau das ,was im Quelltext steht, übersetzt wird.
Ich stelle mir die Optimierungsfunktion von diesem Kompiler so vor:
Auf ein Tonband lese ich den Roman "Robinson Crusoe". Nach der Opti-
mierung ist dann "Die Schatzinsel" auf dem Band.
;-)
MfG Paul
Karl Heinz schrieb:
> Ah. Moment> Das ist jetzt aber eine neue Information.> Denn das ist durchaus normal, dass sich bei eingeschaltetem Optimizer im> Debugger andere Reihenfolgen ergeben.> Ein Optimizer kann durchaus auch Codereihenfolgen umdrehen. Kurz und> gut: Der Code, der nach dem Optimizer raus kommt und der dann> tatsächlich auf dem µC läuft, hat nur noch eine sehr lockere Bindung zu> dem, was du geschrieben hast. EIn Optimizer darf alles umdrehen, solange> sich das extern beobachtbare Verhalten des Programmes nicht verändert.> Oft ist es überhaupt nicht mehr möglich, einzelne Assemblerabschnitte> einer bestimmten C-Code Zeile zuzuordnen. Was soll der Debugger dann> machen?
Eben drum habe ich ja auch geschrieben (entschuldigt, wenn ich mich
selbst zitiere):
> Da das Ergebnis für mich jedoch stets richtig war und auch alles> funktioniert und ich damals im Studium gelernt habe, dass Compiler> ziemlich intelligente Programme sind, wird das schon alles so seine> Richtigkeit haben... Oder etwa nicht? :-D
Aber ich hatte ja bereits vermutet, dass ich mich damit vermutlich nicht
ganz deutlich ausgedrückt habe.
Udo Schmitt schrieb:
> Je nach Build/Debugging System darfst du zum Debuggen nicht optimieren,> da sonst nur Blödsinn herauskommt, weil der Debugger den Sourcecode dem> optimierten Binärfile nicht mehr korrekt zuordnen kann.
Es war ja auch nicht meine Absicht, dass der Optimierer überhaupt
angeschaltet ist, aber wie meine Tests gezeigt haben, hat sich die
Checkbox (-Os), trotz leerem Feld in der DropDownListe zur Auswahl der
Optimierungsstufe, auf meinen Quelltext ausgewirkt...
> Es ist wahrscheinlich so, daß man jede Optimiereung abschalten muß,> damit genau das ,was im Quelltext steht, übersetzt wird.> Ich stelle mir die Optimierungsfunktion von diesem Kompiler so vor:> Auf ein Tonband lese ich den Roman "Robinson Crusoe". Nach der Opti-> mierung ist dann "Die Schatzinsel" auf dem Band.
Eine nette Analogie, aber passend zur meinem Problem ;-)
Ich hatte halt gedacht, dass die Checkbox bei deaktivierter Optimierung
nichts weiter bewirken würde...
Hi Roland,
ich hatte dir vorgeschlagen zu schauen, ob die Daten richtig in die
aufgerufene Funktion übergeben werden, das ist dann ein Indiz dafür, wo
der Aufruf erfolgt ist.
Du kannst auch den Call-stack verwenden, ich weiss nur nicht, wie gut er
im Code Composer implementiert ist.
Im IAR klappt das trotz Optimierung (ich habe mir mal dein Codeschnipsel
in den IAR eingebaut) ganz gut.
Wie Udo schon sagte, zum debuggen ist Optimierung suboptimal, wenn das
wirklich nötig ist, ist das disassembly dein Freund....
Grüßle
Peter
Roland M. schrieb:>> Hallo Karl-Keinz,>> wobei, wenn ich so sehe was beschrieben wurde und wie sichs auswirkt>> würde ich eher auf Optimierung tippen.>>>> Da fehlt mir noch die Info die ich oben mal nachgefragt hatte.>>>> grüße>> Peter>> Entschuldige bitte, welche Informationen benötigst du noch?>>> Gemeint ist: das er sich nicht mehr in der "zuvor beobachteten Form">> auswirkt. Es kann sogar sein, dass überhaupt keine Anomalie mehr>> wahrnehmbar ist. Allerdings ist das immer ungut. Denn der Fehler ist ja>> nicht beseitigt worden und wartet nur darauf, an anderer Stelle erneut>> zuzuschlagen. Durchaus auch erst bei der nächsten Programmerweiterung.>> Ich habe gesagt, dass das Debugging sich komisch verhält (mehrfache> Sprünge in ELSE-/CASE-Verzweigungen). Das produktive Ergebnis war aber> eigentlich immer richtig.>> Ein Beispiel: Mit eingeschalteter Checkbox war ich beim Debugging immer> verwirrt, dass sowohl der richtige switch-Case, als auch nachfolgend> Zeile "DisplaySelectValue(m_OffTime, "ms", MIN_OFF_TIME, MAX_OFF_TIME);"> ausgeführt worden ist. Zumindest hat der Debugger mir das so suggeriert.> Auf dem LCD-Display stand jedoch immer das richtige Resultat (zu> erkennen am Wertebereich sowie der Endung ("ms" != "mV").