PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PROGMEM-Array über "extern" verwenden?



Jaecko
30.01.2010, 12:33
Moin.

Kleines Problem: In einer .h-Datei liegt ein Array im Flash:

const stc_menuitem_extdV2 menuitems[] PROGMEM = {
// nen haufen Daten
};

Bisher wurde dieses Array nur von einer main.c-Datei verwendet, in dem halt die betreffende menuitems.h-Datei includiert wurde. Hat soweit auch funktioniert.

Nun wird dieser Array jedoch von mehreren .c-Dateien benötigt (main.c, keys.c). Der Schritt, hier die menuitems.h zu includen, bringt jedoch den Fehler "multiple definition of 'menuitems'".

Nun war meine Idee, das ganze wie mit "normalen" Variablen zu machen, d.h. ich werf den Array in menuitems.c, setze in die menuitems.h eine extern-Deklaration und binde die Datei so ein.
Klappt ja mit normalen Variablen im RAM wunderbar.

"extern const stc_menuitem_extdV2 menuitems[] PROGMEM;"
klappt jedoch nicht so ganz, da z.B. in der keys.c in einer Funktion mit einer for-Schleife selbige bemängelt wird:

for (ui16_t MenuCnt = 0 ; MenuCnt < sizeof (menuitems) / sizeof (stc_menuitem_extd) ; MenuCnt++)
{
}

Fehler: invalid application of 'sizeof' to incomplete type 'const struct stc_menuitem_extdV2[]'

Wie müsste hier die extern-Deklaration für eine PROGMEM-"Variable" aussehen?

mfG

sternst
30.01.2010, 13:14
Dein Problem hat nichts mit dem PROGMEM zu tun (würde im RAM genauso wenig funktionieren). Bei einem "extern type array[];" ist die Größe des Arrays nun mal unbestimmt, und daher funktioniert auch sizeof() nicht.

Du hast im Grunde drei Möglichkeiten:

1) Die konkrete Größe mit angeben:
extern type array[123];

2) Eine zusätzliche Variable für die Größe verwenden:
type array[] = {...};
const uint8_t array_size = sizeof(array);
...
extern type array[];
extern const uint8_t array_size;

3) Das Array mit einer eindeutigen Endkennung versehen (wie die Null-Terminierung bei Strings). Dann brauchst du die Größe in der Schleife nicht.

Ich persönlich favorisiere immer Variante 3, außer "type" ist wirklich richtig groß.

Jaecko
30.01.2010, 13:24
Hm eigentlich logisch.
Dachte, dass der Compiler selbst die Grösse des Arrays bestimmt, da die ja zur Compilezeit bekannt ist.
Aber werd hier dann auch auf #3 zurückgreifen, zumal es einen "EOF"-Eintrag ja schon gibt.

sternst
30.01.2010, 13:33
Dachte, dass der Compiler selbst die Grösse des Arrays bestimmt, da die ja zur Compilezeit bekannt ist.Die Dateien werden strikt getrennt voneinander übersetzt. Bei der einen Datei sieht er nur das "extern type array[];". Er weiß beim Übersetzen dieser Datei schlicht nicht, wie groß das Array ist.