-         

Ergebnis 1 bis 5 von 5

Thema: Adresse eines struct-Elements ermitteln???

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    18.11.2004
    Beiträge
    33

    Adresse eines struct-Elements ermitteln???

    Anzeige

    Hallo,

    ich habe eine größere struct (ca. 200Bytes), die in einem extern angeschlossenen RAM gespeichert wird (viele Kopien davon). Das RAM wird nicht über die Hardwaremäßig beim ATMega128 vorgesehenen Pins angesprochen, sondern über eigene Routinen, ich habe sie dram_read_rc und dram_write_rc genannt. Es handelt sich um ein DRAM, das ich von einem alten 30poligen Modul 'gerippt' habe.

    Da die Struktur recht groß ist, und einige der Werte deutlich öfter gelesen werden müssen als andere, lohnt es nicht die ganze Struktur zu laden (RAM + Laufzeit des Codes).
    Wenn ich nun aus der Struktur aber nur ein Element lesen will (z.B. einen uint16_t), dann muß man ja wissen, wo vom Beginn der Struktur im Speicher an gerechnet dieses Element gespeichert ist. Diesen Wert hartzucoden finde ich, scheidet aus, weil mit Optimierung etc. oder Veränderungen an der Struktur artet das schnell in Arbeit aus. Ist auch ne tolle Fehlerquelle bei ca. 70kByte Source-Code.

    Wenn man die Struktur im RAM anlegen kann ist es ja natürlich keine Herausforderung (die struct ts ist _natürlich_ nicht die richtige Struktur). Ich habe versucht, dass mal mit diesem Programm deutlich zu machen.
    Code:
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    struct ts {
    	uint16_t a;
    	uint16_t b;
    	uint8_t c;
    	uint16_t d;
    };
    
    int main (void)
    {
    	struct ts x;
    	int the_offset;
    
    	// calculate the offset (cast required as data types are different!)
    	the_offset = ((char *) &x.d) - ((char *) &x);
    
    	printf("offset %d required to access structure element 'd' directly\n", the_offset);
    }
    Aber wie mache ich dasselbe, ohne die Struktur anzulegen??? Ich möchte ja eben nur die Adresse vom Element d innerhalb der Struktur.

    Nutze avr-gcc 4.1.2.

    TIA für alle Hinweise
    - cl

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    18.11.2004
    Beiträge
    33
    für alle die es interessiert, hier noch ein Bild der Platine
    Die Platine habe ich mit dem Conrad-Laminator laminiert, aber das ist ja eigentlich OT.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken erg1.jpg  

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Du kannst ja über die Adressen gehen.

    Code:
    void foo (void)
    {
       foo_t * bar;
       int offset = (int) & bar->x - (int) bar;
       ...  
    }
    Aber sowas brauchst du nicht. Du kannst ja die ganze Struktur kopieren, also ab ihrem Anfang (als unsigned char*) einfach die Anzahl der Bytes (sizeof...). Falls du nicht die gesamze STruktur willst, dann organisierst du sie eben in Teil/Unterstrukturen.
    Disclaimer: none. Sue me.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    18.11.2004
    Beiträge
    33
    Tja, man sieht man kommt doch nicht auf alles. Danke für den Tipp. Jetzt sieht meine "App" so aus:

    Code:
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    struct ts {
    	uint16_t a;
    	uint16_t b;
    	uint8_t c;
    	uint16_t d;
    };
    
    int main (void)
    {
    	struct ts *p;
    	int the_offset;
    
    	// calculate the offset (cast required as data types are different!)
    	the_offset = ((char *) &p->d) - ((char *) p);
    
    	printf("offset %d required to access structure element 'd' directly\n", the_offset);
    }
    BTW: Du castest wie ganz selbstverständlich die Pointer auf int. Ich kenne den C-Standard nicht genau genug, aber ist garantiert, dass int die selbe Größe wie int hat??? Auf AVR, 8051 und x86 ja, aber sonst?

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2005
    Ort
    Kaiserslautern
    Beiträge
    794
    Nein, eigentlich nicht.

    Es gibt ja 8-Bit-Systeme (die von die angesprochenen) und 32- oder mittlerweile auch 64-Bit-Systeme, auf denen ein Int entsprechend länger ist. Daher sollte man auch lieber uint8_t benutzen.

    Gruß, CowZ

Berechtigungen

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