Forum: Compiler & IDEs STM32: struct-Pointer auf Array -> falsche Werte


von Markus R. (maggus)


Lesenswert?

Hallo zusammen,
ich habe folgendes Array und Struct:
1
unsigned char array[10] = {1,2,3,4,5,6,7,8,9,0};
2
struct strct {
3
    unsigned char one[2];
4
    unsigned char two[3];
5
    unsigned int three;
6
};
Das ist global definiert.

In Main erstelle ich einen struct pointer
1
struct strct *test;

und lasse diesen Pointer auf den Anfang des Arrays zeigen:
1
test = (struct strct*)&array;

Ich erwarte mir dann folgendes:
one = [1,2]
two = [3,4,5]
three = 1543   (6<<8 | 7)

Im debugger bekomme ich für one und two auch die gewünschten Werte, 
three hat aber den wert 9.
Auf den AVRs hat alles wie gewünscht funktioniert, auf dem STM32 
(Discovery-Board) aber nicht.

Wie komme ich also möglichst einfach zum gewünschten Ergebnis?

von Noname (Gast)


Lesenswert?

Der STM hat eine Wortbreite von 32Bit kann aber auch gut mit 16Bit 
umgehen.

Du siehst das die unerwartete 9 genau nach 8 unsigned char auftritt.

Compiler (welchen hast Du denn?) neigen dazu, structs möglichst so 
aufzuteilen, das die Wortbreite auf Befehle passt die eine schnelle 
Verarbeitung ohne Schieben erlauben.

Von einer anderen Warte aus, ist es bei structs implementierungsabhängig 
wie die Mitglieder angeordnet sind. Es gibt keine Garantie, das sie im 
Speicher unmittelbar aufeinander folgen.

Da sich aber diese Tricks eingebürgert haben bzw. irgendwann mal von den 
Programmierern gefordert wurde, das sie möglich sien sollen, wurden 
verschiedene sogenannte "Pragmas" eingeführt die aber nicht zum Standard 
von C gehören.

In Deinem Fall solltest Du schauen, ob es ein pragma "Pack" gibt und das 
unmittelbar vor die Strukturdeklaration legen. Dann klappts.

von Markus R. (maggus)


Lesenswert?

Hallo, danke für die Antwort.
Ich benutze den GCC. Das mit dem pragma pack sieht mir aber auch recht 
kompliziert aus... werde mich da noch etwas genauer einlesen.
Ansonsten hilft wohl nur ein Zwischenschritt über eine neue 
int-variable, in der die zwei unsigend-chars aus dem array 
zusammengefügt werden.

von Noname (Gast)


Lesenswert?

>Das mit dem pragma pack sieht mir aber auch recht kompliziert aus

Das ist im Gegenteil recht einfach.
Eben nur "#pragma pack" vor die Strukturdeklaration setzen. Dann ordnet 
der Compiler die Strukturmitglieder direkt aufeinanderfolgend an und 
erzeugt Code der das berücksichtigt.

Lies Dir einfach mal die Doku durch.

von Markus R. (maggus)


Lesenswert?

Danke, jetzt funktionierts! Man sollte auch beachten, dass ein int beim 
STM32 32 Bit lang ist und nicht 16 wie auf den AVRs....

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Begleitende Literatur findest Du hier:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/index.html

Compiler neigen nicht zu diesem Verhalten, sie müssen die Regeln der 
Architektur befolgen.

Gruß
Marcus

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
Noch kein Account? Hier anmelden.