Endianess Umwandlung notwendig?

Gast #1726945
Lesenswert?

Hallo zusammen,

ich hätte mal eine Frage. Ich arbeite mit einem Cortex M3, dieser 
arbeitet im little endian. Jetzt bekomme ich aber externe Daten im Big 
endian in den Speicher gelegt. Wenn ich jetzt mit diesen Daten arbeiten 
möchte, muss ich die zuerst konvertieren, oder? Weil ansonsten 
interpretiert der Cortex einen falschen Wert. Es handelt sich um 16Bit 
Werte. So wie ich es verstehe muss ich quasi "nur" das erste mit dem 
zweiten Byte vertauschen um die Daten in den little endian zu bringen.

Also:
Der Wert 43707 wird im big endian gespeichert, also 0xAABB. Wenn ich 
diesen Wert jetzt vom Cortex interpretieren lasse würde der 0xBBAA also 
48042 lesen.

Ist dem so? Gibt es "standard" Funktionen dafür bzw. irgendwelche 
performanten implementierungen?

Wahrscheinlich lachen sich die meisten über die Frage kaputt... Deshalb 
möge man meine Unkenntnis entschuldigen.
#1727004
Lesenswert?

Du musst die Reihenfolge der Bytes umdrehen, vollkommen richtig. Die 
Frage ist, bekommst du auch mal 4 Byte Daten? Wenn ja wirds etwas 
komplexer, an sonsten einfach Bytes tauschen.

Da gibts verschiedene Lösungswege. Du könntest den int16_t mit 0xff 
"verUNDen" und in ein int8_t packen, den int16_t acht mal nach rechts 
schieben und dann den int8_t in den oberen Teil deines Wertes packen.

Was auch gehen würde, wäre ein union.
1
union byteToWord
2
{
3
 int8_t byte[2];
4
 int16_t word;
5
};

Oder so ;-) Bin grad nicht ganz Sattelfest mit unions.

Dann hättest du die Möglichkeit davon zwei zu erstellen und könntest mit
1
union2.word = DeinWertAusDemSpeicher;
2
union1.byte[1] = union2.byte[2];
3
union1.byte[2] = union2.byte[1];
4
DeineVariableZurVerarbeitung = union1.word;

Sicherlich gibt es noch viel viel bessere Varianten als meine hier ;)
Gast #1729954
Lesenswert?

Vielen herzlichen Dank an euch alle!

Ich werde die Varianten mal testen und schauen was für meinen Geschmack 
das beste ist. Aber ich denke es wird auf die REV16 Variante raus 
laufen. Damit ist der Code zwar nicht mehr CPU und Compiler independent, 
aber wenn man auf gute Performance aus ist, gestalltet sich das ohnehin 
schwer.

Nochmal Danke an alle. :o)
Gast #1729964
Lesenswert?

Sorry noch ne Frage. Ich habe mal geschaut wie die REV16 im Thumb2 
Instruction Set (Cortex-m3) implementiert ist.

Bytes in both halfwords
REV16 Rd, Rm
Rd[15:8] := Rm[7:0],
Rd[7:0] := Rm[15:8],
Rd[31:24] := Rm[23:16],
Rd[23:16] := Rm[31:24]

Der tauscht hier quasi alle 4 Byte eines 32 Bit Registers. Das macht 
insofern Sinn, also dass der Cortex 32Bit Register verwendet. Wieso 
heißt dann aber der Befehel REV16? Das Ergebnis stimmt natürlich wenn 
ich in beide Register 16 Bit Werte lade, allerdings werden hier 2 
Befehle ausgeführt, die man eigentlich nicht bräuchte. Oder bezieht sich 
das "16" hier allgemein auf die Vertauschung der 2 Bytes in den beiden 
16 bit Worten?

Nun gut, ich teste mal rum... ;)
#1729974
Lesenswert?

Le_Q schrieb:

> ich in beide Register 16 Bit Werte lade, allerdings werden hier 2
> Befehle ausgeführt, die man eigentlich nicht bräuchte.

Nö. Er macht zwar mehr als du für das Vertauschen der beiden unteren 
Bytes benötigst, aber das sind nicht 4 Befehle, sondern ist eine einzige 
Operation, die im Handbuch als 4 Operationen dargestellt wird.

In der gleichen Weise könntest du Shift-Operationen auch als
  d[31] = s[30]
  ...
  d[1] = s[0]
  d[0] = 0
darstellen und es wären dennoch keine 32 Befehle.

> das "16" hier allgemein auf die Vertauschung der 2 Bytes in den beiden
> 16 bit Worten?

Damit wird signalisiert, dass die Bytes innerhalb der 16-Bit Hälften 
vertauscht werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren