beim ersten Durchlauf springt der Debugger sofort in die "IF" Bedingung
i=0
keychanged=0x02
somit ist die Bedingung false
Der Debugger übergeht aber das IF Statement und springt gleich in
"tu etwas"
ist mir zu hoch
Die Optimierung steht auf -Os, -O1 geht auch nicht.
Ohne Optimierung wird mir der Code zu groß.
Schöne Weihnachtsfeiertage
Hans
Hans F. schrieb:> Der Debugger übergeht aber das IF Statement und springt gleich in> "tu etwas"Hans F. schrieb:> Die Optimierung steht auf -Os
Dann kann der Compiler vielleicht merken, daß der erste Durchlauf nichts
macht?
Wäre zumindest nachvollziehbar.
Hans F. schrieb:> Ohne Optimierung wird mir der Code zu groß.
Dann darfst du dich aber auch nicht wundern, wenn der Compiler Code
erzeugt, der anders abläuft wie in deinem Quelltext steht.
Bedingung ist nur, daß im Endeffekt dasselbe rauskommt.
Daß ein wirkungsloser erster Schleifendruchlauf auch wirklich ausgeführt
wird, steht nicht in den Spielregeln, wenn man mit Optimierung arbeitet.
Wo ist das Problem?
Hans F. schrieb:> Der Debugger übergeht aber das IF Statement und springt gleich in> "tu etwas"
Mit welchem Wert von i?
wird i überhaupt verwendet?
> Dieses AVR Studio / debugger macht mich crasy
Deine Sprache zieht mir die Fußnägel hoch.
Hans F. schrieb:> Schöne Weihnachtsfeiertage
dto.
Debuggen geht grundsätzlich nur ohne Optimierung. Auch auf großen C++
Compilern für PC.
Das ist eine Grundregel die man nur einmal akzeptieren muss und dann ist
gut. Deshalb den Controller immer eine Nummer größer wählen.
> Debuggen geht grundsätzlich nur ohne Optimierung.
@TO
Zumindest muss man damit rechnen, dass die Reihenfolge der Anweisungen
umsortiert wird und nicht alles ganz genau so ausgeführt wird, wie es
der Programmierer niedergeschrieben hat. Sonst wärs ja auch keine
Optimierung, denn dazu muss der Compiler ja schliesslich irgendwas
verändern.
Und wie schon gesagt: solange sich am #sichtbaren# Ergebnis des
Programms nichts verändert, darf er das auch.
> Ohne Optimierung wird mir der Code zu groß.
Solange du solche Expressions wie 1<<i benutzt, schätze ich mal, dass
man in deinem Programm noch vieles besser machen könnte.
Bei solchen C-code-Zeilen:
if (((1<<i) & keychanged) != 0)
würde ich von Anfang an, die kritischen Stellen auf Assembler-Ebene
debuggen.
Ich weiss zwar nicht, ob das unter AVR Studio möglich ist - Der GDB/DDT
kann es jedenfalls.
Hans Peter
Wenn das "sichtbare Ergebnis" gleich bleiben würde, hätte ich ja auch
nichts dagegen.
Aber genau hier ist das Problem
Beim ersten Schleifendurchlauf ist i = 0
1<<i = 0x01
keychanged = 0x02
0x01 & 0x02 ist definitiv == 0
trotzdem wird die if Bedingung true und der Code dahinter wird
ausgeführt.
Der Debugger überspringt sogar das if Statement und springt gleich
in die nachfolgende Klammer.
{
// tu etwas
}
Und Optimierung hin oder her, das Ergebnis sollte richtig sein.
@kbuchegg
Was ist gegen 1<<i auszusetzen wenn man bitweise maskieren will?
Ich bin nicht lernresistent und neugierig auf eine bessere Variante.
@ Klaus Wachtler
Na bei den Fußnägeln kann ich auch nicht helfen.
Aber wenn man >3h einen Fehler sucht, dann feststellt das der Code
nicht das macht was erwartet wird und man die Ursache nicht ergründen
kann, geht halt schon mal der Gaul durch.
Nach mehr als 25 Jahren Programmierung macht mich das halt crazy.
Nix für ungut.
Ich hab das ganze sogar in Einzelstatements zerlegt mit dem gleichen
Ergebnis.
@Hans Peter
Die Möglichkeit habe ich im AVR Studio noch nicht gefunden.
Wobei ich die Zeile nicht als kritisch ansehe.
@Astro
Die Einstellung -O1 ist default beim AVR Studio.
Somit hätte ich schon erwartet, das diese auch brauchbare Ergebnisse
liefert. Zumindest sollte das Resultat nicht falsch sein.
In dem Sinne
Immer ein Bit übrighalten :)
Hans
kann zwischen
uint8_t keychanged=0x02;
und dem Aufrauf der Schleife irgendwo der Wert von keychanged geändert
werden? Fall nicht, weiß der Compiler schon, dass der "tue etwas" Teil
genau nur einmal aufgerufen wird (nämlich für i==1). Dann kann er sich
Schleife und if-Abfrage sparen.
Klaus Wachtler schrieb:> Mit welchem Wert von i?> wird i überhaupt verwendet?
Das ist die relevante Frage. Wird im "tue etwas" Teil i wirklich falsch
benutzt? Was ist denn das falsche Ergebnis, das sich daraus ergibt? Dass
der Debugger einen direkten Einsprug anzeigt, ohne zuvor auf einigen
nicht benötigten Code-Zeilen herumzuspringen, ist noch kein falsches
Ergebnis.
Achim S.
Hans F. schrieb:> @Hans Peter> Die Möglichkeit habe ich im AVR Studio noch nicht gefunden.> Wobei ich die Zeile nicht als kritisch ansehe.
Gilt für Studio 6: Starte eine Debug Session, dann wähle "Debug |
Windows | Disassembly"
Hans F. schrieb:> Was ist gegen 1<<i auszusetzen wenn man bitweise maskieren will?> Ich bin nicht lernresistent und neugierig auf eine bessere Variante.AVRs haben keinen Barrel-Shifter o.ä., sodass im schlimmsten Fall bei
jeder einzelner Berechnung von (1 << i) eine Schleife durchlaufen
werden muss, die die 1 i mal um eins nach links shiftet. Das ist langsam
und verbraucht Speicher.
Besser wäre
Hans F. schrieb:> Nix für ungut.
Nix für ungut.
Aber wenn dein Code nach der Optimierung nicht mehr das tut, was du ohne
Optimierung erwartet hast, dann ist es meistens so, dass DU einen Fehler
gemacht hast.
Der C-Compiler und speziell der Optimizer kann besser C als 99% der hier
anwesenden Poster und kennt die Regeln besser. Natürlich kommt es auch
vor, das Compiler/Optimizer ferhlerhaft sind. Aber in den meisten Fällen
ist es der Fehler des Programmierers.
Und nein: mit 'sichtbares Ergebnis' ist NICHT gemeint, dass du im
Debugger exakt dieselbe Schritte siehst. Das kann und wird differieren.
Mit sichtbarem Ergebnis ist alles gemeint, was du letztendlich im I/O
sehen wirst. Seien das Pins oder Ausgaben auf ein LCD oder UART oder
dergleichen.
Aus deinem Code kann man nichts ableiten, was denn jetzt fehlerhaft sein
sollte, ausser das dein vom Compiler optimiertes Programm im Debugger
nicht die Schritte macht, die du erwartet hättest. Was aber weiter nicht
verwunderlich ist. Denn wie soll denn ein Optimizer ein Programm
schneller machen, wenn er nichts verändern darf? Wenn da mal drüber
nachdenkst, kommst du drauf, dass das nicht geht. Ergo wirst du im
Debugger bei einem Programm, über welches sich der Optimizer her gemacht
hat IMMER Differenzen in der Reihenfolge der Ausführungen sehen.
OK, ich denke die Problematik ist noch nicht ganz angekommen
Ich schreibs mal anders
1
uint8_tkeychanged=0x02;
2
3
uint8_ti=0;
4
5
for(i=0;i<7;i++)
6
{
7
if(((1<<i)&keychanged)!=0)
8
{
9
printf("Wert von i = %x ",i);
10
}
11
}
Ausgabe:
"Wert von i = 0"
"Wert von i = 1"
Erwartet hätte ich:
"Wert von i = 1"
aber nicht
"Wert von i = 0"
so und jetzt wird Zeit für die Familie
wünsche allen ein schönes Weihnachtsfest
Hans
Hans F. schrieb:> OK, ich denke die Problematik ist noch nicht ganz angekommen>> Ich schreibs mal anders>>
1
>uint8_tkeychanged=0x02;
2
>
3
>uint8_ti=0;
4
>
5
>for(i=0;i<7;i++)
6
>{
7
>if(((1<<i)&keychanged)!=0)
8
>{
9
>printf("Wert von i = %x ",i);
10
>}
11
>}
12
>
>
Und das ist TATSÄCHLICH dein Programm, welches dir Ärger bereitet hat?
Die Betonung liegt auf TATSÄCHLICH!
Du hilfst niemanden damit, wenn du jetzt auf die Schnelle ein Programm
erfindest, welches NICHT dein Problem darstellt. Ich bin mir nämlich
sehr sicher, dass dieses Programm NICHT den von dir angegebenen Output
liefert, wenn ich ein main drumherum stricke und es laufen lasse.
Optimizer hin oder her.
Hans F. schrieb:> OK, ich denke die Problematik ist noch nicht ganz angekommen>> Ich schreibs mal anders
das hilft nichts. Wenn ein Programm nicht funktioniert dann musst du
dieses zeigen, und nicht ein anderes!
Bernd schrieb:> das hilft nichts. Wenn ein Programm nicht funktioniert
Wobei für mich der Terminus "nicht funktioniert" noch lange nicht
nachgewiesen ist.
Eine andere Schrittfolge im Debugger zu sehen, ist noch lange nicht
"funktioniert nicht".
Ändert aber nichts an der Feststellung, dass das exakte Programm her
muss und man sich dessen Ergebnisse ansehen muss, um zu entscheiden, ob
hier überhaupt ein Fehler vorliegt oder ob einfach nur seine Erwartungen
falsch waren.
Karl Heinz Buchegger schrieb:> printf("Wert von i = %x ",i);
dass das nicht das Originalprogramm ist kann man auch daran erkennen
dass der Output auch gar nicht
Wert von i = 0
Wert von i = 1
sein kann wie von Hans geschrieben
Bernd schrieb:> Karl Heinz Buchegger schrieb:>> printf("Wert von i = %x ",i);>> dass das nicht das Originalprogramm ist
Ist es ganz sicher nicht.
Das beobachtete Verhalten im Debugger lässt sich ganz leicht mit einer
Kombination aus Loop-Unrolling, Constant-Folding und Dead Code
Elimination erklären. Alles Standardmechanismen in der Optimierung.
Das i im Debugger nicht den erwarteten Wert hat bzw. dass der
Asuführungspfeil sofort bis in die then-Klausel vom if runterrutscht ist
nichts beunruhigendes, solange der tu_was Teil trotzdem des Korrekte
macht. Und bis jetzt gibt es keine gegenteilige Aussage (die printf
Variante nehm ich jetzt mal nicht ernst)
Hans F. schrieb:> OK, ich denke die Problematik ist noch nicht ganz angekommen
Ist sie. Voll und ganz.
Was dir weiter oben schon mal jemand sagen wollte: Vergiß einfach, was
du im Debugger siehst. Gerade die avr-Debugger zeigen bei optimiertem
Code Dinge an, die nichts mit dem tatsächlichen Programmablauf zu tun
haben. Da kommt schlicht die Zuordnung des Assembler-Codes zu den
C-Cource-Zeilen durcheinander. Entweder debuggst du ohne Optimierung,
wenn das gar nicht passt, versuch mal mit -O1. Alternativ nimm zum
Debuggen einen Prozessor aus der gleichen Familie mit mehr Speicher.
Solange du allerdings solche trivialen Dinge untersuchst, solltest du
dein Programm abspecken, und Modul für Modul testen. Dann passt es auch
wieder ohne Optimierung in den Speicher.
Oliver
@all
So das Programm läuft jetzt. :)
Ich weis zwar noch nicht 100% warum, aber der Tip von Mark brachte
den Durchbruch.
Das Source Snippet ist nicht 100% das gleiche, führte aber zum gleichen
(falschen) Ergebnis.
Das Statement
printf("Wert von i = %x ",i);
war nur symbolhaft, macht auf dem AVR so ja auch nicht viel Sinn.
Der Rumpf war aber identisch.
Den kompletten Source gibts später mal, sobald das Gesamtprojekt zur
Zufriedenheit läuft.
Dank an alle die hier unterstützt haben.
Gruß Hans
Hans F. schrieb:> Ich weis zwar noch nicht 100% warum, aber der Tip von Mark brachte> den Durchbruch.
damit hast du dein "Problem" das keines war "gelöst":
vermutlich kann der Compiler jetzt nicht mehr optimieren und führt die
Schleife deshalb aus
>> Das Source Snippet ist nicht 100% das gleiche, führte aber zum gleichen> (falschen) Ergebnis.
Unsinn
Hans F. schrieb:> Nach mehr als 25 Jahren Programmierung macht mich das halt crazy.
nach 25 Jahren Programmierung solltest Du eigentlich wissen das es auf
jedes Komma ankommt und das man deshalb (im Gegensatz zu Doktorarbeiten)
immer die ORIGINAL-Source mit Copy and Paste posten muss!
Bernd schrieb:> damit hast du dein "Problem" das keines war "gelöst":> vermutlich kann der Compiler jetzt nicht mehr optimieren und führt die> Schleife deshalb aus
Mein lieber Bernd,
das hier ist ein Hobby Projekt und soll es auch bleiben.
Für mich kommt es mehr darauf an das Ziel zu erreichen, als jedes Bit zu
analysieren und auch noch die letzte Schleife zu optimieren.
Das Projekt soll schließlich auch mal fertig werden und zum Einsatz
kommen.
Auch hierzu gibt es einen persönlichen Zeitrahmen.
Sicher interessiert es mich, warum die obrige Variante nicht
funktioniert, ich bin aber nicht bereit unendlich viel Zeit in die
Analyse zu stecken.
Es gibt wichtigeres im Leben als dies.
Die jetzige Lösung führt nicht nur zum Ziel, sondern ist darüber hinaus
auch performanter, wobei letzters hier keine Rolle spielt.
Damit gilt das Problem für mich als "gelöst".
Im übrigen ist es völlig belanglos, was in dem IF Statement passiert,
da hier nichts das Fehlverhalten beeinflußt.
Nebenbei bemerkt, ist es auch in der kommerziellen Software Entwicklung
häufig so, das ein Problem durch einen "Workaround gelöst wird."
Dies kann unterschiedliche Ursachen haben:
Sei es das ein Problem in einem Software Addon eines Zulieferers liegt,
das sich kurzfristig nicht ändern läßt, oder der Zulieferer an einer
Änderung nicht interessiert ist.
Oder sei es ganz einfach das der Termin und Projektdruck eine
ausführliche
Analyse nicht zuläßt, da eine Überschreitung des Zeit / Budgetrahmens
enorme Kosten und Regressansprüche nach sich zieht.
Es gibt viele Wege zum Ziel und nicht immer ist der kürzeste auch der
optimalste.
Und damit möchte ich diese Diskussion hier beenden.
Ich bedanke mich bei allen die "Zielorientiert" zur Lösung beigetragen
haben.
Hans
Hans F. schrieb:> Sicher interessiert es mich, warum die obrige Variante nicht> funktioniert,
Der speingende Punkt ist: sie hat funktioniert.
Dein Problem war ein ganz anderes: Du hast das was du im Debugger
gesehen hast falsch interpretiert.
> ich bin aber nicht bereit unendlich viel Zeit in die> Analyse zu stecken.
Falscher Ansatz.
Wenn du ein Haus baust und es stürzt dir ein, dann musst du rausfinden
warum.
> Damit gilt das Problem für mich als "gelöst".
Ein Problem ist niemals gelöst, solange man nicht die Ursachen kennt,
die zum Problem geführt haben.
Das was du in deinem Eröffnungsposting erzählt hast, war es jedenfalls
sehr sehr wahrscheinlich nicht. Du hast sozusagen lediglich deine
Messinstrumente falsch interpretiert. Warum dir aber der Kernreaktor um
die Ohren geflogen ist, hast du damit aber nicht erklärt.
> Im übrigen ist es völlig belanglos, was in dem IF Statement passiert,> da hier nichts das Fehlverhalten beeinflußt.
Irrtum.
Genau das beeinflusst es. Denn es steuert, welche Optimierungen der
Compiler in welcher Form anwenden kann. Und da du im optimierten Code
debuggen willst/musst, musst du dieses Verhalten kennen und mit
einbeziehen um nicht dem Trugschluss zu verfallen, dem du zum Opfer
gefallen bist. Du bist einem Phantom hinterher gejagt.
> Nebenbei bemerkt, ist es auch in der kommerziellen Software Entwicklung> häufig so, das ein Problem durch einen "Workaround gelöst wird."
Bitte nenn uns die Firma. Damit wir in Zukunft einen großen Bogen um
diese 'Softwarebude' machen können.
> Sei es das ein Problem in einem Software Addon eines Zulieferers liegt,> das sich kurzfristig nicht ändern läßt, oder der Zulieferer an einer> Änderung nicht interessiert ist.>> Oder sei es ganz einfach das der Termin und Projektdruck eine> ausführliche> Analyse nicht zuläßt, da eine Überschreitung des Zeit / Budgetrahmens> enorme Kosten und Regressansprüche nach sich zieht.
Du redest von ganz anderen Dingen.
Bei dir dreht es sich an dieser Stelle nicht um Zulieferer, die
ausfallen oder um eng gesteckte Zeitrahmen. Bei dir dreht es sich darum,
dass du schlicht und ergreifend mit deinem Werkzeug nicht umgehen
kannst. Brutal gesagt.
Ich werde das nicht weiter kommentieren.
Auf dieses Niveau zieht mich niemand herunter!!!
Gut möglich das ich einem Phantom hinterhergejagt,
Oder einfach den Eigenheiten des Compilers erlegen bin.
Das alles ist aber kein Grund diesen Ton anzuschlagen.
Hans F. schrieb:> Ich werde das nicht weiter kommentieren.> Auf dieses Niveau zieht mich niemand herunter!!!>> Gut möglich das ich einem Phantom hinterhergejagt,> Oder einfach den Eigenheiten des Compilers erlegen bin.>> Das alles ist aber kein Grund diesen Ton anzuschlagen.
Was erwartest du?
Du präsentierst etwas, von dem jedem hier klar ist, dass es NICHT dein
Problem darstellst. Die Aufforderung, doch bitte ein komplettes
nachvollziehbares Beispiel zu posten, ignorierst du geflissentlich.
Statt dessen flüchtest du dich in eine Scheinwelt, in der es dich nicht
interessiert, was denn eigentlich das Problem war.
Professionell ist etwas anderes.
Und es passt so gar nicht zu deinen 25 Jahren Programmiererfahrung.
Mein lieber Karl Heinz Buchegger,
niemand hat hier explizit nach dem kompletten Programm gefragt.
Ich habe das Ergebnis selbst nicht geglaubt.
Daher habe ich vor dem Post das ganze im 2010er Studio gedebuggt.
Wie zu erwarten, gab es hier den Fehler nicht.
Dann hab ich das Resultat incl. aller Variablen vom AVR über den UART
ausgeben lassen.
Resultat: Die If Anweisung war auch bei i=0 true.
Erst danach habe ich diesen Thread verfasst.
Im übrigen habe ich nirgendwo geschrieben, das ich 25 Jahre Erfahrung
mit der AVR Programmierung habe.
Ganz im Gegenteil, einfach mal lesen!
und was dies hier betrifft
>>Bitte nenn uns die Firma. Damit wir in Zukunft einen großen Bogen um>>diese 'Softwarebude' machen können.
Ich nehm' dich gerne mal mit bei einem der nächsten Projekte.
Dann schau wir mal ob hinter den Sprüchen auch Taten stehen.
Aufgrund der Ausartung dieses Threads werde ich mein Projekt hier nicht
mehr zur Verfügung stellen.
Von einem Moderator erwarte ich das er "moderiert" und nicht beleidigt.
@ Frank M.
solltest du weiter Interesse an der Umsetzung haben, lass es mich
wissen.
Ansonsten bedanke ich mich für deine tolle Unterstützung!