mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AtTiny: EEPROM als effektiven Konfigspeicher nutzen (z.B. Defines ablegen)


Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Sinusgeek (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

~

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ...

Autor: Sinusgeek (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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...

~

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.