www.mikrocontroller.net

Forum: Compiler & IDEs Pointer auf Struct -> align problem


Autor: Matthias Hüsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich stolpere gerade zum x-ten mal über das Problem mit
den aligned Speicherzugriffen vom ARM7 und deren Behandlung in GCC.
Ich versuche mal zu erklären was genau passiert:

Es gibt einen Buffer von 128 Bytes länge in den
ein Gerät von ausserhalb seine Datenstrukturen ablegt.
Auf das "wieviel aufeinmal" und wo habe ich dabei keinen Einfluss.
Es handelt sich dabei um eine wild gewürfelte linked-list, deren
Elemente wahlfrei verschieden lang und typisiert sind.
Diese Datenstrukturen will ich nun auswerten.
Der Einfachheit halber natürlich über entsprechende structs.
Die Strukturen sind jeweils aus 8 und 16bit Werten zusammengsetzt
und sind in sich durchaus aligned. Allerdings wandern die auf Bytes
ausgerichtet in diesen Puffer.
Der erste Block beginnt auf buffer[0] , der zweite beispielsweise
auf buffer[9].
Wenn ich aber nun schreibe:
char buffer[128]; // per DMA gefüllt

strukturname *pointer;
pointer = (strukturname*)&buffer[9];

geht das grandios in die Hose und er greift mit dem ersten
structure member auf Buffer[8] zu.
Und nicht wie erwartet etwa buffer[9].
Das er das mit einem WORD nicht können kann habe ich schon 
herausgefunden. In diesem Falle besteht die Struktur aber ausschließlich 
aus Bytes, was er Architekturbedingt können müsste.
Die Struktur selbst ist als typedef struct mit __attribute__((packed)) 
definiert. #pragma pack() habe ich auch schon versucht.

Wie überrede ich denn nun den Compiler dazu, dass er den Pointer
bitte nicht aligned setzten soll, sondern dahin wo ich ihn gerne hätte?

Tausend Dank schonmal!
Grüße,
  Matthias

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Hüsch wrote:

>
> char buffer[128]; // per DMA gefüllt
> 
> strukturname *pointer;
> pointer = (strukturname*)&buffer[9];
> 
>
> geht das grandios in die Hose und er greift mit dem ersten
> structure member auf Buffer[8] zu.
> Und nicht wie erwartet etwa buffer[9].

Das sieht mir nach Compilerfehler aus... Wenn die Struktur nicht aligned 
ist (bzw. gcc nix über das Alignment weiß), dann sollte er 
8-Bit-Zugriffe machen, auch wenn das sehr ineffizienten Code gibt.

Evtl. ist eine Option aktiviert, die solche Transformationen als 
Optimierung nach sich zieht?

Die gesetzten Optionen sieht du mit -save-temps -fverbose-asm im 
erzeugten .s.

Fixen könntest das, indem aus dem Puffer rauskopierst in eine Union aus 
der Struktur und einem char-Puffer, wobei die Union aligned ist, etwa 
__attribute__((aligned)) falls es das für ARM gibt.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Das sieht mir nach Compilerfehler aus...

Nö. Das ist das ganz normale Verhalten.

> Wenn die Struktur nicht aligned ist (bzw. gcc nix über das Alignment
> weiß),

Das weiß er eigentlich nie. Er muß darauf vertrauen, daß das Alignment 
korrekt ist.

> dann sollte er 8-Bit-Zugriffe machen, auch wenn das sehr
> ineffizienten Code gibt.

Wenn man die haben will, muß man sie explizit hinschreiben.

> Fixen könntest das, indem aus dem Puffer rauskopierst in eine Union
> aus der Struktur und einem char-Puffer, wobei die Union aligned ist,
> etwa __attribute__((aligned)) falls es das für ARM gibt.

Wozu sollte man das brauchen? Korrektes Alignment wird automatisch 
eingehalten, wenn man es nicht explizit ausschaltet.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was ist dann das Problem??

Rolf Magnus wrote:
>>Das sieht mir nach Compilerfehler aus...
>
> Nö. Das ist das ganz normale Verhalten.

Ok, dann steht's irgendwo im ABI.

Autor: Nischu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß, das ist wenig effizient, aber mach doch im Zweifel:
char align_buf[128]
memcpy(align_buf, &buffer[9], ...);
strukturname *pointer;
...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.