Forum: Compiler & IDEs Daten aus bestimmten EEProm-Addressen lesen


von Bernd Stenner (Gast)


Lesenswert?

Hallo,

ich bin leider bei der Durchsicht der bisherigen Postings zum Thema
EEProm nicht fündig geworden.
Ich habe folgende Frage: Ich möchte in das EEProm meines Mega8 einige
Defaults speichern -> klappt auch ohne Probleme. Via PonyProg lege ich
die Daten also in bestimmte Speicherzellen ab. Mein Programm soll nun
diese Speicherzellen auslesen und die Daten in Variablen speichern. Da
beginnt mein Problem.

1. Idee: Eine "EEPROM-Variable" deklarieren, in der Hoffnung, das
deren Zeiger auf den Anfang oder das Ende des EEProm zeigt. Mit
eeprom_read_block könnte ich dann den Inhalt auslesen. Klappt aber
nicht, umindest, was den zweiten Teil dieser Idee (Ziel des Zeigers)
betrifft.

2. Idee: den Zeiger auf die gewünschte EEProm-Adresse als uint8_t*
gecastete/deklarierte Konstante übergeben. -> Kommt aber auch nur Müll
raus.

3. Idee: Im Forum nachschauen -> ohne Erfolg

4. Idee: Selber fragen -> sei hiermit geschehen.

Danke für jede hilfe im Voraus.

gruß
bernd

von mthomas (Gast)


Lesenswert?

Dass (2) nicht funktioniert, wundert mich etwas. Was heisst "Muell"?
Nur 0xff? Wie sehen die entsprechenden Codezeilen aus? Sowas in der Art
res=eeprom_read_byte( ((uint8_t*)0x01ff) ); sollte Inhalt von
Eerpom-Adresse 0x01ff in res einlesen.

von Bernd Stenner (Gast)


Lesenswert?

Seltsam, es wird immer verwirrender, also...

Nein, es werden keine 0xFF ausgelesen, wenngleich das EEPROM ist
vollständig gelöscht ist, also mit 0xff beschrieben, außer am Anfang,
dort steht ein Probetext. Die Zeichen, die ausgelesen werden, ließen
sich nicht richtig interpretieren, da ich sie mittels UART an den PC
zur Ausgabe übertrage und somit nur das zugehörige ASCII-Zeichen sehe.
Ich habe aber inzwischen festgestellt, das PonyProg den EEProm mit den
Daten aus meinem Hex-File auch dann überschreibt, wenn ich den Befehl
"Write Program (Flash)" anwende (BTW: wie kann ich das
korrigieren?).
Nachdem ich nun das EEPROM immer kontrolliere und ggfls. neu
beschreibe, erhalte ich als ausgelesenen Daten Text aus dem Flash(!)
oder das Zeichen '#', meist letzteres.

NOch eine Zwischenfrage zur Adresse, die man angibt: Muß dies die
absolute Addresse des Speicherraumes sein, wie in PonyProg angezeigt,
oder relativ zum EEProm-Speicher beginn. (Für meine Versuche habe ich
aber beides probiert.)

Ich benutze übrigens das blockweise Lesen. Das byteweise Lesen
funktioniert nicht, weil es einen Fehler beim Compilieren verursacht,
den ich nicht auflösen kann:
    "implicit declaration of function 'eeprom_read_byte'".
Der betreffende Code lautet bei mir:
    char eeprom_text_buffer[64];
    eeprom_text_buffer[0] = eeprom_read_byte( ((uint8_t*)0x01ff) );

Alternativ habe ich noch folgendes ausprobiert:
    uint8_t eeprom_data_buffer[64];
    eeprom_data_buffer[0] = eeprom_read_byte( ((uint8_t*)0x01ff) );
Da kam dann die Fehlermeldung
    "undefined reference to 'eeprom_read_byte'".
Ist mir auch nicht ganz klar, warum.

hmm, ob Euch das weiterhilft, mir zu helfen?
Danke trotzdem...
gruß
bernd

von Bernd Stenner (Gast)


Angehängte Dateien:

Lesenswert?

hier noch der code...

von Steffen Brüssel (Gast)


Lesenswert?

DAS löschen des EEPROM macht das AVR Studio auch.
Allerdings gibts da ne Einstellung 'Erase device before Programming'

Hab sowas bei PonyProg auch noch nicht gefunden.

Gruß

Steffen

von OldBug (Gast)


Lesenswert?

Guten Morgen!

#include <Eeprom.h>

Möglicherweise mag das der Präprozessor "nicht wirklich", versuch
mal

#include <eeprom.h>

Dann das hier:

eeprom_read_block( *eeprom_text_buffer,
                   (uint8_t*) 0x01ff,
                   sizeof(eeprom_text_buffer));

Damit Zerstörst Du Dir den Zeiger auf Dein Array! Das:

eeprom_read_block( eeprom_text_buffer,
                   (uint8_t*) 0x01ff,
                   sizeof(eeprom_text_buffer));

übergibt den Zeiger auf den Anfang des Arrays an die Funktion.
Möglicherweise schreibst Du aber auch ausserhalb des EEPROMs, die
Adressen habe ich jetzt nicht geprüft. Man gibt sie übrigens ohne
offset an, d.h. '(uint8_t*) 0x01' Zeigt auf die zweite Adresse im
EPPROM.

von OldBug (Gast)


Lesenswert?

Quatsch, es muss natürlich

#include <avr/eeprom.h>

lauten! Sorry...

von OldBug (Gast)


Lesenswert?

Und natürlich noch viel mehr:

#include <io.h>      -> #include <avr/io.h>
#include <progmem.h> -> #include <avr/progmem.h>

von Bernd Stenner (Gast)


Lesenswert?

Moin,

danke für die verschiedenen Hinweise. Leider habe ich es aber bis jetzt
noch nicht zum Laufen bekommen.

Die Pfadergänzung "avr/" bzw. "avr\" führt bei mir zu
Compilerfehlern (Datei nicht gefunden). So wie ich die includes in
meinem Code definiert habe, läuft es aber grundsätzlich - halt von
Teilen des EEProm-Zugriffes abgesehen.

Der Hinweis mit Eeprom.h -> eeprom.h hat leider auch nicht geholfen.

Oldbug, dein Hinweis auf den Zeiger auf den Zeiger eines Arrays war
natürlich berechtigt, war schon spät gestern, daher vergaß ich zu
sagen, das ich verschiedene Variationen ausprobiert habe. Ich hatte und
habe auch mal probiert, nur mit dem Offset (0x1f u.ä.) zu arbeiten.

Die aktuell getesteten Alternativen sind:
    eeprom_read_block(eeprom_text_buffer, (uint8_t*) 0x01ff,
sizeof(eeprom_text_buffer));
    eeprom_read_block(eeprom_text_buffer, (uint8_t*) 0x01,
sizeof(eeprom_text_buffer));
    eeprom_read_block(eeprom_data_buffer, (uint8_t*) 0x01ff,
sizeof(eeprom_text_buffer));
    eeprom_read_block(eeprom_data_buffer, (uint8_t*) 0x01,
sizeof(eeprom_text_buffer));
..._text_... -> char [64]
..._data_... -> uint8_t [64] (wobei sich die Frage stellt, ist uint8_t
bereits ein Zeiger? Ändert aber nichts an dem eigentlichen Problem,
habe es auch mal mit ..._data_... -> uint8_t ausprobiert.)
Ergebnis: Durchweg kryptische Daten, aber stets reproduzierbar.
Irgendwie scheint ein Speicherbereich angesprochen zu werden, denn für
jede verwendete Adresse läßt sich eine bestimmte kryptische
Zeichenfolge reproduzieren. Ich tippe mal auf den Flash, denn nach
einem Reset kommen die gleichen Zeichenfolgen wie vorher und der EEProm
ist wie gesagt, gewiped, außer die ersten 8 Bytes.

gruß
bernd

von Bernd Stenner (Gast)


Lesenswert?

Nachtrag: Hat vielleicht jemand einen lauffähigen Code, mit dem ein
Programm auf das EEProm zugreift? Lernen-by-Nachmaching funktioniert
bei mir auch ganz gut ;-)

von OldBug (Gast)


Lesenswert?

Wenn avr/ als Prefix nicht funktioniert, stimmt mit Deiner
WinAVR/avr-gcc-Installation etwas nicht.

von Jörg Wunsch (Gast)


Lesenswert?

Ich vermute auch eine zu alte Version der Library hier...

In dem ein wenig erweiterten Demo hier:

http://www.sax.de/~joerg/avr-demo/

benutze ich den EEPROM, um den letzten PWM-Wert zwischenzuspeichern,
sodass er beim nächsten Einschalten wieder aktiviert wird.  Hat aber
noch keine Hooks für den ATmega8, das müsstest du selbst mal
reinnageln.  Sollte kein prinzipielles Problem sein, schließlich ist
es mit dem (pinkompatiblen) AT90S4333 ja schon gelaufen.

von Bernd Stenner (Gast)


Lesenswert?

Hallo Jörg,

danke für's Beispiel, hilft mir aber im Moment nicht wirklich, denn
soweit ich das sehen konnte, deklarierst du einen Zeiger auf eine
EEProm-Speicherzelle. Das hatte ich ganz zu Anfang schon mal versucht,
aber es hat nicht funktioniert. Ich hatte vermutet, das bei diesem
Vorgehen nicht eindeutig festgelegt ist, wo der Zeiger genau hinzeigt.
Wenn man dann also außerhalb des Programms Daten ins EEProm schreiben
will, stellt sich die Frage wohin. Daher suche ich die Lösung für das
direkte Adressieren des EEProms mittels Konstante. Aber das hat bisher
halt auch nicht geklappt. :-(

Den Sourcecode werde ich trotzdem gut gebrauchen können, um mir ein
paar andere Dinge, die du darin implementiert hast, anzuschauen.

gruß
bernd

von Jörg Wunsch (Gast)


Lesenswert?

Nein, ich nehme eine direkte EEPROM-Variable:

uint16_t ee_pwm __attribute__((section(".eeprom")));

Da es nur diese eine gibt, liegt das ab EEPROM-Adresse 0.

Deine Beschreibung "geht nicht" klingt mir irgendwie alles zu
schwammig.  Entweder nimmst du wirklich eine uralte Version von
Compiler/Library, oder du macht irgendwo anders Fehler (Hyperterminal
soll ja wohl auch nicht gerade det jelbe von det Ei sein).  Du kannst
doch zumindest mal dieses Demo ausprobieren und gucken, ob du damit an
den EEPROM richtig rankommst.

Hier sind noch die Änderungen für den ATmega8, aber ungetestet.

Index: demo.c
===================================================================
RCS file: /home/jcvs/src/avr/demo/demo.c,v
retrieving revision 1.20
diff -u -r1.20 demo.c
--- demo.c  8 Apr 2005 12:05:13 -0000  1.20
+++ demo.c  8 Apr 2005 14:27:58 -0000
@@ -85,6 +85,13 @@
 #if defined(_AVR_AT90S2333_)
 # define HAVE_ADC 1
 # define OC1 PB1
+#elif defined(_AVR_ATmega8_)
+# define HAVE_ADC 1
+# define OC1 PB1
+# define OCR1 OCR1A
+# define UBRR UBRRL
+# define PWM10 WGM10
+# define PWM11 WGM11
 #elif defined(_AVR_AT90S2313_)
 # define UCSRA USR
 # define UCSRB UCR

von bernd stenner (Gast)


Lesenswert?

Was ich meinte, war, das du die Adresse durch eben diese Anweisung in
eine Variable reinpackst. Was mir vorschwebt, ist halt sowas wie von
Oldbug beschrieben: (uint8_t*) 0x1fff oder (uint8_t*) 0x10, usw.

Ich gehe davon aus, daß du dir sicher bist, daß der Zeiger ee_pwm auf
Adresse 0 zeigt (rethorische Frage ;-). Davon bin ich bei meinen ersten
Versuchen halt auch ausgegangen. Denn deine Vorgehensweise war auch
meine zuerst. Ich habe aber nicht den Text aus dem EEProm ausgelesen,
der an Adresse 0 stand, sondern einen anderen, bzw. kryptische Zeichen.
Die konnte ich dann aber nicht im Speicher "orten".

Ich werde aber deine Demo natürlich ausprobieren, wenn auch erst nach
dem WE. Dann prüf ich auch mal meine Lib-Version.

Dank dir und den anderen aufs erste... (weitere Lösungsideen sind
natürlich immer willkommen ;-)

von Stefan Sczekalla (Gast)


Lesenswert?

Hallo Bernd,

also ich hab gerade das mit dem EEPROM so gemacht, wie es im wiki steht
anbei der code aus meinem ( funktionierendem )program:

#include avr/eeprom.h

#define EEPROM  _attribute_ ((section (".eeprom")))
uint16_t eeParameter[32] EEPROM;

/* ...folgnder Code liest beim booten das eeprom aus.) */

for ( i=0; i<32; i++)
{
  Parameter[i]= eeprom_read_word(&eeParameter[i]);
}

/* und so schreibe ich */

void Write( int Value, uint8_t Adr )
  {
    eeprom_write_word(&eeParameter[Adr], Value);
  }

von wann ist denn den WinAVR Paket,

Grüße,

Stefan

von Bernd Stenner (Gast)


Lesenswert?

Hallo Stefan, nur den eeprom

so in etwas habe ich es auch gemacht, doch es funktioniert nicht, weil
der Compiler
1. nur eeprom_read_block akzeptiert. Dabei funktioniert aber der
Speicherzugriff nicht, weil ich nicht die Zeichenfolge bekommen, die an
der EEProm-Adresse liegen, die ich meinte, angesprochen zu haben.
2. alle anderen eeprom_read/write Befehle bringen den Compiler zum
Abbruch (-> mein Posting vom 8.4. 3 Uhr)
Weniger schwammig kann ich das Problem, das ich bisher hatte, nicht
beschreiben.

Im Moment tut sich allerdings gar nichts mehr. Ich hatte tatsächlich
eine alte Version von avr-gcc. Ich habe mir eben WiinAVR 20050214
installiert - jetzt funktioniert garnichts mehr :-#

Es kommen die verschiedensten Fehlermeldungen, oder gleich gar keine
außer dem Hinweis, das die Compilierung fehlerhaft war. Zumeist aber
werden Parse-Errors geneldet.

Dafür funktioniert jetzt der Pfad für Includes: "avr/...". Aber das
war ja ursprünglich nicht wirklich mein Problem.

Angesichts der Tatsache, das die Installation von WinAVR außer dem
Installationspfad (habe Default gewählt) keine Optionen erfordert und
die Doku auch nicht weiterhilft, ist das schon ziemlich ärgelich.


gruß
bernd

von Bernd Stenner (Gast)


Lesenswert?

ups - entschuldigung für meine grauenvolle Rechtschreibung

von Jörg Wunsch (Gast)


Lesenswert?

Ohne ein konkretes (möglichst kleines) Beispiel und konkrete
Fehlermeldungen wird wohl niemand erraten können, was für parse errors
du hier bekommst.

von Stefan Sczekalla (Gast)


Lesenswert?

Hallo Bernd,

ich hab die Erfahrung gemacht das "Parse"-Errors in der Regel an mir
( bzw. meiner Rechtschreibung ) lagen.

... da hilft nur oben anfangen und dann durchs Programm durcharbeiten.

Grüße,

       Stefan

von Bernd Stenner (Gast)


Lesenswert?

Hätte ich auch gedacht (->"Rechtschreibfehler"), wenn es nicht
unmittelbar vor der Installation mit der alten avr-gcc noch
funktioniert hätte (die Parse-Errors beziehen sich nicht auf mein
EEPROM-Problem, sondern auf die UART-Funktionen). Mittlerweile habe ich
dies Problem aber gelöst. Es scheint so, daß nach der Installation von
WinAVR eine bestimmte Header-Datei nicht mehr richtig includiert wurde.
Habe sie jetzt an anderer Stelle im Source zusätzlich eingebunden - et
voila - keine Parse Errors mehr. Erstauntlich ist nur, das es vorher
funktioniert hat.

Da der Compiler nun weiterkommt, hat er mir jetzt kiloweise neue Fehler
gemeldet. Die Ursache für diese liegt aber in wesentlichen Unterschieden
der alten und neuen Version pgmspace.h. In der neuen fehlen einige
Makros, so das bestimmte Funktionen nicht mehr bekannt sind. In folge
dessen gibt es "implicit declaration"-Warnungen, die in der Folge
mittelbar zu Fehlern führen. Mit der alten Version lief es dagegen
einwandfrei.

Jetzt muß ich mir erstmal überlegen, wie ich die serielle Kommunikation
wieder ans laufen kriege, sonst bin ich "blind".

gruß
bernd

von Bernd Stenner (Gast)


Lesenswert?

Um genau zu sein, es handelt sich um das Testprogramm gcctest7 aus dem
gcctest-paket, das bei avr-gcc (?) dabei war...

von Jörg Wunsch (Gast)


Lesenswert?

Die Dinger sind seit Jahren ungepflegt.  Vergiss sie.

von Bernd Stenner (Gast)


Lesenswert?

das is' 'ne Ansage ;-)
Ok, dann schau ich mal, wo ich einen brauchbaren Code für die UART
finde - es sei denn jemand kann mir adhoc eine URL nennen, dann kann
ich mir das suchen sparen.

Ich habe ja die Hoffnung, das sich meine EEProm-Probleme mit der neuen
WinAVR-Version bereits behoben haben und ich es nur noch nicht weis,
weil ich die serielle Kommunikation erst wieder zu laufen kriegen muß.

ich schau dann mal - danke auf's erste

gruß
bernd

von Sebastian (Gast)


Lesenswert?

ist es egal ob "(include)" ODER <(include)>??
das hatte doch auch was mit dem pfad zu tun.
es gibt da doch ein fusebit um das löschen vom eprom beim programmieren
zu "verhindern"... nennt sich EESAVE
vielleicht hilf dir das ja

von OldBug (Gast)


Lesenswert?

#include "datei.h" -> datei.h im selben source-Dir. suchen
#include <datei.h> -> datei.h im stanard Includepfad suchen

EESAVE: hat mir der Sache gar nichts zu tun...

von Bernd Stenner (Gast)


Lesenswert?

Hallo Sebastian,

danke für den Hinweis mit dem Fuse-Bit, Jörg hatte mir den Hinweis auch
schon in einem anderen Thread gegeben, und ihr habt recht, das ist das
Problem gewesen.

ob "" oder <> hat tatsächlich was mit dem Pfad zu tun in dem der
Compiler die includes sucht. Das hatte ich bei meiner Problembehandlung
aber bereits berücksichtigt.

gruß
bernd

von Bernd Stenner (Gast)


Lesenswert?

Schön, das das Forum so gut benutzt wird, das es auch zu
überschneidungen kommt ;-)

Sebastian bezog sich wohl auf mein anfangs nebenbei geschildertes
Problem, daß mein EEProm immer gelöscht wurde, wenn ich Daten ins Flash
schrieb.

von Sebastian (Gast)


Lesenswert?

das mit dem eesave war eher zu folgendem gemeint

"Nein, es werden keine 0xFF ausgelesen, wenngleich das EEPROM ist
vollständig gelöscht ist, also mit 0xff beschrieben, außer am Anfang,
dort steht ein Probetext. Die Zeichen, die ausgelesen werden, ließen
sich nicht richtig interpretieren, da ich sie mittels UART an den PC
zur Ausgabe übertrage und somit nur das zugehörige ASCII-Zeichen sehe.
Ich habe aber inzwischen festgestellt, das PonyProg den EEProm mit den
Daten aus meinem Hex-File auch dann überschreibt, wenn ich den Befehl
"Write Program (Flash)" anwende (BTW: wie kann ich das
korrigieren?)."

soll doch heißen daß er den inhalt vom eprom nicht löschen will(beim
flashen) die aber passiert.

von OldBug (Gast)


Lesenswert?

Stimmt, hatte ich wieder verdrängt, sorry!

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
Noch kein Account? Hier anmelden.