Hallo, Ich programmiere zur Zeit einen Atmega328p mit einem W5100 Wiznet Chip für die Ethernet Schnittstelle. Diese beiden kommunizieren über eine SPI Schnittstelle. Die Implementierung hat uach wunderbar geklappt, Verbindungsaufbau / -abbau, senden und empfangen klappt soweit. Jetzt habe ich die Aufgabe bekommen, Daten nach einem bestimmten Anwendungsprotokoll zu senden und zu empfangen: Anfrage: |NachrichtenLänge|NachrichtenTyp|anzSamples|16x bool Kanäle| |uint32|uint16|uint32|uint16| Antwort: |NachrichtenLänge|NachrichtenTyp| chan sample anz| |uint32|uint16|chan anz double| Mein Empfangsbefehl fürs Ethernet: ETH_recv(uint8_t *buf,uint16_t len); Problem: Ich habe probleme beim Einlesen der Request Anfrage. ms_len = ((unsigned long) buf[0] << 24) + ((unsigned long) buf[1] << 16) + ((unsigned long) buf[2] << 8) + ((unsigned long) buf[3]); uint16_t ms_typ = ((unsigned short) buf[4] << 8) + ((unsigned short) buf[5]); Diese Methode habe ich versucht, aber erhalte ich keine Nachvollziehbaren Daten. Kann mir jemand helfen, wie ich dieses Problem am besten realisieren kann oder wo mein Denkfehler liegt? Grüße Cassidy
Cassidy schrieb: > Problem: > Ich habe probleme beim Einlesen der Request Anfrage. > > ms_len = ((unsigned long) buf[0] << 24) > + ((unsigned long) buf[1] << 16) > + ((unsigned long) buf[2] << 8) > + ((unsigned long) buf[3]); > uint16_t ms_typ = ((unsigned short) buf[4] << 8) + > ((unsigned short) buf[5]); Dir ist aber schon klar, dass du hier allerhand Annahmen über die Bytereihenfolge triffst? zb das das höherwertigste Byte zuerst im Datenstrom kommt. Das muss aber nicht so sein. Das hängt unter anderem auch davon ab, wie der Sender die Daten auf den Weg bringt. > Diese Methode habe ich versucht, aber erhalte ich keine > Nachvollziehbaren Daten. Hast du dir schon mal die Einzelbytes angesehen? Also: Noch ehe du sie zu größeren Einheiten zusammensetzt.
Cassidy schrieb: > Kann mir jemand helfen, wie ich dieses Problem am besten realisieren > kann Bei solchen Problemen fängt man immer damit an, dass man sich zuerst auf tifster Ebene erst mal die Bytes ansieht, die aus einer Verbindung herauspurzeln und sich ansieht, ob die plausibel und richtig sein können. Und zwar sieht man sich die Bytes so an, wie sie ankommen: Als Bytes. Stimmen die schon nicht, ist es sinnlos auf höheren Ebenen nach Fehlern zu suchen.
Karl heinz Buchegger schrieb: > Dir ist aber schon klar, dass du hier allerhand Annahmen über die > Bytereihenfolge triffst? > zb das das höherwertigste Byte zuerst im Datenstrom kommt. > > Das muss aber nicht so sein. Das hängt unter anderem auch davon ab, wie > der Sender die Daten auf den Weg bringt. > >> Diese Methode habe ich versucht, aber erhalte ich keine >> Nachvollziehbaren Daten. > > Hast du dir schon mal die Einzelbytes angesehen? > Also: Noch ehe du sie zu größeren Einheiten zusammensetzt. Also Ich hatte vorher ein Programm, welches Zeichenketten (mit Trennzeichen) gesendet hat, dort kamen die Zeichen geordnet an und es konnte alles richtig interpretiert werden. Deshalb gehe ich davon aus, dass meine Bytes die übertragen werden ebenso geordnet ankommen, da ich meine Bytes ja als Chars übertrage. Vielleicht habe ich auch gerade einen Denkfehler, oder übersehe etwas, da ich in dem Bereich der Programmierung noch recht neu bin. Könnte es sein, dass meine 0-Bytes den Datenstrom terminieren, da ich ja über char-arrays sende? Und wenn ja, welche möglichkeit habe ich, das zu unterbinden? Grüße Cassidy
Cassidy schrieb: >> Hast du dir schon mal die Einzelbytes angesehen? >> Also: Noch ehe du sie zu größeren Einheiten zusammensetzt. > > Also Ich hatte vorher ein Programm, welches Zeichenketten (mit > Trennzeichen) gesendet hat, > dort kamen die Zeichen geordnet an und es konnte alles richtig > interpretiert werden. Zeichenketten sind uninteresant für diesen konkreten Fall. > Deshalb gehe ich davon aus, dass meine Bytes die übertragen werden > ebenso geordnet ankommen, da ich meine Bytes ja als Chars übertrage. Das ist nicht die Frage. Nehmen wir 2 Byte Zahlen. zb die Zahl 23598 die interne Repräsentierung dieser Zahl ist 0x5C2E sie bestehst aus 2 Byte. Aber das bedeute nicht, dass diese Bytes in dieser Reihenfolge auch so im Speicher liegen! AUf einem Motorola Rechner liegen sie so im Speicher: 0x5C 0x2E Auf einem Intel Rechner liegen sie so im Speicher: 0x2E 0x5C Schickst du einfach die Bytes in der Reihenfolge, wie sie im Speicher liegen weg, so erhält sie der Empfänger in einer der beiden Reihenfolgen. Setzt er sie falsch zusammen, dann erhält er eine ganz andere Zahl. Bei 4 Bytes gibt es dann noch mehr Möglichkeiten > Vielleicht habe ich auch gerade einen Denkfehler, oder übersehe etwas, > da ich in dem Bereich der Programmierung noch recht neu bin. Schau dir endlich die Einzelbytes an, die dein Programm erhält. Und zwar als Hex-Zahlen. > Könnte es sein, dass meine 0-Bytes den Datenstrom terminieren, da ich ja > über char-arrays sende? Wie sieht dein Sendecode aus? Du musst strikt zwischen einer reinen binären Übertragung und einer Übertragung in Textform unterscheiden. Das sind andere Funktionsaufrufe. Bei einer reinen binären Übertragung gibt es auch dein 0-Byte welches irgendwas terminieren könnte. Jedes Byte wird übertragen so wie es eben ist. Also was machst du jetzt eigentlich: Übertragung in Textform oder rein binäre Übertragung?
Die Übertragung ist rein binär. Da ich jetzt die Paketgröße berechnet habe und vorgegeben habe, klappt die Übertragung an sich auch. Allerdings stellt sich ein neues Problem. Die Daten kopiere ich per memcpy() in den Buffer. Allerdings werden die Werte "invertiert" gesendet, da ich ein Little-Endian System habe. Gibt es eine Möglichkeit dies zu ändern bzw. eine einheitliche Reihenfolge unabhängig vom System zu haben. Gruß Cassidy
Wenn Du über Ethernet sendest und ich mich nicht ganz irre, dann gibt es dafür ein fixes Byte ordering genannt "Network byte ordering". Soweit ich mich erinnere ist das für Ethernet Big Endian. Little Endian Systeme konvertieren ihre Zahlen dann normalerweise in der Netztzugriffs-API.
Es gibt normalerweise Funktionen htons Host to Network Short htonl Host to Network Long ntohs Network to Host Short ntohl Network to Host Long gemeint ist jeweils: Die Byteorder auf/zu dem auf dem Hostsystem vorliegenden Endianess umdrehen. Ob du sie auf deinem System hast oder nicht (kommt mit den TCP/IP Libararies) musst du abklären. Wenn nicht solltest du dir die entsprechenden Funktionen machen und die dann benutzen anstatt deinen Code an allen möglichen Stellen mit den entsprechenden händischen Konvertierungen zu spicken. Ach ja: Der Sendcode sollte ebenfalls sein Daten mit den entsprechenden Aufrufen in die Standard-Network Byteorder umkonvertieren. Das vermeidet zukünftige Probleme.
Gibt es für AVR eine vorgefertigte Bibliothek dafür oder irgendwo eine Erklärung / Beispiel Implementierung der hton/ntoh Befehle? Grüße Cassidy
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.