Hallo
Ich stehe auf dem Schlauch, warum es das eine Mal funktioniert und das
andere Mal nicht. Ich habe einen PIC32 mit XC32 und ICD3 zum debuggen.
Definiert habe ich folgendes (hintendran, die Adressen während des
Debuggens)
Da der PIC32 32bit-Befehle ausführen kann, möchte ich folgendes machen,
was auch funktioniert (die 6 Dimming-Variablen werden auf die 6
SpecLightDummy-Variablen kopiert):
die Frage ist, wieso hängt sich der uC dort auf?
Ich habe schon Copy/Paste gemacht und dann ".Dimming" durch
".WaterChange" ersetzt, jedoch führt das zum selben Problem. Ein
Tipfehler ist somit ausgeschlossen.
Danke für jegliche hilfe.
Master Snowman schrieb:> Da der PIC32 32bit-Befehle ausführen kann, möchte ich folgendes machen
Was Du eigentlich machen willst, hängt davon ab, was das Programm tun
soll. Also was die Anforderungen sind. Wie man diese dann umsetzt, steht
auf einem anderen Blatt. Es gibt ziemlich sicher einen besseren Weg, das
zu erreichen was Du willst - ohne wildes Rumgecaste.
XC32 User guide, Seite 140:
unsigned int hat eine Grösse von 32Bits. Wenn, dann müsstest du unsigned
short verwenden (16Bits). Ich würde aber solche Hacks grundsätzlich sein
lassen und die Arrays in einer for Schleife oder mit memcpy kopieren.
Denn woher willst du wissen, wie gross ein int auf einer anderen
Plattform ist?
@ Master Snowman (snowman)
>Definiert habe ich folgendes (hintendran, die Adressen während des>Debuggens)
Da geht das Problem schon los. Als C-Programmierer haben dich die
expliziten Adressen keine Sekunde zu interessieren. Die verwaltet der
Compiler!
>Da der PIC32 32bit-Befehle ausführen kann, möchte ich folgendes machen,>was auch funktioniert (die 6 Dimming-Variablen werden auf die 6>SpecLightDummy-Variablen kopiert):>*(unsigned long *)&SpecLightDummy[0] = *(unsigned long >*)&Settings0.Dimming[0];>*(unsigned int *)&SpecLightDummy[4] = *(unsigned int >*)&Settings0.Dimming[4];
Solche Monster-Cast sind ein sicheres Zeichen für Murks.
Was zum Geier spricht gegene eine GANZ NORMALE Zuweisung?
1
SpecLightDummy[0]=Settings0.Dimming[0];
Denkst du der Compiler is zu doof, das halbwegs gescheit auszuführen?
ASM-Denkweise beim C-Programmieren ist nicht sinnvoll. Das geht nur in
gaaanz wenigen Situationen gut. Und meist auch nicht nötig und sinnvoll!
Selbst eine Schleife für mehrere Elemente setzt jeder zurechnungsfähige
Compiler gut um, einfach über zwei Pointer.
1
for(i=0;i<6;i++){
2
SpecLightDummy[i]=Settings0.Dimming[i];
3
}
Und das ist in 99,99% aller Fälle schnell genug. Hochoptimierten
Assembler braucht man da nicht. Und wenn DOCH, dann nimmt man WIRKLICH
Assembler und keine vergewaltigten C-Konstrukte! Oder man nimmt DMA.
One PIC zu kennen -- viele 32-Bit Architekturen verlangen, daß
Speicherzugriffe entsprechend aligned sind, d.h. 32-Bit-Zugriffe sind
nure erlaubt, wenn die Speicherstelle an einer 32-Bit Grenze liegt.
Jedoch greifst du auf .WaterChange, das nicht auf einer 32-Bit-Grenze
liegt, durch den Cast 32-bittig drauf zu.
Lass das Gehampel mit den Cast-Schweinereien und verwende wie oben
empfohlen memcpy.
Bei PIC32 müssen IIRC Zugriffe aligned sein, d.h. du kannst ein 4 Byte
long nicht aus einer Adresse lesen, die nicht 4 byte aligned ist. Wenn
ab Dimming[0] noch ein long gelesen werden kann, dann scheitert dass
natürlich an WaterChange[0], dass 6 bytes weiter liegt.
Ausserdem solltest du mal nachgucken, was bei deinem Compiler
sizeof(int) ist. Du scheinst von 2 ausgehen, was bei PIC32 auch nicht
der Fall ist, oder?
Die Felder kopierst du überhaupt besser mit memcpy(). Das ist beim PIC32
Compiler (der auf GCC basiert) ein intrinsic, d.h. der Compiler "weiss"
was memcpy bedeutet und kann optimalen code generieren.
wow! vielen dank für die vielen beiträge. das mit dem aligned habe ich
noch nie gehört, macht aber logischerweise sinn - danke!
> Solche Monster-Cast sind ein sicheres Zeichen für Murks.> Was zum Geier spricht gegene eine GANZ NORMALE Zuweisung?> SpecLightDummy[0] = Settings0.Dimming[0];
weil dann nur das erste element kopiert wird ;-)
dass in einer for-schlaufe das byte-weise kopieren auch geht, ist mir
klar; jedoch wieso das in 6 schritten machen plus 6 bedingungsabfragen,
wenn's auch in 2 zuweisungen geht? daher dieser ansatz.
ich gebe zu, das ist natürlich murks aus jetztiger sicht nachdem ich das
oben gelesen habe. ich verwende jetzt memcpy, braucht sogar noch etwas
weniger platz als mein hack mit pointer :-)
vielen dank nochmals, auch für die superschnellen antworten!
Luther Blissett schrieb:> Bei PIC32 müssen IIRC Zugriffe aligned sein, d.h. du kannst ein 4 Byte> long nicht aus einer Adresse lesen, die nicht 4 byte aligned ist. Wenn> ab Dimming[0] noch ein long gelesen werden kann, dann scheitert dass> natürlich an WaterChange[0], dass 6 bytes weiter liegt.
Dieser Einwand ist nicht stichhaltig, denn wenn es harte Alignment-
forderungen geben sollte, dann würde der Compiler die struct-member
ohnehin alignen.
Tatsächlich sind diese Forderungen aber meist gar nicht hart, schon gar
nicht in einer Hochsprache. Im Zweifel werden halt einfach mehr Daten
gelesen bzw. geschrieben (ein write wird dann ein read-modify-write).
Das ist zwar sicherlich suboptimal, aber nicht unmöglich.
> Die Felder kopierst du überhaupt besser mit memcpy()
Das sowieso.
XL
Master Snowman schrieb:> dass in einer for-schlaufe das byte-weise kopieren auch geht, ist mir> klar; jedoch wieso das in 6 schritten machen plus 6 bedingungsabfragen,> wenn's auch in 2 zuweisungen geht?
Woher willst du denn wissen, wie das der Compiler umsetzt?
Du machst dich gerade der so ziemlich größten Sünde schuldig, die es für
einen Programmierer gibt: premature optimization. Du optimierst(?)
Dinge, für die weder klar ist ob sie a) optimierungswürdig noch b)
optimierungsbedürftig sind.
Die erste Priorität bei der Programmierung in einer Hochsprache sollte
die einfache Verständlichkeit (vulgo: Lesbarkeit, Wartbarkeit) des Codes
sein. Ein richtiger Programmierer hätte vermutlich die Größen der Arrays
in ein #define gepackt und würde sich evtl. später darüber freuen, daß
er das jetzt an einer einzigen Stelle ändern kann. Vergleiche das mal
mit den Klimmzügen, die deine "Lösung" erfordert, wenn die Arrays mal 9
statt 6 Elemente haben sollten.
XL