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.
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 ;)
Sven H. schrieb: > Sicherlich gibt es noch viel viel bessere Varianten als meine hier ;) Eine Zwischenvariable wäre nicht schlecht ;-) Oliver
GCC kennt ein __builtin_bswap32 für diesen Zweck http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Other-Builtins.html#Other-Builtins
Le_Q schrieb: > Gibt es "standard" Funktionen dafür bzw. irgendwelche performanten > implementierungen? Assembler: REV16
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)
> GCC kennt ein __builtin_bswap32 für diesen Zweck
Interessanterweise gibt es da eins für 32 und eins für 64 Bit, aber
anscheinend keins für 16 Bit.
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... ;)
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.
Ah ich verstehe. Ich dachte, dass REV16 ein Pseudo-OpCode ist, der in Wirklichkeit aus den 4 einzelnen besteht. Danke für die Aufklärung.
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.