mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ARM7 kopieren von 32bit-Zahlen


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen
ich bin hier langsam Bridget Jones - am Rande des Wahnsinns.  :(

Auf meinem ARM7 versuche ich einfach, einem unsigned long den Wert eines 
anderen zuzuweisen.
LocalIP ist eine globale Variable, msg->yiaddr ein unsigned long in 
einem Puffer. (Ihr seht schon, riecht nach DHCP...)
LocalIP = msg->yiaddr;
DEBUG("IP");
UART0_WriteByte(LocalIP==msg->yiaddr);
UART0_WriteBuffer((unsigned char*)&LocalIP, 4);
UART0_WriteBuffer((unsigned char*)&msg->yiaddr, 4);
Jedenfalls liefert die Vergleichsausgabe 1 (LocalIP==msg). Soweit 
korrekt.
Wenn ich aber die Werte über UART anzeigen lasse, dann fehlt 
(mindestens) das unterste Byte, das oberste Byte ist korrekt. Die beiden 
dazwischen sind vorher und hinterher korrekterweise 0.
Wenn ich die Zuweisung mit memcpy mache, ist das Ergebnis das gleiche. 
Alle Kombinationen mit volatile bringen auch nichts.
Die Ausgabe deckt sich übrigens mit dem Verkehr auf dem Netzwerk - alo 
kein Problem der UART-Funktionen. Sonst hätte ich mit dem Schmuß auch 
gar nicht erst angefangen.  ;)

Sieht jemand, wo mein Hirn aufhört und mein Fehler anfängt?  :(
Danke!
Andy

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal folgenden Code


unsigned char Buffer[4]

Buffer[0] = (unsigned char) LocalIP;
Buffer[1] = (unsigned char) (LocalIP >> 8);
Buffer[2] = (unsigned char) (LocalIP >> 16);
Buffer[3] = (unsigned char) (LocalIP >> 24);


UART0_WriteBuffer(Buffer, 4);


Gruss Helmi

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Helmi,
Danke für die Antwort. Ich werde es nachher noch ausprobieren.
Allerdings ist es glaube ich etwas am Problem vorbei.

LocalIP und msg->yiaddr sind beides unsigned long. Wenn die UART-Routine 
da ein Problem hätte, müßte sie doch bei beiden etwas falsches ausgeben.
Außerdem hatte ich das nur zur Fehlersuche. Das "Original"-Problem 
war/ist, daß LocalIP später weiterverwendet wird und genau da der Fehler 
auftauscht. Außerdem stimt die UART-Ausgabe mit dem überein, was übers 
Netz geht.

N.B. Das ganze ist ähnlich schon gelaufen. Der DHCP lief die ganze Zeit 
unter uIP. Jetzt stelle ich gerade auf meinen eigenen Stack um. Und 
jetzt tritt der Fehler auf. Vorher var LocalIP vom Typ uip_ipaddr_t, 
daher auch das memcpy().

Interrupts schließe ich aus, da das ganze Zeug in einem IRQ läuft und es 
keine FIQs gibt. Stack-Problem eigentlich auch nicht, weil es 1. in 
allen anderen Sockets funktioniert, und 2. LocalValue mitten in den 
Daten steht. Davor und dahinter ist alles in Ordnung. Außerdem müßte der 
Stack jetzt sogar kleiner sein, weil mein eigener IP-Stack 2 Tiefen 
weniger braucht.

Habe probehalber auch mal den Bereich vor msg->yiaddr mit -1 gefüllt, um 
zu sehen, ob er vielleicht "in die falsche Richtung" kopiert vom Zeiger 
aus gesehen. Ist aber auch nicht so. Wenn ich LocalIP bei der 
Initialisierung fest beschreibe, dann funzt es.

Alles sehr strange - wer hätte gedacht, daß ich jetzt schon für a=b zu 
doof bin.  :(

Autor: Tim Seidel (maxxie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist msg->yiaddr (4Byte) aligned?
Sonst schlägt das lesen fehl, damit ist auch der compare true (weil der 
Fehler beidemale auftritt) aber der Wert ist eben nicht byteweise gleich 
mit dem was an der unaligned addresse steht.

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe nicht so genau verstanden, welche Bytes verfälscht werden. Aber 
ich kenne solche Mysterien. Ursache war immer misalignment in gepackten 
Strukturen. Also 32-Bit-Felder, die nicht auf 4-Byte-Grenzen 
ausgerichtet sind.

Könnte das bei dir der Fall sein?

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tim,
das ist noch eine gute Idee. Gleich mal nachschauen.
Ansonsten müßte ich byte-weise kopieren...

Oder ich habe woanders einen Fehler. Der Netzwerk-Puffer ist ja von Haus 
aus aligned, die Netzwerk-Geschichten sind von Haus aus auch ziemlich 
alle an 16bit(!) ausgerichtet.
Fragt sich nur, warum dann memcpy scheitert. Arbeitet das nicht 
byteweise?

Ich frage deshalb so blöd, weil ich den Fehler dann wahrscheinlich noch 
an anderer Stelle kriege.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, kleiner Nachtrag.
&msg->yiaddr = 0x40001f3e, also wirklich im Puffer und an 16bit 
ausgerichtet.
Das wirds wohl sein.

Danke!

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anscheinend wurde der Fehler nicht von mir ge/erfunden:   ;)

http://gcc.gnu.org/ml/gcc-bugs/2000-03/msg00155.html

(falls nochmal jemand über diesen Thread stolpert)

Autor: Helmut Lenzen (helmi1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Fragt sich nur, warum dann memcpy scheitert. Arbeitet das nicht
>byteweise?

Wenns gut gemacht ist nicht. Dann werden nur die ersten nicht alignment 
Bytes einzeln kopiert dann gehts dann 32Bit mässig weiter.

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das läßt sich ziemlich gut austricksen, wenn man die (nicht-aligned) 
Struktur nach (char*) castet.
Dann funzt es auch mit memcpy().

Juju, es läuft!  freu
Genug Erfolg für heute. Danke Euch beiden und noch einen schönen Abend! 
;)

Andy

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.