Hallo, momentan habe ich in einem etwa 4 KByte großen C-Projekt auf einem Attiny84 eine Datei die von jeder Source-Datei im Projekt inkludiert wird und als globale Konfigurationsdatei verstanden werden will. Darin sind jede Menge #defines enthalten die z.B. Timeout-Zeiten, Baudraten usw. enthalten. Da ich später nicht mehr die Möglichkeit haben werde bei jeder Änderung den Sourcecode neu aufzuspielen, muß ich dies z.B. per UART regeln. Dafür habe ich ein kleines Protokoll, das läuft auch alles schon. Jetzt hatte ich die Idee, einige der Parameter ins EEPROM zu schreiben, damit ich sie später noch von außen ändern kann ohne neu kompilierten Code zu flashen. Jetzt zu meiner Frage: Gibt es eine Möglichkeit (nutze IAR for AVR) Daten im EEPROM so anzusprechen, als wären es "normale" #define's im Programmspeicherbereich? Hinzu kommt ja, dass ich nicht alle Daten ins RAM laden kann, weil mir sonst die Luft ausgeht. Andererseits das Zeug jedes mal über eine ReadEeprom-Funktion mit EEAR, EECR und EEDR zu holen, ist ja auch nicht effektiv, oder? Ist es vielleicht auch denkbar beim Systemstart die Parameter ins FLASH umzukopieren und dann dort via #define zuzugreifen? Gibt's da eine elegante Möglichkeit? Vielen Dank
Du verwechselst Kraut und Rüben :-/
#define ist eine Präprozessordirektive. Die Zahlen und Werte, die dort
definiert sind, werden bereits beim Compilieren in den Sourcecode
eingetragen. Und sind natürlich anschliessend wild im Programmspeicher
verteilt.
Was du willst, ist offenbar ein "Parameterspeicher". Das wird idR über
Strukturen abgebildet, dann kannst du den ganzen Parameterblock auf
einen Rutsch irgendwo hinkopieren.
> einem etwa 4 KByte großen C-Projekt
Das ist mE ein eher verschwindend kleines C-Projekt ;-)
Du solltest dir deine Grundstruktur der Datenhaltung und -verwaltung vor
Projektbeginn gründlich überlegen (es ist noch nicht zu spät).
Lothar Miller wrote: > Du verwechselst Kraut und Rüben :-/ > > #define ist eine Präprozessordirektive. Die Zahlen und Werte, die dort > definiert sind, werden bereits beim Compilieren in den Sourcecode > eingetragen. Und sind natürlich anschliessend wild im Programmspeicher > verteilt. Vielleicht nicht schön, funktioniert aber. Ich gelobe Besserung. ;-) > Was du willst, ist offenbar ein "Parameterspeicher". Das wird idR über > Strukturen abgebildet, dann kannst du den ganzen Parameterblock auf > einen Rutsch irgendwo hinkopieren. Ja richtig, aber wo hinkopieren? Doch nur in den RAM? Da das mittlerweile ganzschön viele Parameter sind und ich nur 512B habe, kann ich mir das nicht leisten. Das ganze in eine Struktur zu füllen macht sicherlich Sinn, guter Vorschlag. Nur wohin damit? >> einem etwa 4 KByte großen C-Projekt > Das ist mE ein eher verschwindend kleines C-Projekt ;-) > Du solltest dir deine Grundstruktur der Datenhaltung und -verwaltung vor > Projektbeginn gründlich überlegen (es ist noch nicht zu spät). Der kleine Knirps hat nur 8KByte. Für den ist das schon ne ganze Menge. Insgesamt betrachtet hast du aber natürlich recht.
na, immerhin hat der Tiny84 den SPM-Befehl. Theoretisch ist es also möglich, Daten in den flash zur Laufzeit zu schreiben. Das bedeutet aber auch, dass vorher eine ganze page gelöscht wird, weiss nicht, wie gross die flash-pages beim Tiny84 sind. Das ganze wirst du wahrscheinlich per inline-Assembler machen müssen. Also, -Parameter sammeln und als const (oder flash) einrichten. Irgendwie dem Compiler mitteilen, dass die in einem Block lokalisiert werden -neue Parameter direkt in den flash oder über den Umweg EEPROM - dann bei Programmstart nachschauen, ob die Daten gleich oder ein Nachladen erforderlich ist Prinzipiell machbar, aber rel. aufwändig.
Der Tiny84 hat 64 Byte große Pages. Einen FLASH-Treiber habe ich auch schon geschrieben, der den Zugriff darauf ermöglicht. 64 Byte müssten für die Parameter reichen. Vielleicht wäre es möglich beim Programmstart den Käse erstmal aus dem EEPROM ins FLASH zu kopieren und von dort aus über eine Struktur zugreifen? Ich habe auch im Handbuch von den IAR-Speicherkeywords "__flash" und "__eeprom" als Variablenattribut gelesen. Im endeffekt versteckt sich dahinter aber sicherlich auch nur ein verkapselter Zugriff via die Spezialregister, oder? Wie macht man sowas üblicherweise? Einfach in den RAM laden? Ich erfrinde ja hier sicherlich nicht gerade das Rad neu... Parameterspeicher gibt's doch in jedem gewöhnlich Steuergerät.
Ich vermute, Alex will die Konstanten, die zwar vordefiniert wurden, aber (nach dem Compilieren) aufgrund der Imidiate-Instruktionen Teil des Codes werden (also nicht in separaten Codeblöcken landen, sondern weit verstreut in XXi-Instruktionen), ins EEP verlagern. Dies geht natürlich nicht. Es bietet sich aber an, die Parameter im EEP zu halten und sie dann, wenn sie gebraucht werden, aus dem EEP zu lesen. Sehr oft gebrauchte Parameter können bei Programmstart ins SRAM kopiert werden und von dort gelesen werden. Im Flash sehe ich da keinen (großen) Nutzen, Flash-Zugriffe sind aufwendiger als EEP-Zugriffe (Z-Pointer sichern, laden, LPM). Natürlich bläht das das Programm etwas auf, denn statt einfacher Immidiate-Instruktionen müssen die Parameter jetzt etwas umständlicher ins Register geschaufelt werden. ~
Richtig, die meisten #define's werden nur wenige Male benötigt und sind somit direkt im Code eingebettet, beispielsweise das Generatorpolynom für den CRC. Ich werde mal mit dem "__eeprom"-Keyword von IAR herumspielen und den Assembler analysieren. Aber an einiger zusätzlicher Registerschaufelei werde ich wohl nicht vorbei kommen. Ich muß mir mal Gedanken machen, bei welchen Parametern es wirklich sinnvoll ist, diese ins EEPROM auszulagern, der Rest bleibt dann als #define stehen.
Hallo nochmal, Das "__eeprom" ist zwar ungemein praktisch, da es die Verwendung wie eine normale Variable ermöglicht, aber es verbirgt sich dahinter nichts anderes als das übliche Spezialregister-Gemauschel. Jeder Lesezugriff benötigt rund 12 ASM-Befehle, jeder Schreibzugriff sogar 30 ASM-Befehle. Das ist schon einiges mehr als etwas "immediate" zu erledigen ...
> jeder Schreibzugriff sogar 30 ASM-Befehle.
Naja, das gilt aber nur, wenn nur 1 Byte geschrieben werden muss. Denn
das nächste Byte muss warten, bis der EEP mit dem vorherigen Byte fertig
ist, und das dauert (wenn ich mir nichts Falsches gemerkt habe) einige
Millisekunden.
Sorry, bei C will und kann ich nicht mitreden, aber C erzeugt auch nur
ASM/MC und kann dadurch auch nicht schneller/sparsamer sein...
~
Bei diesem Mikrocontroller dauert jeder Schreibzugriff auf's EEPROM pro Byte ca. 3-4ms. Die dort gehaltenen Daten werden jedoch oft gelesen und sehr selten geschrieben. Ich habe mal testhalber das Lese/Schreiben/Verwenden eines Structs einmal mit "__flash" und einmal mit "__eeprom" getestet. Vom "Befehlaufwand" her, lag der Flash-Zugriff da deutlich besser. Okay, mit Assembler kann man da sicher noch 20-30% ausknautschen, aber in dem getesteten Fall war die Performance des Flash doch erheblich besser, da nur mit dem Z-Pointer hantiert wurde, während beim EEPROM jedes mal das Rad neu erfunden wurde (Adresse in Register schaufeln, EEPROM-Adresse anlegen, Auslesevorgang starten, Umkopieren, etc.). Auch schien es mir, dass Burst-Lesevorgänge deutlich schneller vom Flash aus sind, da die Adresse nicht komplett neu erzeugt werden muß sondern lediglich inkrementiert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.