Array im EEPROM mit "variabler" Länge initialisieren

Gast #2208229
Lesenswert?

Hallo Forum,
ich habe eine Frage zur initialisierung (zur Entwicklungszeit) eines 
EEPROMs. In meinem konkreten Fall geht es darum, dass ich ein Spiel auf 
einem AVR umsetze.
Die Anzahl der Spieler definiere ich mittels #define PLAYER_MAX, so dass 
ich diese je nach Auslastung des EEPROMs ggf. noch einfach anpassen 
kann. Außerdem programmiere ich ungerne mit "starren" Parametern.

Derzeit gehe ich von 16 Spielern aus.

Meine initialisierung des EEPROMs sieht aktuell so aus:
1
/* ************************************************************************** **
2
 * ** DEFINES
3
 * ************************************************************************** */
4
#define TOURNAMENT_INIT_PLAYER     {PLAYERTSTATE_OFF, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
5
#define TOURNAMENT_INIT        {TOURNAMENTSTATE_FREE, {TOURNAMENT_INIT_PLAYER, \
6
  TOURNAMENT_INIT_PLAYER, \
7
  TOURNAMENT_INIT_PLAYER, \
8
  TOURNAMENT_INIT_PLAYER, \
9
  TOURNAMENT_INIT_PLAYER, \
10
  TOURNAMENT_INIT_PLAYER, \
11
  TOURNAMENT_INIT_PLAYER, \
12
  TOURNAMENT_INIT_PLAYER, \
13
  TOURNAMENT_INIT_PLAYER, \
14
  TOURNAMENT_INIT_PLAYER, \
15
  TOURNAMENT_INIT_PLAYER, \
16
  TOURNAMENT_INIT_PLAYER, \
17
  TOURNAMENT_INIT_PLAYER, \
18
  TOURNAMENT_INIT_PLAYER, \
19
  TOURNAMENT_INIT_PLAYER, \
20
  TOURNAMENT_INIT_PLAYER}}
21

22
/* ************************************************************************** **
23
 * ** LOCAL VARIABLES
24
 * ************************************************************************* */
25
tTournament eeTournament[] EEMEM = {TOURNAMENT_INIT, \
26
  TOURNAMENT_INIT, \
27
  TOURNAMENT_INIT, \
28
  TOURNAMENT_INIT};

Es werden also 4 Spielstände á 16 Spieler im EEPROM abgelegt.

Meine Frage ist nun, wie kann ich den o.g. Quelltext so dynamisieren, 
dass ich nicht 16x TOURNAMENT_INIT_PLAYER schreibe, sondern sich dies 
auf mein #define PLAYER_MAX bezieht?!

Vielen Dank im vorraus!

Fabian

PS: Die typdefs habe ich mir gespart zu posten, da es mir erstmal um das 
grundsätzliche Lösen eines solchen Problems geht.
#2208340
Lesenswert?

Da der Preprozessor keine Schleifen kann, mußt du dir ein #if-Gebirge 
bauen, das entsprechend der Definition von PLAYER_MAX die notwendigen 
Initialisierungen erzeugt.

Schön ist das nicht, aber es geht...

Die andere Möglichkeit wäre, dynamisch zu initialisieren.
Persönliche Seite #2208483
Lesenswert?

Falls du gcc verwendest und keine keine Abneigung gegen GNU-C hast, geht 
ähnlich wie bei case-Ranges:
1
#define N 12
2

3
char c[N] = 
4
{
5
    [0 ... N-1] = 'a'
6
};

ansonsten gibt's noch die Möglichkeit, den Initializer in Assembler zu 
schreiben; der gas-Präprozessor kann mehr als der C-Präprozessor. Schau 
dir einfach mal .macro an. Damit kann man auch Schleifen machen und z.b. 
das i-te Element mit 2i initialisieren. Und dann gibt es noch .rept für 
einfache Fälle.
#2208522
Lesenswert?

Das wäre auch noch eine Möglichkeit für N <= 31:
1
#define N 11
2
 
3
char c[N] =
4
{
5
  #if N & 0x01
6
    "a"
7
  #endif
8
  #if N & 0x02
9
    "aa"
10
  #endif
11
  #if N & 0x04
12
    "aaaa"
13
  #endif
14
  #if N & 0x08
15
    "aaaaaaaa"
16
  #endif
17
  #if N & 0x10
18
    "aaaaaaaaaaaaaaaa"
19
  #endif
20
};
Persönliche Seite #2208962
Lesenswert?

Uhu Uhuhu schrieb:
> Das wäre auch noch eine Möglichkeit für N <= 31:
>
> [c]#define N 11
>
> char c[N] =
> {
>   #if N & 0x01
>     "a"
>   #endif
>   ...

Wenn's kein String ist, fehlen dann aber die trennenden Kommas.

Am einfachsten ist wohl, die Daten so auszulegen, daß sie Initializer 
überall 0 ist. Der obige Initializer sieht schon mal schwer danach aus.
#2209666
Lesenswert?

Johann L. schrieb:
> Wenn's kein String ist, fehlen dann aber die trennenden Kommas.

Das ist dank der Syntax für Initialisiererlisten auch kein Problem:
1
#define N 11
2

3
char c[N] =
4
{
5
  #if N & 0x01
6
    'a',
7
  #endif
8
  #if N & 0x02
9
    'a','a',
10
  #endif
11
  #if N & 0x04
12
    'a','a','a','a',
13
  #endif
14
  #if N & 0x08
15
    'a','a','a','a','a','a','a','a',
16
  #endif
17
  #if N & 0x10
18
    'a','a','a','a','a','a','a','a',
19
    'a','a','a','a','a','a','a','a',
20
  #endif
21
};

Ein Komma am Ende einer Initialisiererliste ist zulässig.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren