liegt mein Array "verkehrt herum" im Ram?

Gast #3367181
Lesenswert?

Hey Zusammen :)

Es ist spät, ich habe mir lang den Kopf zerbrochen und nun hoffe ich von 
Euch auf nen kleinen Tip :)

Ich habe ein Array data[8]. Dies ist gefüllt mit ( 0x01, 0x00, 0x0, 
0x50, 0x00, 0x00, 0x00, 0x00).
data[0] ist also 0x01, data[3] ist 0x50.

In einem Fall stellt data[0...3] den Inhalt eines uint32_t dar.

Mein Gedanke: Die Daten liegen ja im RAM hintereinander, sollte doch ein 
leichtes sein.

uint32_t test;
test = data[0];  ->> warn versucht, klappt natürlich nicht
test = (uint32_t){data[0]}; ->> auch nicht

uint32_t* ptr = data[0];
test = *prt   --> test wird mit (0x75, 0x01, 0x00, 0x00) geladen.

uint32_t* ptr = data[1];
test = *prt   --> test wird endlich mit (0x01, 0x00, 0x00, 0x50) 
geladen. Dann resetet der µC

uint32_t* ptr = &data[0];
test = *prt   --> test ist nun (0x50, 0x00, 0x00, 0x01) und ab diesem 
Moment bin ich total durcheinander... evt ist es auch einfach zu spät...

Aber evt habt Ihr nen Rat/Vorschlag für mich?

Danke und Gruß
Danny
Moderator #3367189
Lesenswert?

Integers werden auf dem von dir benutzten Prozessor little-endian, d.h.
beginnend mit dem niederwertigsten Byte im Speicher abgelegt. 0x01 wird
somit als das niedrigstwertige und 0x50 als das höchstwertige Byte
betrachtet, so das die gelesene uint32_t-Wert 0x50000001 ist.
Gast #3367192
Lesenswert?

Vielen Dank für die schnellen Antworten!

Ich bin grad völlig verblüfft, bislang war für mich "big-endian" die 
einzig denkbarer Art und ich bin jahrelang damit in kein Problem 
gelaufen...

Das muss ich mir ausgeruht morgen früh nochmal selbst verdeutlichen :)
(Firma: Schweigstill IT) Persönliche Seite #3367412
Lesenswert?

Oliver S. schrieb:
> Was für Exoten-Prozessoren hast du denn jahrelang benutzt?

Sehr gebräuchliche Prozessoren mit Big Endian sind:

- 68000
- PowerPC
- SPARC

Viele ARM-Prozessorkerne lassen sich wahlweise als Big oder Little 
Endian konfigurieren, teilweise per externem Endianess-Pin. Beispiel 
Alcatel MTC-20285. Auch StrongARM- und Xscale-Prozessoren werden oft in 
Big Endian verwendet, gerade in Netzwerkkomponenten, da die Header von 
TCP/IP-Paketen auch in Big Endian (sog. Network Byte Order) spezifiziert 
sind.

Bei einigen MIPS-Prozessoren kann die Endianess sogar für jeden Prozess 
separat eingestellt werden, z.B. Toshiba TX39.

Nachtrag: Auch aktuelle ARM-Kerne beherrschen beide Betriebsarten, 
exemplarisch für den Cortex-A9:
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0407e/BABCIEHF.html
#3367578
Lesenswert?

DirkB schrieb:
1
> uint32_t test;
2
> test = *(uint32_t*)(&data[0]);

Weil noch keiner darauf eingegangen ist: DirkB hat hier völlig recht. 
Ganz unabhängig davon ob der TE einen kleinen oder großen Indianer 
programmiert, hat er auch Daten und Adressen durcheinandergewürfelt.

So hat er z.B. hier:

Danny schrieb:
> uint32_t* ptr = data[1];
> test = *prt

den Inhalt von data[1] (also vermutlich ein uint_8t) als Adresse 
eines uint32_t interpretiert. Und das geht in jedem Fall in die Hose. 
Wenn es das erwartete Ergebnis geliefert hat, dann auf jeden Fall nur 
zufällig.


XL
Gast #3367599
Lesenswert?

Mensch, da habe ich ja etwas losgetreten :)

Obwohl ich mir fest vornahm den Ziel-µC zu nennen, hab' ich's doch 
vergessen... Es ging/geht um einen Atmel AVR (Mega8 / Mega 128)...

Und tatsächlich hatte ich diese Probleme in den ganzen letzten Jahren 
nicht, aber meiner Recherche nach kann das auch gut sein, denn Probleme 
treten ja nur auf wenn Daten zwischen zwei Unterschiedlichen Systemen 
getauscht werden.
Auch dieses Mal wäre ich sicher nicht darüber gefallen, wenn ich mich 
nicht zu Testzwecken einmal als "fremdes System (big-endian-denkend)" 
eingemischt hätte :)


einmal noch für mein Verständnis Dirk's Lösung:

uint32_t test;
test = *(uint32_t*)(&data[0]);

mit (uint32_t*)(&data[0]); lade ich einen pointer auf einen uint32_t mit 
der Startadresse von data[0]. Durch den * vor dem ganzen wird der 
Ausdruck zum 32 Bit breiten Inhalt, auf den der Pointer zeigt. Um das 
big/little-endian muss ich mich dann zu Fuß kümmern.
Hab ich das soweit richtig verstanden?

Danke nochmal
Gast #3367692
Lesenswert?

Danny schrieb:
> in einer Zeile, richtig?

Ja.
Mehr wollte ich auch nicht machen.

Damit änderst du noch nichts an der Bytereihenfolge.

Wenn du zwischen verschiedenen Systemen die Werte austauschen willst, 
solltest du dir mal die Funktionen wie htonl oder ntohl ansehen.
Gast #3367821
Lesenswert?

@Dirk:  danke für den Tip, da werde ich mal vor dem schlafen gehen nach 
schauen :)

für den Moment habe ich mir geholfen, indem ich nicht die Bytes selbst 
"errechnet" habe sondern per (uint32_t[]){ 200 } eingefügt...

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