Hallo,
ich habe ein paar Tabellen, die sehr groß sind. Für einen Nano könnte es
schon eng werden. Da auf die Tabellen nur lesend zugegriffen wird, habe
ich mir überlegt, ob man die nicht auch ins EEPROM verlegen könnte. Wie
kriege ich das am besten hin?
Beispieltabelle:
Hallo Elli,
hast tu tatsächlich so wenig Varianz in deiner Tabelle?
Dann zieh einfach für die Tabelle 500 ab, und schlag sie später wieder
drauf. Dann reicht dir ein uint8_t(0-255) und schon passt doppelt so
viel in den Flash.
Wenn das konstante Werte sind gehören die ins Flash!
So, wie es oben steht liegt die im RAM,
Wenn das Flash bereits voll ist, bringen dich die 512 Byte EEPROM auch
nicht wirklich weiter.
Man kann Variable mit dem Attribut der Memory Section versehen. eeprom
ist definiert. Dann landet alles gleich dort,wo es hin soll und man kann
sich den Umweg über das File ersparen.
Georg G. schrieb:> Man kann Variable mit dem Attribut der Memory Section versehen.> eeprom ist definiert. Dann landet alles gleich dort,wo es hin> soll und man kann sich den Umweg über das File ersparen.
Wie werden dann die initialen Werte ins EEprom geschrieben?
Stefanus F. schrieb:> Georg G. schrieb:>> Man kann Variable mit dem Attribut der Memory Section versehen.>> eeprom ist definiert. Dann landet alles gleich dort,wo es hin>> soll und man kann sich den Umweg über das File ersparen.>> Wie werden dann die initialen Werte ins EEprom geschrieben?
Natürlich mit AVRDude!
Es wird eine .eep-Datei generiert.
Wenn das konstante Werte sind gehören die ins Flash!
So, wie es oben steht liegt die im RAM,
Wenn das Flash bereits voll ist, bringen dich die 512 Byte EEPROM auch
nicht wirklich weiter, und dein eigentliches Problem liegt mit grosser
Wahrscheinlichkeit an einer ganz anderen Stelle.
Stromverdichter schrieb:> Dann zieh einfach für die Tabelle 500 ab, und schlag sie später wieder> drauf. Dann reicht dir ein uint8_t(0-255) und schon passt doppelt so> viel in den Flash.
Das würde wohl voll daneben gehen.
Wie willst du in einer uint8_t eine Wert von -6 unterbringen? ;-)
Der Offset darf maximal so groß sein, wie der kleinste Wert im Array,
bei o.g. Belegung also 494.
Vermutlich habe ich mich mit EEPROM falsch ausgedrückt. Ich meine in den
Speicher, wo der Programmcode steht. Ist auch EEPROM, wird aber wohl
Flash genannt.
Result:
> Der Sketch verwendet 10508 Bytes (34%) des Programmspeicherplatzes.> Das Maximum sind 30720 Bytes.> Globale Variablen verwenden 624 Bytes (30%) des dynamischen Speichers,> 1424 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
Und jetzt ohne PROGMEM:
1
<avr/pgmspace.h
2
3
volatileconstintTestArray[400]={500,...,569};
> Der Sketch verwendet 10508 Bytes (34%) des Programmspeicherplatzes.> Das Maximum sind 30720 Bytes.> Globale Variablen verwenden 1424 Bytes (69%) des dynamischen Speichers,> 624 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
Eine Frage noch: Wieso ändert sich die Belegung des
Programmspeicherplatzes nicht? Hier wie da bleiben es 10508 Bytes.
El Friede schrieb:> Eine Frage noch: Wieso ändert sich die Belegung des> Programmspeicherplatzes nicht? Hier wie da bleiben es 10508 Bytes.
Weil die initialen Werte beim Programmstart noch vor der main() Funktion
vom Flash in das RAM kopiert werden. Das RAM weiß ja sonst nicht, welche
Werte diese Speicherzellen haben sollen.
Stefanus F. schrieb:> Weil die initialen Werte beim Programmstart noch vor der main() Funktion> vom Flash in das RAM kopiert werden. Das RAM weiß ja sonst nicht, welche> Werte diese Speicherzellen haben sollen.
OK. Nur zum besser verstehen: Heißt das im Umkehrschluss, dass die Werte
ohne PROGMEM auch schon im Flash stehen, nur zum initialisieren des
RAM?
Mit PROGMEM müssten sie 2x im Flash stehen: 1x zum initialisieren und
zum 2. als Tabelle. Ist das so?
El Friede schrieb:> Mit PROGMEM müssten sie 2x im Flash stehen: 1x zum initialisieren und> zum 2. als Tabelle. Ist das so?
Ich korrigiere: nur 1x natürlich.
El Friede schrieb:> OK. Nur zum besser verstehen: Heißt das im Umkehrschluss, dass die Werte> ohne PROGMEM auch schon im Flash stehen, nur zum initialisieren des> RAM?
richtig,
deinen 2ten Teil versteh ich nicht, dürfte wohl falsch sein.
Stefanus F. schrieb:> Georg G. schrieb:>> Man kann Variable mit dem Attribut der Memory Section versehen.>> eeprom ist definiert. Dann landet alles gleich dort,wo es hin>> soll und man kann sich den Umweg über das File ersparen.>> Wie werden dann die initialen Werte ins EEprom geschrieben?
Ja, das Problem ist mir schon unter gekommen...
Dazu habe ich meine Arduino IDE so erweitert, dass ich die erzeugte
*.eep aus dem Menü auf einen Arduino spielen kann. Incl. Anwendung und
auch Bootloader, wenn nötig.
Eigentlich ist es nur eine Zeile in einer Konfigurationsdatei (ohne die
originalen Dateien anzufassen)
Und der Upload erfolgt über einen (beliebigen?) ISP Programmer.
Wenn Bedarf besteht, dann kann ich es ja mal raus suchen und versuchen,
in erklärende Worte zu fassen ...
Stefanus F. schrieb:> Wie werden dann die initialen Werte ins EEprom geschrieben?
Nur als Ergänzung: Wenn man ein .elf File erzeugten lässt, hat man alles
beisammen, Flash, EEProm und Fuses.
Arduino Fanboy D. schrieb:> Ja, das Problem ist mir schon unter gekommen...
eine eep wird normal nicht erzeugt, ich nutze noch den flash und später
das EEPROM vom RTC, ist leicher zu tauschen als den AVR.
Ausserdem löscht die IDE den ganzen AVR auch das EEPROM, das müsste
verhindert werden, aber bis jetzt brauche ich das nicht.
Stefanus F. schrieb:> Weil die initialen Werte beim Programmstart noch vor der main() Funktion> vom Flash in das RAM kopiert werden. Das RAM weiß ja sonst nicht, welche> Werte diese Speicherzellen haben sollen.
Die werden nicht kopiert, sondern man muss per Pointer darauf zugreifen.
Steht ebenfalls auf der von mir und dir verlinkten Seite.
Hallo,
eine andere Idee wäre mal zu schauen ob sich deine Werte nicht auch
durch eine einfache Funktion (4.-5. Grades) darstellen lässt? Muss man
natürlich schauen wie gut man eine Funktion annähern kann, aber dann
müsstest du gar ncihts mehr speichern außer deine Funktion und
berechnest die Werte on the fly. Wie gesagt nur ne Idee, hab nicht
überprüft wie die Werte aussehen bzw. MATLAB angeschmissen und was
berechnen lassen.
Gruß
EDIT = Vergiss meine Idee, die Funktion wäre zu komplex.
MikeH schrieb:>> Weil die initialen Werte beim Programmstart noch vor der main() Funktion>> vom Flash in das RAM kopiert werden. Das RAM weiß ja sonst nicht, welche>> Werte diese Speicherzellen haben sollen.> Die werden nicht kopiert, sondern man muss per Pointer darauf zugreifen.> Steht ebenfalls auf der von mir und dir verlinkten Seite.
Normale globale Variablen liegen im RAM. Wenn sie Initialisierungswerte
ungleich 0 haben, werden diese vor dem Start der main() Funktion vom
Flash ins RAM kopiert.
Wenn Du mir nicht glaubst, schau Dir das Assembler-Listing an.
Joachim B. schrieb:> Arduino Fanboy D. schrieb:>> Ja, das Problem ist mir schon unter gekommen...>> eine eep wird normal nicht erzeugt, ich nutze noch den flash und später> das EEPROM vom RTC, ist leicher zu tauschen als den AVR.>> Ausserdem löscht die IDE den ganzen AVR auch das EEPROM, das müsste> verhindert werden, aber bis jetzt brauche ich das nicht.
Da muss ich dir leider widersprechen.
Von den AVR Arduinos ist mir bekannt:
A:
Die Arduino IDE erzeugt beim kompilieren automatisch eine *.eep Datei.
Immer.
Das kann man nur verhindern, wenn man die Konfigurationsdateien
verändert.
B:
Beim normalen Upload aus der Arduino IDE, wird das EEPROM nicht
gelöscht, da bei allen Arduinos die EESAVE Fuse standardmäßig gesetzt
ist.
Stefanus F. schrieb:> Wenn Du mir nicht glaubst, schau Dir das Assembler-Listing an.
Die u.a. von dir verlinkte Dokumentation gibt eine ausführliche
Erklärung:
"Now that your data resides in the Program Space, your code to access
(read) the data will no longer work. The code that gets generated will
retrieve the data that is located at the address of the mydata array,
plus offsets indexed by the i and j variables. However, the final
address that is calculated where to the retrieve the data points to the
Data Space! Not the Program Space where the data is actually located. It
is likely that you will be retrieving some garbage. The problem is that
AVR GCC does not intrinsically know that the data resides in the Program
Space."
Alles andere wäre auch sinnlos, weil kein bit im RAM gespart würde.
Ich bin damit raus.
MikeH schrieb:> Now that your data resides in the Program Space, your code to access> (read) the data will no longer work.
Das ist für C++ absolut richtig.
C hingegen kennt das __flash Attribut für Variablen.
Wenn man also die Datendefinition und die Zugriffsroutinen in C Dateien
unterbringt, kann man da doch was managen, ohne explizit auf die
pgm_read_***() Dinger zurückgreifen zu müssen.
MikeH schrieb:> "Now that your data resides in the Program Space
Das gilt für den Fall mit PROGMEM.
Ich habe aber über normale Variablen ohne PROGMEM geschrieben. Das war
doch der Fall, wo doppelt Speicher belegt wurde und der TO nachgehakt
hatte, warum das so sei.
Wir haben aneinander vorbei geredet.
Stromverdichter schrieb:> Dann zieh einfach für die Tabelle 500 ab, und schlag sie später wieder> drauf. Dann reicht dir ein uint8_t(0-255) und schon passt doppelt so> viel in den Flash.El Friede schrieb:> {500,505,506,497,
da aber mindestens ein Wert 497 ist würde ich 450 abziehen dann bleiben
alle Werte >0 && <255 jedenfalls positiv
Beim C-Compiler der IAR Workbench gibt es das
Attribut "flash".
So wird
flash char Name[]={"Mercedes"};
im Flash gehalten und auch von dort verwendet.
mfg