Ich empfange hier auf meinem PC ein Packet welches im Payload ein
String (Char array enthält, ein INT, FLOAT, BOOL).
1
54
2
000038002f4040a0200800a020080000
3
6659f9e50100000010026c09a000d300
4
0000000000000000a658f9e500000000
5
16001103d300a801d0000000ffffffff
6
ffffc44f330ffe71ffffffffffff2076
7
7f18fe34deb14200dd3118fe34040154
8
48495320495320412043484152000000
9
000000000000000000000000000000ff
10
ff000000005942010000003ff1010e
Die Daten werden vom Sender und Empfänger 1:1 aufgebaut:
1
typedefstructstruct_message
2
{
3
uint8_theader[95];
4
chara[32];
5
intb;
6
floatc;
7
boold;
8
}struct_message;
9
10
struct_messagemyData;
Damit ich den Anfang erwische, habe ich den Header als Dummy im Struct angelegt (uint8_t header[95];).
Auf der Empgfängerseite kopiere ich mir das mit memcpy in das Struct.
Soweit so gut, die Zeichenkette wird korrekt ausgegeben aber INT, FLOAT,BOOL
nicht. Die Werte scheinen als little Endian abgelegt.
Wie gehe ich damit um?
1
memcpy(&myData,data,sizeof(myData));
2
3
printf("char:%s\n",myData.a);
4
printf("int:%d\n",myData.b);
5
printf("float:%f\n",myData.c);
6
printf("bool:%d\n",myData.d);
Auf der Senderseite werden die Daten wie folgt erzeugt:
1
// Set values to send
2
strcpy(myData.a,"THIS IS A CHAR");
3
myData.b=65535;
4
myData.c=54.25;
5
myData.d=true;
Auf dem Bild im Anhang ist das Char Array markiert, die Nullen nach den Werten entsprechen (char a[32]) den 32 byte. Danach steht der INT
Wert (65535) in Hex FF FF, dann Float (54.25) in Hex 00 00 59 42.
Zum schluss Bool (1) in Hex 01. Alles 4 byte lang.
Du schreibst dir kleine Funktionen, die die Bytes tauschen. POSIX definiert dafür die Funktionen htonl, htons, ntohl und ntohs, die zwischen der Endianess der CPU und Big Endian konvertieren.
Wenn Du bei einem int statt 0xffff empfängerseitig 0xff rausbekommst, klingt das nicht nach einem Endianness-Problem (dann wäre es 0xffff0000), sondern nach einem Alignment-Problem.
Auf der Senderseite werden die Daten wie folgt erzeugt
Ist das in Stein gemeisselt, oder kannst Du aus dem 95-Byte-Header auch einen mit 96 Bytes machen?
Sich nicht an das Alignment zu halten, sorgt je nach Plattform für schlechtere Performance (z.B. x86), weil aus einem Speicherzugriff zwei werden, oder knallt sogar (z.B. m68k).
Die headersize stimmt noch nicht. Der Header ist doch im Espressif IDK definiert.
Das mit der String Ausgabe ist keine sichere Methode den Anfang zu finden, da sind zwei nicht druckbare Zeichen vor die du auch treffen kannst.
Also printf("%x/n", myData[0]);
Und wieso ständig andere Strukturen? Da blickt doch keiner mehr durch.
Falls das hier mal jemand findet, BOOL ist nur EIN Byte und muss
mit einem Pad[3] aufgefüllt werden ... es hatt nur funktioniert weil
es am Ende stand.
Falls das hier mal jemand findet, BOOL ist nur EIN Byte und muss
mit einem Pad[3] aufgefüllt werden ... es hatt nur funktioniert weil
es am Ende stand.
Aber das weiß man doch. Das ist doch schon seit Jahrzehnten so. Spätestens mit der breiten Einführung dem M68000 Mitte der 80er wurde das so gemacht.
"68000 und 68010 können nur byteweise auf ungerade Adressen zugreifen. Diese Exception wird ausgelöst, wenn man dennoch einen Wort- oder Langwort-Zugriff versucht (auch Programmzähler oder Stack-Pointer dürfen keine ungeraden Adressen enthalten)."
https://freemint.github.io/tos.hyp/de/the_system_vectors.html