Um ganz weit auszuholen und über einen (hoffentlich Interessanten) Umweg
ans Ziel zu kommen...
Die AVR CPU/MCU's basieren auf der Harvard Architektur. Im Gegensatz
dazu haben die "normalen" PC-CPUs eine Von Neumann Architektur.
Von Neumann Architektur:
Programm(e) und Daten teilen sich einen Adressraum.
D.h. Wenn auf Adresse 4712 Programmcode steht, kann man dort keine
Daten ablegen (ohne das Programm an dieser Stelle zu zerstören).
Harvard Architektur:
Programm(e) und Daten (und eEprom) besitzen jeder für sich einen
eigenen Adressraum.
D.h. Die Adresse 4712 im Programmspeicher ist eine völlig andere als
die Adresse 4712 im Datenspeicher und wiederum eine andere als 4712 im
eEprom Bereich.
Für die Zugriffe auf die verschieden Adressräume werden verschieden
Maschinenbefehle verwendet.
Da "C" aus der Welt der Von Neumann Architektur stammt, kennt "C"
keine Notation für die unterschiedlichen Adressräume. Unter AVR-GCC
werden die normalen "C" Zeigeroperationen immer in einen Zugriff auf
das RAM übersetzt. Für den Zugriff auf die aderen Addressräume
existieren spezielle Funktionen (inline Assembler-Macros).
Um dem Compiler mitzuteilen, dass er die Daten gefälligst im
Programmspiecher bzw. eEprom abzulegen hat und nicht im RAM, existieren
die "Konstrukte" mit
_attribute_ ((section (".xxx")))
Zugriff auf Byte 4712 im RAM: char c = *((char *)4712);
Zugriff auf Byte 4712 im Flash: char c = pgm_read_byte(4712);
Zugriff auf Byte 4712 im eEprom: char c = eeprom_read_byte(4712);
Der CV Compiler kaschiert diese Unterschiede intern und führt
(offensichtlich) für jeden Zeiger die Information über dessen
zugehörigen Adressraum (auch zur Laufzeit?) mit. Darum ist es möglich
ganz normale "C" Speicherzugriffe zu verwenden.
unsigned int sinarray[241] _attribute_ ((section (".eeprom"))) ={
0, 305, 610, 916, 1221, 1527, 1832, 2137, 2442, 2748, 3053, 3358,
......};
Zugriff mit: eeprom_read_word(&sinarray[index]);
Wenn man/frau davon ausgeht dass sich die Werte in sintab nicht
verändern, kann man diese auch im FLASH ablegen.
unsigned int sinarray[241] PROGMEM ={ 0, 305, 610, 916, 1221, 1527,
1832,2137, 2442, 2748, 3053, 3358, ......};
Zugriff mit: pgm_read_word(&sinarray[index]);
P.S. Hinter PROGMEM verbirgt sich auch nur ein _attribute_ ((section
(".progmem")))
Happy new year.
Werner