www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik IAR (MSP430): ByteArray -> Struktur hat Probs mit Integern?


Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich hab' da ein Problem mit der IAR Embedded Workbench for MSP430
Kickstart Version (Was für ein Name...). Ich hab' ein ByteArray und
möchte dessen Inhalt einer Struktur zuweisen. Nun scheint es aber so,
als hätte der Compiler Probleme mit 16 Bit Integern in der Struktur.
Die Struktur sieht so aus:
struct BootSec
{
  U08 BS_jmpBoot[3];      //3 bytes
  U08 BS_OEMName[8];      //8 bytes
  U16 BPB_BytesPerSec;   //2 bytes
  U08  BPB_SecPerClus;     //1 byte
  U08  BPB_RsvdSecCntL;    //2 bytes
    U08  BPB_RsvdSecCntH;
  U08  BPB_NumFATs;        //1 byte
  U08  BPB_RootEntCntL;    //2 bytes
    U08  BPB_RootEntCntH;
  U08  BPB_TotSec16L;      //2 bytes
    U08  BPB_TotSec16H;
  U08  BPB_Media;          //1 byte
  U08  BPB_FATSz16L;       //2 bytes
    U08  BPB_FATSz16H;
  U16  BPB_SecPerTrk;      //2 bytes
  U16  BPB_NumHeads;       //2 bytes
  U32  BPB_HiddSec;        //4 bytes
  U32  BPB_TotSec32;       //4 bytes
};

Einige Werte hab' ich bereits testweise durch zwei 8 Bit Werte
ersetzt, damit funktioniert's. Sobald ich aber an einen 16 Bit Wert
komme, scheint es so, als würde der Compiler die Offsets verdrehen.
Mein ByteArray hat z.B. folgenden Inhalt (Ist nur der Anfang davon):
eb 3c 90 4d 53 44 4f 53 35 2e 30 00 02 04 04 00
oder als Zeichen
ë<MSDOS5.0......
Das ist korrekt so. Weise ich dieses Array nun der Struktur zu
    struct BootSec *BootSector = (struct BootSec *)Buffer;
so habe ich in BS_jmpBoot sowie BS_OEMName die richtigen Werte
(0xEB3C90 bzw. "MSDOS5.0"). Aber im ersten 16 Bit Wert
(BPB_BytesPerSec) einen Wert von 1026 bzw. 0x0402 anstatt 512 (0x0200).
Der lässt da also aus irgendeinem mir unerklärlichen Grund das Nullbyte
nach 0x30 aus. Aber WIESO? Ich hab's auch schon mit einem DummyByte
vor BPB_BytesPerSec versucht. Das ist dann auch wirklich 0x00. Der
folgende Int beinhaltet dann aber nicht etwa 0x0404 sonder wieder
0x0402, was ja auch stimmt. Ich versteh's nimmer. Woran kann es
liegen, dass der mir da die Werte irgendwie
verschiebt/verdreht/verändert? Ersetze ich alle 16 Bit Ints durch Char
(8 Bit) so funktioniert's tadellos! Aber das kann's ja wohl nicht
sein...

Langsam beginne ich IAR zu hassen...

Ich hoffe jemand kann mir helfen und bedanke mich schonmal für
Antworten.
Grüsse
Philipp

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hiho,
meines Wissens sind auch beim IAR/MSP430 Wort-Zugriffe auf ungerade
Adressen nicht erlaubt. Deshalb füllt der Compiler Deine Struktur nach
U08 BS_OEMName[8] mit einem Dummy-Byte auf, damit das naechste
16-Bit-Wort auf einer geraden Adresse liegt (Alignment).
Wenn Du also Byte-weise in die Struktur reinschreibst, aber dann über
die Struktur-Member selbst darauf zugreifst, greift er da halt "eins
daneben" durch das Dummy-Byte.
Wenn das Array unveränderlich ist und Deine Struktur auch, musst Du
wohl oder übel eine Konvertierungsfunktion schreiben, die Stück für
Stück Dein Array in die Struktur rueberhebelt. Mit dem einfachen
Abbilden ist da leider nix. Zumindest ist mir keine IAR-Option bekannt.

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach du sch***... Irgendwie hab' ich's doch noch fast befürchtet...
Naja, muss ich wohl doch mit meinen Byte-Werten vorlieb nehmen. Wär'
aber schon nicht schlecht, wenn der Compiler dann wenigstens eine
Warnung ausspucken würde >:(

Aber danke dir für die Antwort, dann muss ich wohl nimmer nach einem
Fehler meinerseits suchen, geht halt einfach nicht.

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oerks,
wer lesen kann, ist klar im Vorteil, hast ja das Dummy-Byte schon
probiert... muss ich nochmal neu ueberdenken...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wer lesen kann, ist klar im Vorteil, hast ja das Dummy-Byte schon
> probiert... muss ich nochmal neu ueberdenken...

Deine Analyse war schon richtig.
Der Compiler fügt ein padding Byte in die Struktur ein.
Ist also quasi so als ob er geschrieben hätte:

struct BootSec{
  U08 BS_jmpBoot[3];      //3 bytes
  U08 BS_OEMName[8];      //8 bytes
  U08 Dummy_Padding_Byte;
  U16 BPB_BytesPerSec;   //2 bytes
  ...

Ob er jetzt explizit dieses Byte einfügt, oder ob der Compiler
das macht, macht keinen Unterschied für den Wert von BPB_BytesPerSec.

Der einzige Unterschied ist:
Das explizite Padding Byte kann man rausnehmen woraufhin der Compiler
stillschweigend sein eigenes rein macht.

@Phillip
Durchsuche die Compiler Doku, wie du das Padding entweder abschalten
oder auf 1 setzen kannst. Bei vielen Compilen geht das mit einem
#pragma
Geht das nichts, dann bleibt dir nur der Weg über Einzelzuweisungen
wie szimmi bereits gesagt hat.

Und: Der Compiler braucht nicht davor warnen. Ja er könnte es
nicht mal tun, denn woher soll er den wissen, dass in dem Arry
das Padding Byte nicht enthalten ist?
Ìm Übrigen: In dem Moment wo du Pointer auf andere Datentypen
zurecht castest, bist du sowieso alleine. Es obliegt dann deiner
Verantwortung ob da das Richtige raus kommt oder nicht. Offiziell
ist das 'undefined behaviour': Alles Mögliche kann passieren.

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@szimmi:

Nur keine Angst, du  hast das Problem richtig erkannt und mir zur
Lösung verholfen :) Thx

@Karl:

Danke für den Hinweis, werde mal schauen ob ich die entsprechende
Anweisung finde. Weisst du zufälligerweise, wonach ich da suchen
sollte? Die Hilfe ist relativ gross und doch findet man nicht recht was
man sucht...

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, hab's gefunden. Es ist
#pragma pack(1):
#pragma pack(1) 
 
struct FirstPacked 
{ 
  char alpha; 
  short beta; 
}; 
 
#pragma pack()

Allerdings steht da, dass es grösseren und langsameren Code erzeugt...
Ich lass' es mal für's Erste, möglicherweise brauche ich das noch
woanders.
Aber danke euch beiden!

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.