Dei Adresse muss nicht bekannt sein. Zwei Adressen in meinem Beispiel ergeben sich werst zur Laufzeit, andere zur Linkzeit (extern...). Woher die Adressen sind ist ja egal.
oderCode:function_t func = (function_t) pgm_read_word (& menu[i].Menu_Funkt); func();
Das Problem mit der Harvard-Architektur und GCC ist, daß man Flash-Adressen (dito EEPROM) als Attribut angibt, und nicht wie es sein müsste als Qualifier (so wie const, volatile, unsigned, ...). Das macht vielerorts Probleme. U.a weiß GCC beim zugriff nicht, wie er darauf zugreifen soll. Etwa wenn ein Zeiger in eine Funktion run kommt: ist es RAM-Adresse? EEPROM? oder Flash? Deshalb muss man umständlich mit den pgm_read/write Zeug arbeiten.Code:((function_t) pgm_read_word (& menu[i].Menu_Funkt))();
Für andere Architekturen (linearere Adressraum) hätte man einfach sagen können
#define pgm_read_byte(addr) (*((uint8_t*) addr))
bzw
#define pgm_read_byte(addr) (* addr)
wenn addr ein Zeiger aud uint8_t ist.
Wenn du eine Struktur im Flash hast musst du eben die Komponenten per pgm_xxx holen/schreiben:
x = a.b; --> pgm_read_block (&x, &a.b, sizeof (a.b));
x = a->b; --> pgm_read_block (&x, &a->b, sizeof (a->b));
Lesezeichen