Forum: Mikrocontroller und Digitale Elektronik Struktur um Offset verschieben


von Schotter (schottre)


Lesenswert?

Hallo,

ich habe im EEPROM eine Parametrierung liegen, sagen wir an Position 
0x00 und eine weitere an Position 0x100. Je nach Jumper soll entweder 
die eine oder die andere geladen werden.

Ursprünglich lagen die Parametrierungen direkt aneinander, sprich die 
zweite lag bei 0x10 und in der Software selbst hatte ich Zugriff mittels 
eines Arrays (Konfigurationstruktur[]). Das ist jedoch nicht 
aufwärtskompatibel. Deswegen habe ich den zweiten Parametersatz im 
EEPROM weiter weg geschoben.

Die einfachste Lösung wäre nun meine Konfigurationsstruktur um soviele 
Bytes zu vergrößern, aber dann frisst das natürlich unnötig viel RAM. 
Viel schöner wäre es daher die letztlich genutzte Strukturvariable um 
den genannten Offset zu verschieben.
1
struct PARAMETRIERUNG_T {
2
  U8 par1;
3
  U8 par2;
4
..
5
  U8 parX;
6
};
7
8
struct PARAMETRIERUNG_T Config;

Neben Config gibt es noch F_Config, das letztlich die Speicherposition 
im EEPROM enthält.
1
extern const struct PARAMETRIERUNG_T F_Config[2];

In meiner main-Funktion dachte ich dann an sowas:
1
if(jumper_set)
2
  Config = F_Config[0];
3
else
4
  Config = (F_Config[0] + 0x100);

Das meckert, aber da wird's doch sicherlich eine Möglichkeit geben.

Schöne Grüße,
Thorsten

von Martin L. (maveric00)


Lesenswert?

Hallo,

Du vermischt hier munter Strukturen und Arrays von Strukturen, ohne den 
Zeigeraspekt von Arrays zu berücksichtigen.

F_Config ist in Deinem Fall ein Zeiger auf ein Array von zwei 
Config-Strukturen, der mit F_Config[0] oder F_Config[1] dereferenziert 
wird.

Config ist jedoch einfach direkt eine Struktur. Was Du möchtest, ist 
jedoch die Adresse der Struktur ändern zu können. Daher muss Config als 
Zeiger ausgebildet werden:
1
struct PARAMETRIERUNG_T *Config;

Dann kannst Du Config zuweisen:
1
if(jumper_set)
2
  Config = &(F_Config[0]);
3
else
4
  Config = (&(F_Config[0]) + 0x100);

Zugreifen kannst Du dann wieder mit
1
Config[0].par1

oder einfacher mit
1
Config->par1

Liest Dich noch etwas in die Behandlung von Zeigern und Zeigern auf 
Strukturen ein.

Alternativ kannst Du natürlich auch in Deiner Config-Strukt Dummy-Werte 
vorsehen, die den Platz für zukünftige Parameter reservieren. Dann 
funktioniert Dein alter Ansatz auch.

Schöne Grüße,
Martin

von Pandur S. (jetztnicht)


Lesenswert?

Ich haette eine Parametrierung auf [..], dort als erstes Word den 
Versatz zur naechsten Parametrisierung. Dann ist das System portabel.

von Schotter (schottre)


Lesenswert?

Martin L. schrieb:
1
struct PARAMETRIERUNG_T *Config;
>
> Dann kannst Du Config zuweisen:
>
1
if(jumper_set)
2
  Config = &(F_Config[0]);
3
else
4
  Config = (&(F_Config[0]) + 0x100);

Auf diesen Weg hatte ich es gestern noch probiert und es kompilierte 
auch alles sauber, lies sich aufspielen, aber es funktionierte nicht. 
Ich bin dann mit dem Debugger drauf und hab mir die Adresszuweisungen 
angesehen.

&F_Config liegt auf 0x8400 und +0x100 sollte dann eigentlich 0x8500 
ergeben. Dort liegt auch der zweite Parametersatz, aber da geht irgend 
etwas schief. Nach der Addition von 0x100 zeigt Config nicht auf 0x8500 
sondern auf 0x9800 :/ Danach habe ich noch etwas gespielt, mit der 
Addition von 0x10 war ich immerhin schon auf 0x8540, aber letztlich habe 
ich es anders gelöst.

F_Config ist in Assembler definiert und meine Lösung war dann einfach 
noch ein F_Config2 zu definieren. Der Code vereinfachte sich dann zu:
1
if(jumper_set)
2
  Config = F_Config;
3
else
4
  Config = F_Config2;

Danke nochmals für die Hilfe.
Thorsten

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.