Hallo zusammen,
ich bastle an einer Funktion herum, die mir zwei uint32_t[4] vergleichen
soll. Dieser Funktion übergebe ich die Pointer auf die Arrays, während
des Vergleichs wird beim Durchsteppen aber an irgendeiner Stelle die
Referenz zerstört, danach schlägt der Vergleich fehl.
Leider habe ich außer dem Debugging keine Möglichkeit nachzuvollziehen,
was das Programm macht (außer, dass ich weiß, dass es nicht das tut, was
ich möchte).
Beim Aufruf der Funktion CompareColors werden die richtigen Adressen
übergeben (lt. Debugger liegt background auf 0x0110 und measurement auf
0x0120), mit dem Eintritt in die for-Schleife zeigt er beim ersten
Vergleich, dass die Adressen entweder "irgendwas" enthalten, hier wurde
immer wieder 0x0940 gezeigt, oder der Debugger sagt "out of scope")
Ich habe auch versucht die Variablen als volatile zu definieren, ebenso
habe ich versucht die Funktionsparameter als const zu definieren. In
beiden Fällen unterscheidet sich vielleicht die Anzeige, ich habe aber
nichts gefunden, mit dem der Vergleich sauber funktioniert. Auch ein
Zugriff über reference[0] ändert nichts.
Umgebung:
MPLAB X IDE v6.05
XC8 v2.4
pickit4
Relevanter Code (main ist leicht gekürzt, ist aber für diesen Punkt
nicht relevant):
Keywords: implicit type promotion rules, int promotion!
Bedeutet bei 8-bit uC gehts Richtung int16_t,
also die Condition Operatoren casten (uint32_t) ...
Sebastian schrieb:> Ich habe auch versucht die Variablen als volatile zu definieren, ebenso> habe ich versucht die Funktionsparameter als const zu definieren.
Unbegründetes trail & error Spielen!? Spätestens jetzt sollte bewusst
werden, dass grundsätzlich was im Verständnis fehlt ...
Hallo und danke für die Antworten,
- implicit type promotion:
Ich habe diesbezüglich gegoogelt und die Doku für XC8 sagt: "uint32_t
Unsigned integer of exactly 32 bits
width.
unsigned long"
Ich verstehe es so, dass xc8 diese Typen unterstützt (und lt. Doku
sogar unsigned long long int) und dass der Compiler dafür sorgt, dass
diese Variablen richtig verarbeitet werden. Sollte das nicht so sein,
bin ich sehr an einer Erklärung interessiert.
- volatiles Verständnisproblem:
Ich möchte nicht darauf eingehen, wie sinnlos der Beitrag ist. Ich
habe geschrieben, dass das von mir erwartete Verhalten nicht gezeigt
wurde. Damit muss ich meine Erwartungen hinterfragen und nach einigem
erfolglosen googeln bin ich bei volatile und Compileroptimierungen
gelandet. Natürlich ist das Trial and Error, hätte ich eine Lösung,
würde ich hier nicht fragen.
Ich bin Anfänger in C und willig zu lernen. Da der Debugger Sachen
macht, die ich nicht erklären kann, gibt es die Variante, dass in den
paar von mir geposteten Zeilen etwas den Heap umschreibt oder sonst
irgendwelche Schweinereien macht (die Init() Funktion schiebt nur
Register für die Pin-Definition) oder der Debugger den Ablauf
durcheinanderbringt. Beides würde ich verstehen, hätte aber gern
verstanden, warum das so ist.
tia
Sebastian
Hallo,
Du verwendest 32 Bit Werte in einem Array. Du möchtest im Array durch
Inkrementieren des Pointers den nächsten Wert erreichen.
Ich weiß jetzt nicht, welchen Controller du verwendest aber evtl. musst
du um mehrere Bytes inkrementieren um den Pointer zum nächsten
Array-Element setzen.
Sebastian schrieb:> Ich habe diesbezüglich gegoogelt und die Doku für XC8 sagt: "uint32_t> Unsigned integer of exactly 32 bits width unsigned long"
... dann google nochmal und fang an nachzudenken! Welche Typen XC8
unterstützt hat nichts mit int Promotion zu tun.
Sebastian schrieb:> - volatiles Verständnisproblem:
... erkennbar hast du kein Verständnis vom Sinn zu const und volatile
und zudem die Vorstellung das dritte als Erklärbär dir das abnehemen,
dieses copy&past Verhalten verdient laute Kritik und ist leider typisch
für die vielen Anhnungslosen unserer Zeit. Selber arbeiten? Nee warum,
die Community macht das alles für mich ...
... und Leseverständnis auch mehr als unzureichend, weil die angebene
Lsg. wurde erkennbar auch nicht ausprobiert.
Hans K. schrieb:> Du verwendest 32 Bit Werte in einem Array. Du möchtest im Array durch> Inkrementieren des Pointers den nächsten Wert erreichen.> Ich weiß jetzt nicht, welchen Controller du verwendest aber evtl. musst> du um mehrere Bytes inkrementieren um den Pointer zum nächsten> Array-Element setzen.
... gehe besser was anderes spielen!
Ein Pointer ist Type und Maschinen abhängig und incrementiert
entsprechend, also hier bei 8-bit Maschine viermal.
Hi,
wenn deine Aussagen auch ohne persönliche Angriffe gingen, könnte ich
sogar annehmen, dass das hier ein Forum ist, in dem man bei Unklarheiten
nachfragen kann -> man kann offensichtlich nicht alles haben. Ich habe
von meinem Code nichts kopiert, ich wüsste noch nicht mal, woher. Bei
der Einfachheit der Funktionen gäbe es dafür auch keinen Grund
Zur implicit type promotion:
Die Regeln der impliziten Konvertierung besagen, dass im Falle des
Falles nach oben konvertiert wird, int zu long zu long long, bzw. von
signed zu unsigned.
Jetzt habe ich schon unsigned long, eine Umwandlung kann das System von
mir aus auch machen, das war niemals meine Frage, lasse mich aber gerne
erklären, warum das relevant ist.
Meine Frage, zur nochmaligen Erklärung, war, warum der Debugger von
MPLAB X beim Durchsteppen durch die Funktion beim Funktionseinstieg die
jeweilige Adresse für die beiden Argumente anzeigt (und damit auch Werte
der Speicherstelle), nach dem ersten Vergleich (bei dem gerne gecasted
werden kann, das ist erst in zweiter Linie für meine Frage relevant)
aber weder eine Adresse noch ein Wert angezeigt wird (der Debugger zeigt
danach nur mehr "out of scope"). Wenn das ein systemimanentes Problem
des Debuggers darstellt kann das natürlich so sein. Wenn der Debugger
bekanntermaßen immer einwandfrei und anstandslos Variablen anzeigt (ich
arbeite normalerweise mit Visual Studio und bin den Debugger dort
gewöhnt, verstehe aber die Schwierigkeiten auf einem Mikrocontroller zu
debuggen), habe ich, trotz keiner schreibenden Funktionen (ausgenommen
die Zuweisung von i für die Schleife) anscheinend etwas, das die
Speicherstelle überschreibt.
Dass volatile normalerweise nur bei etwas wie Interrupts benötigt wird,
weiß ich, dass const in der Argumentdeklaration vor der Typzuweisung
eigentlich die Adresse, aber nicht den Wert, konstant halten sollte (im
Unterschied zu const vor dem Argumentnamen), weiß ich ebenfalls. Nach
dem wir jetzt das Wettpissen hinter uns gebracht haben, könnte sich
vielleicht jemand finden, der einem Entwickler, der normalerweise eher
im C# und Visual Studio Umfeld arbeitet und sich erst kurz mit ATmega
auseinandersetzt, vernünftig erklärt, warum ich sehe, was ich sehe.
tia
Sebastian
Hi,
noch ein Nachsatz:
Ich habe COLORDELTA überprüft, das UL hat gefehlt, ich habe es
nachgetragen. Es ändert aber immer noch nichts an dem Verhalten, das ich
beim Debuggen sehe.
Daher nochmal zur Klarstellung: Mir geht es gerade um eine Aussage über
die Zuverlässigkeit von Debugger-Anzeigen, nicht um den direkten
Programmablauf.
tia
Sebastian
Du solltest 2-3 freie Pins deines uC nutzen als "Toggle"-Melder.
Mit Scope in Echtzeit verfolgen wo das Programm hinläuft.
Das ist zuverlässiger als Debugger.
Gruss
Hallo Erich,
danke für die Info. Das mit den Toggle-Pins hatte ich schon gemacht,
mich hat "nur" die Anzeige des Debuggers verwirrt. Seit ich weiß, was
ich davon erwarten kann, war es deutlich einfacher sich auf das
wesentliche zu konzentrieren, 4 Logikfehler zu finden (wäre auch ohne
Debugger gegangen, hat mich aber abgelenkt) und das Programm zu einem
angenehmen Ende zu bringen. Jetzt muss ich noch an meiner Hardware
rundherum basteln und wenn ich besonders verwegen bin, mache ich mich an
die Umstellung auf einen ATtiny85 (dafür hatte ich mal eine Platine
entworfen, durch den unklaren Programmlauf bin ich auf einen ATmega
gegangen, weil ich dort debuggen konnte).
Trotzdem nochmal vielen Dank für die Hilfe
cu und schönes Wochenende
Sebastian
Am gezeigten Code liegt es nicht. Der ist in Ordnung, bis auf die
Initialisierung der unsigned Werte mit -1.
Ein stack overflow verursacht solche Effekte, aber der ist aus dem
gezeigtem Code auch nicht ersichtlich.
Ergo: Fehler in Zeile 42.
Oliver
Hallo Oliver,
danke fürs Drüberschauen. Die Initialisierung mit -1 ist gleichbedeutend
mit 0xFFFF (das Zweierkomplement bei -1 sieht genauso aus) und hat den
Vorteil, dass es mit allen uint funktioniert, egal welche Größe.
cu
Sebastian
Sebastian schrieb:> MeasureColor(background);
Hallo Sebastian
Kannst Du bitte den Code von MeasureColor() mal posten? Der fehlt leider
in Deinem Listing und könnte evtl auch diesen Fehler erzeugen.
Und lass Dich nicht von Leuten wie Apollo ärgern. Das Forum ist ja schon
zum helfen gedacht.
/regards
Solltest die Frage anders stellen: Benutzt hier irgend jemand Pickit4
und XC-8 für ATmega328P?
Wäre auch vorstellbar, die Microchip Entwickler hatten die Pic Tools nur
Quick&Dirty auf Amtel Prozessoren portiert. Wollte halt irgendjemand aus
der Marketingabteilung. Ist nur noch nicht aufgefallen, weil die AVR
Programmierer bei ihren alten Tools bleiben.
Noch ein Kommentar schrieb:> Benutzt hier irgend jemand Pickit4> und XC-8 für ATmega328P?
MPLab Snap (was im wesentlichen ein abgespecktes Pickit4 ist)
funktioniert mit Microchip Studio ganz wunderbar mit Atmega328p, egal,
welchen C-Compiler man nun verwendet, den kastrierten XC-8 oder den
freien gcc. Beide werden mit Microchip Studio mitgeliefert.
Sebastian schrieb:> Die Initialisierung mit -1 ist gleichbedeutend> mit 0xFFFF (das Zweierkomplement bei -1 sieht genauso aus) und hat den> Vorteil, dass es mit allen uint funktioniert, egal welche Größe.
für 'uint' nehme ich lieber '~0'.