Forum: Compiler & IDEs Definition von Variablen


von Thomas P. (topla)


Lesenswert?

Hallo,

es tauchen nach Beitrag "Deklaration von external memory" die 
nächsten Fragen auf:
1. Im zu migrierenden asm-Projekt habe ich 2-Byte-Variablen in einem 
Array verwendet. Das niederwertige Byte enthält rechtsbündig den 7 Bit 
langen high-Teil einer Adresse, das höherwertige Byte enthält 
rechtsbündig eine 3 Bit lange Subadresse dieser Adresse. Die beiden 
Adressteile werden nicht zusammengesetzt und bei einer Übertragung 
getrennt behandelt. Die übrig bleibenden Bits sind mit anderen 
Informationen zu dieser Adresse gefüllt. Jetzt habe ich ein Array 
definiert mit uint16_t[256][8]. Bei Zugriff werden die Daten in 2 
uint8_t zerlegt und weiter behandelt.
Frage:
Macht das so Sinn oder sollte man das ganz anders angehen?

2. Da der EEPROM im Controller vorne und hinten nicht ausreicht, habe 
ich einen externen EEPROM über SPI angebunden.
Frage:
Wie bildet man den Aufbau dieses Speichers ab?
Es gibt ja keinen direkten Zugriff auf dieses Teil Hardware, den der 
Compiler umsetzen muss (kann). Ich bin noch nicht so weit, aber es wäre 
ja bestimmt ganz nett, wenn man mit den eigenen SPI-Routinen für die 
Ermittlung der Adressen im externen EEPROM auf ein array[a][b] 
EXT_EEPROM zugreifen könnte.

Danke für alle Hinweise.

Thomas

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas P. schrieb:
> Jetzt habe ich ein Array definiert mit uint16_t[256][8].

Den Zusammenhang zwischen dem von Dir beschriebenen in Assembler 
genutzten Array aus "zwei-byte-Variablen" und dem zweidimensionalen 
Array hier kann ich nicht so recht erkennen.

Ansonsten kannst Du in C natürlich genau die Art von Bitschiebereien 
veranstalten, die Du in Assembler auch betreibst.

Ein Bitfeld ist allerdings eine Konstruktion, die das ganze lesbarer 
machen kann:
1
typedef struct
2
{
3
  unsigned int rest_oben : 5;
4
  unsigned int subadresse : 3;
5
  unsigned int rest_unten : 1;
6
  unsigned int adresse_high : 7;
7
} meine_adresse_t;
8
9
meine_adresse_t array[256];
10
11
...
12
13
array[17].subadresse = 2;
14
array[17].adresse_high = 19;

"rest_oben" und "rest_unten" sind die von Dir beschriebenen "anderen 
Informationen", die man, sofern sie einzelne Bits sind, natürlich auch 
weiter aufdröseln kann.

Auf die Elemente des Bitfelds kann wie auf normale Strukturelemente 
zugegriffen werden; der Compiler übernimmt für Dich sämtliche Bitshift- 
und Maskierungsoperationen.

Soll alternativ noch ein Zugriff auf das Ding als opaker 16-Bit-Wert 
geschehen, lässt sich das ganze in eine union mit einem uint16_t 
verpacken.

Aber: Was da sinnvoll ist, hängt von der Art der Nutzung ab.

Wenn die Reihenfolge der Elemente im Speicher relevant ist (weil sie 
z.B. als direkte Kopie die Daten eines von irgendwo kommenden Protokolls 
abbilden), muss die Reihenfolge der Bitfeldelemente gegbenenfalls 
angepasst werden.

: Bearbeitet durch User
von Thomas P. (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Den Zusammenhang zwischen dem von Dir beschriebenen in Assembler
> genutzten Array aus "zwei-byte-Variablen" und dem zweidimensionalen
> Array hier kann ich nicht so recht erkennen.

Die Beschreibung trifft auf ein Element des Arrays zu. Es gibt pro Zeile 
also 8 solcher Elemente, von denen 0-8 gültig sein können.

> Soll alternativ noch ein Zugriff auf das Ding als opaker 16-Bit-Wert
> geschehen, lässt sich das ganze in eine union mit einem uint16_t
> verpacken.

Ein alternativer Zugriff muss möglich sein, da dieses Array derzeit bei 
jedem Start aus dem EEPROM in den RAM gelesen werden muss. Keine Ahnung, 
wie man das am besten umsetzt. Wird wohl nur byteweise gehen, wenn ich 
das Datenblatt des EEPROM anschaue.

> Wenn die Reihenfolge der Elemente im Speicher relevant ist (weil sie
> z.B. als direkte Kopie die Daten eines von irgendwo kommenden Protokolls
> abbilden), muss die Reihenfolge der Bitfeldelemente gegbenenfalls
> angepasst werden.

Wird wohl auch zutreffen, da in einer späteren Ausbaustufe die Daten 
über USB kommen und auch geliefert werden sollen und dann in die 
verschiedenen Arrays einzusortieren sind. Ich glaube, ich sollte die 
Datenanordnung noch einmal neu konzipieren. Die alte Lösung hat stark 
Rücksicht auf die Zugriffsgeschwindigkeit und einfache Zeigerverwaltung 
genommen und die Wartbarkeit stand im Hintergrund (Änderungen waren auch 
nie notwendig).

Thomas

von Thomas P. (topla)


Lesenswert?

Ich glaube, ich habe das jetzt verstanden, zumindest im Ansatz. Etwas 
auf mein Vorhaben angepasst könnte das so aussehen:
1
typedef struct 
2
{
3
  unsigned int rest_oben    : 4;
4
  unsigned int plmi         : 1;
5
  unsigned int subadresse   : 3;
6
  unsigned int adresse_high : 8;
7
} stbed_t;
8
9
typedef struct
10
{
11
  unsigned int rest_oben : 5;
12
  unsigned int rm_nr : 3;
13
  unsigned int adr_rm : 8;
14
} albed_t;
15
16
typedef struct
17
{
18
  unsigned int rest  : 5;
19
  unsigned int adr_w : 11;
20
} fstep_t;
21
22
typedef struct
23
{
24
  unsigned int rest_oben : 6;
25
  unsigned int rm_nr : 10;
26
} lm_dat_t;
27
28
29
typedef struct 
30
{
31
  stbed_t stbed[4];
32
  albed_t albed[4];
33
  fstep_t step[32];
34
  lm_dat_t lm_dat[8];
35
} folge_t;
36
37
folge_t folge[256] EXTMEM;

Und wie greift man nun auf die Daten zu?
In deinem Beispiel

array[17].subadresse = 2;
array[17].adresse_high = 19;

als auch mein Versuch mit

folge[32].stbed[2].adresse_high = 34;

wirft den gleichen Fehler

error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token

und ich habe hier keinen blassen Schimmer, was ich falsch mache.
Bitte um Nachhilfe.

Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas P. schrieb:

> wirft den gleichen Fehler
>
> error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
>
> und ich habe hier keinen blassen Schimmer, was ich falsch mache.
> Bitte um Nachhilfe.


bei derartigen Fehlermeldungen ist der eigentliche Fehler meist in den 
Zeilen davor zu finden. Das könnte auch ein vergessenes Include File 
sein. Zum Beispiel ein Include File, in dem die ganzen Strukturen 
definiert sind.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas P. schrieb:
> folge[32].stbed[2].adresse_high = 34;

So heißen Deine Datentypen ja auch nicht.

folge[5].step[2].adr_w = 7;

oder

folge[6].albed[0].rm_nr = 1;

Das muss funktionieren.

von Eric B. (beric)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Thomas P. schrieb:
>> folge[32].stbed[2].adresse_high = 34;
>
> So heißen Deine Datentypen ja auch nicht.

Eh... doch! Oder?

> folge[5].step[2].adr_w = 7;
>
> oder
>
> folge[6].albed[0].rm_nr = 1;
>
> Das muss funktionieren.

Und was ist da der Unterschied zum Thomas' Beispiel?

von Stefan W. (dl6dx)


Lesenswert?

Rufus Τ. Firefly schrieb:
> folge[32].stbed[2].adresse_high = 34;
>
> So heißen Deine Datentypen ja auch nicht.

Hallo Rufus,

das Problem dürfte an anderer Stelle liegen:
Die nachstehenden Ausdrücke compilieren sauber - wenn sie an an der 
richtigen Stelle stehen.

Die vom OP zitierten Fehlermeldungen bekomme ich genau dann, wenn die 
Zuweisungen außerhalb einer Funktion stehen. Baut man so was (Auszug):
1
folge_t folge[256] EXTMEM;
2
3
folge[32].stbed[2].adresse_high = 34;
4
folge[5].step[2].adr_w = 7;
5
folge[6].albed[0].rm_nr = 1;
6
7
int main(void)
8
    {
9
    }

bekommt man die genannten Fehlermeldungen
1
avr-gcc  -mmcu=atmega1284p -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT struct_test.o -MF dep/struct_test.o.d  -c  ../struct_test.c
2
../struct_test.c:45:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
3
../struct_test.c:46:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
4
../struct_test.c:47:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token

Grüße

Stefan

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Eric B. schrieb:
> Eh... doch! Oder?
>
>>

Äh, ich war etwas oberflächlich und hielt "stbed" für einen typo.


Leise rieselt Asche auf mein ergrauendes Haupt.

Stefan hat den eigentlichen Fehler aber wohl gefunden:

Zuweisungen außerhalb einer Funktion sind nicht möglich.

von Thomas P. (topla)


Lesenswert?

Stefan Wagner schrieb:
> Rufus Τ. Firefly schrieb:
>> folge[32].stbed[2].adresse_high = 34;
>>
>> So heißen Deine Datentypen ja auch nicht.
>
> Hallo Rufus,
>
> das Problem dürfte an anderer Stelle liegen:
> Die nachstehenden Ausdrücke compilieren sauber - wenn sie an an der
> richtigen Stelle stehen.

Hallo Stefan,

Du hast Recht, blöder Anfängerfehler, obwohl ich es gerade erst gelesen 
habe.
Ich schreibe freiwillig ohne copy&paste 100 mal "Anweisungen sind nur 
innerhalb von Funktionen zulässig".

Vielen Dank für die Unterstützung.

Thomas

von Thomas P. (topla)


Lesenswert?

Nachdem die Kuh im Punkt 1 vom Eis ist, möchte ich gerne noch einmal auf 
die 2. Frage zurückkommen:

Da der EEPROM im Controller vorne und hinten nicht ausreicht, habe
ich einen externen EEPROM über SPI angebunden.
Frage:
Wie bildet man den Aufbau dieses Speichers ab?
Es gibt ja keinen direkten Zugriff auf dieses Teil Hardware, den der
Compiler umsetzen muss (kann). Ich bin noch nicht so weit, aber es wäre
ja bestimmt ganz nett, wenn man mit den eigenen SPI-Routinen für die
Ermittlung der Adressen im externen EEPROM auf ein array[a][b]
EXT_EEPROM zugreifen könnte.
Wie fängt man das am besten an?

Es gibt auch noch eine Zusatzfrage:
Kann man den Compiler/Linker überreden, die Auslastung des selbst 
definierten EXTMEM beim build mit auszugeben? Und wenn ja, wie geht es?

Thomas

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas P. schrieb:
> aber es wäre ja bestimmt ganz nett, wenn man mit den eigenen
> SPI-Routinen für die Ermittlung der Adressen im externen EEPROM auf ein
> array[a][b] EXT_EEPROM zugreifen könnte.

Keine Chance. Du wirst statt des Arrayzugriffs eigene Funktionen 
verwenden müssen, à la

wert = ReadExtEEPROM(a, b);

und

WriteExtEEEPROM(a, b, wert);

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.