-         

Ergebnis 1 bis 6 von 6

Thema: #pragma pack(1) Problem

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    523

    #pragma pack(1) Problem

    Anzeige

    Hallo zusammen,
    darf ich das hier fragen, geht ja nicht direkt um ATMEL aber ich denke mal es betrifft alle C-Compiler...
    Laut Hilfe kann ich mit der Direktive #pragma pack(1) dem Compiler mitteilen, daß er meine Daten entsprechend dem Klammerausdruck packen soll.
    Also wen ich pack(1) angebe müsten die Daten meiner Meinung nach Byteweise gepackt werden. Damit keine unnötigen Löcher im Speicher entstehen.
    Wenn ich mir den Mapfile ansehe wird für meine angelegten Variablen aber trotzdem mehr Speicher reserviert als nötig.
    Dazu ein Beispiel:

    #pragma pack(1) /* align the structure to bytes */
    char name[5]
    #pragma pack() /* end of packed structure */

    Für meine Variable "name" werden laut Mapfile 8 Bytes statt 5 reserviert.
    Wenn ich die sizeof Funktion benutze, wird aber korrekterweise 5 zurückgeliefert. Warum reserviert er dann 8 Bytes ? Das wollte ich doch durch pack(1) verhindern.

    Ist das bei anderen Compilern auch so, oder habe ich die pack direktive vielleicht nicht richtig verstanden ?
    Für Informationen wäre ich Euch dankbar.
    Siro
    Geändert von Siro (21.09.2011 um 17:24 Uhr)

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Wesentlich ist, wo der Compiler die nächste Variable hinlegt.
    NACH pack() wird der Compiler die nächste Variable wieder "alignen", d.h. du hast eigentlich von dem ganzen nix.

    Probiere und prüfe dann:
    Code:
    #pragma pack(1)
    char name[5];
    char addr[13];
    char plz[5];
    #pragma pack()
    da darf dann zwischen den Variablen keine Lücke sein.





    Abgesehen von allem Anderen, solltest du das so machen: (wenn der Compiler mitspielt)
    Code:
    #pragma pack(push)
    #pragma pack(1)
    ------
    #pragma pack(pop)
    Der Sinn liegt auf der Hand (bei verschachtelten ".H" files
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    523
    Hallo PicNick,
    erst einmal Danke für deine Antwort,

    ich hab das grad mal ausprobiert und dachte ich träume. Nach welchen Kriterien legt denn mein Compiler die Variablen an ?????
    Schau Dir mal die Adressen laut Mapfile an, da fällt man doch vom Glauben ab.

    #pragma pack(1)
    char name[5]; /* Adresse laut Mapfile: 6A5C 8 Bytes reserviert, sizeof liefert 5 */
    char addr[13]; /* Adresse
    laut Mapfile: 6A24 16 Bytes reserviert, sizeof liefert 13 */
    char plz[5]; /* Adresse
    laut Mapfile: 6A64 8 Bytes reserviert, sizeof liefert 5 */
    #pragma pack()

    Sizeof liefert aber immer die richtige Größe.

    Hab dann mal folgendes probiert:

    name[1] Compiler reserviert 1 Byte
    name[2] Compiler reserviert 2 Byte
    name[3] Compiler reserviert 4 Byte
    name[4] Compiler reserviert 4 Byte
    name[5] Compiler reserviert 8 Byte
    name[6] Compiler reserviert 8 Byte
    name[7] Compiler reserviert 8 Byte
    name[8] Compiler reserviert 8 Byte
    name[9] Compiler reserviert 12 Byte
    name[12] Compiler reserviert 12 Byte
    name[13] Compiler reserviert 16 Byte

    Meiner Meinung nach funktioniert PACK überhaupt nicht. Hab aber grad gelesen, daß das pack NUR nur in Verbindung mit struct funktioniert. Kann das sein ???
    Mit dem (push) und (pop) beim pack scheint mir eine gute Sache zu sein, das unterstützt mein IAR Compiler auch.
    Ich kann das wohl auch so schreiben, wenn ich das richtig verstanden habe.
    #pragma pack(push,1) und am Ende dann #pragma(pop) Deine Variante akzeptiert er aber auch.

    Nun aber ab ins Wochenende,
    Siro

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Naja, ich verwend' es nur bei Daten-strukturen, denn da müssen die Daten ja geschlossen u. lückenlos definiert sein.

    Das mit dem "nur mit struct" könnt' schon sein, denn ausserhalb von struct legt der Compiler die Variablen offenbar dort an, wo es ihm gerade einfällt. (alphabetisch?). Ich weiss jetzt garnicht, ob es einen Anspruch darauf gibt, dass der Kompiler die Variablen in der Folge anlegt, wie die angegeben werden ?
    Das ist von akademischen Interesse, daher würd ich an deiner stelle, damit was weitergeht, eben eine struct konstruieren, wo die Variablen drin stehen, die ich beieinander haben möchte. da hat der Kompiler dann keine Ausflüchte.

    Dass "sizeof" richtige Werte liefert, wundert mich nicht, denn, ich schwör's, das wär schon aufgefallen.

    Aber wer checkt schon, an welcher Adresse seine Variablen liegen, und ob es dazwischen Lücken gibt.
    (Natürlich µC Programmierer, denn die müssen jedes Byte zweimal umdrehen, bevor sie es belegen )
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    523
    Im struct scheint es richtig zu funktionieren. Er belegt jedoch trotzem teilweise mehr Bytes. Er scheint die Strukturen auf 4 Bytes zu "Alignen" vermutlich wegen der 32 Bit Struktur des verwendeten Prozessor.
    Und ja, ich drehe jedes Byte immer 2 mal um, oder dreimal, bevor ich es ver(sch)wende. Früher zumindest bei den 8 Bittern, jetzt eigentlich weniger der LPC1768 hat ja reichlich RAM.

    Hab es nun so probiert:

    #pragma pack(push,1)
    struct
    {
    char name[5];
    char addr[13];
    char plz[5];
    } t;
    #pragma pack(pop)

    Das kann aber unter Umständen zu ineffektiven Code führen, wenn man auf ungrade Adressen innerhalb der Struktur zugreift. Wenn man also genügend Speicher hat, sollte man lieber dem Compiler die Arbeit überlassen,
    und pack ganz weglassen, denke ich.
    Siro

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Felix G
    Registriert seit
    29.06.2004
    Ort
    49°32'N 8°40'E
    Alter
    34
    Beiträge
    1.780
    Im struct scheint es richtig zu funktionieren. Er belegt jedoch trotzem teilweise mehr Bytes. Er scheint die Strukturen auf 4 Bytes zu "Alignen" vermutlich wegen der 32 Bit Struktur des verwendeten Prozessor.
    Ja, das ist sehr oft so. Ich z.B. habe beruflich mit Blackfin DSPs von Analog Devices zu tun, und wenn man da versehentlich mal auf eine nicht durch 4 teilbare Addresse zugreift, stürzt der DSP sofort mit einer Exception ab.

    Bei #pragma pack geht es übrigens in erster Linie nicht darum Speicher zu sparen, sondern darum ein ganz bestimmtes vorgegebenes Speicherlayout zu erzielen. Das kann insbesondere bei der Kommunikation wichtig sein. Ein Beispiel wäre etwa ein Ethernet Frame, bei dem ja ganz genau vorgegeben ist wie es aussehen muss, und da wäre es extrem kontraproduktiv, wenn so eine Struktur im Speicher irgendwelche Lücken hätte.
    So viele Treppen und so wenig Zeit!

Ähnliche Themen

  1. Antworten: 15
    Letzter Beitrag: 15.03.2011, 18:44
  2. Akku-Pack mit Balancieren selber bauen
    Von Hellmut im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 01.03.2010, 12:39
  3. Problem mit Atmega644P Erkennung (Bascom-Versions-Problem)
    Von Rohbotiker im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 11.08.2008, 19:52
  4. Akku-Pack im Eigenbau
    Von zennehoy im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 13.11.2006, 18:02
  5. mH Akku Pack analog und sicher laden
    Von Luke17 im Forum Elektronik
    Antworten: 7
    Letzter Beitrag: 24.11.2005, 20:16

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •