Forum: Mikrocontroller und Digitale Elektronik eeprom_write_byte (Adresse > 255 übergeben)


von New2017 (Gast)


Lesenswert?

Hallo,

ich nutze die funktion
1
 void eeprom_write_byte (uint8_t *__p, uint8_t __value);
 aus der <avr/eeprom.h> lib und habe jetzt das Problem, dass

ich eine feste EEPROM-Adresse vorgebe die größer als 255 ist z.B.
1
 #define EE_ADR_TYPE 1001
 dabei bekomme ich eine Warnung:

"passing argument 1 of 'eeprom_write_byte' from incompatible pointer 
type".


Es funktioniert soweit aber wie bekomme ich diese Warnung weg?

von Cyblord -. (cyblord)


Lesenswert?

Du benutzt das falsch.

Du erstellst eine Variable mit dem Attribut EEMEM und deren Adresse 
übergibst du den eeprom_ funktionen. Die Variable wird nicht im Ram 
angelegt, sondern dient als Adressierung für den EEPROM und kann zur 
Generierung einer. eep Datei genutzt werden.

Ansonsten eben einen Cast einbauen. Ist aber Pfusch. Warum ist dir 
exakte Adresse wichtig? Bei Variablen im RAM ist dir die doch auch egal. 
Benutze den EEPROM in gleicher Weise.

von New2017 (Gast)


Lesenswert?

Cyblord -. schrieb:
> Du benutzt das falsch.
>
> Du erstellst eine Variable mit dem Attribut EEMEM und deren Adresse
> übergibst du den eeprom_ funktionen. Die Variable wird nicht im Ram /
> Flash angelegt, sondern dient nur als Adressierung für den EEPROM und
> kann zur Generierung einer. eep Datei genutzt werden.

wird bei EEMEM nicht eine beliebige Adresse im EEPROM belegt?

Mir ist wichtig auf die Adresse "1001" im EEPROM zu schreiben.

Ist es mit
1
 void eeprom_write_byte (uint8_t *__p, uint8_t __value);

möglich?

habe sowas versucht aber ohne Erfolg:
1
 #define EE_ADR_TYPE  (uint16_t*)1001
2
3
 eeprom_write_byte(EE_ADR_TYPE, 35);

von New2017 (Gast)


Lesenswert?

Cyblord -. schrieb:
> Ansonsten eben einen Cast einbauen. Ist aber Pfusch. Warum ist dir
> exakte Adresse wichtig? Bei Variablen im RAM ist dir die doch auch egal.
> Benutze den EEPROM in gleicher Weise.

Wichtig weil die anderen Adressen reseviert sind...

Wie caste ich das richtig?

von Cyblord -. (cyblord)


Lesenswert?

New2017 schrieb:
> Cyblord -. schrieb:
>> Ansonsten eben einen Cast einbauen. Ist aber Pfusch. Warum ist dir
>> exakte Adresse wichtig? Bei Variablen im RAM ist dir die doch auch egal.
>> Benutze den EEPROM in gleicher Weise.
>
> Wichtig weil die anderen Adressen reseviert sind...

Wenn du mit allen EEPROM Variablen und sogar ganzen Strukturen so 
verfährst legt sie dir der Compiler hintereinander ab.
Aber gut, es wird Spezialfälle für so was geben.

> Wie caste ich das richtig?

Gute Frage, evt. so was wie (uint8_t* EEMEM)

Habe ich aber noch nie gemacht. Schau dir das EEMEM Makro mal an.

Die Funktion erwartet einen Pointer auf eine Variable in dieser Art:
1
uint8_t EEMEM myEEPVariable;
2
eeprom_write_byte(&myEEPVariable,myRamVariable);

Also denke ich, das EEMEM muss da in den Cast mit rein..

von Einer K. (Gast)


Lesenswert?

New2017 schrieb:
> Wie caste ich das richtig?
1
 #define EE_ADR_TYPE  (uint8_t*)1001
2
3
 eeprom_write_byte(EE_ADR_TYPE, 35);
Und, wenn du glaubst dass das falsch ist, dann solltest du dringend, 
ganz dringend was über Zeiger lernen.

von Cyblord -. (cyblord)


Lesenswert?

Nochmal überlegt und ein (uint8_t*) Cast sollte reichen. Dein Fehler war 
der Cast auf einen uint16_t* Zeiger.

von Einer K. (Gast)


Lesenswert?

Arduino F. schrieb:
> falsch

Nachtrag:
Überlass besser dem Kompiler die Adressberechnungen.

New2017 schrieb:
> Wichtig weil die anderen Adressen reseviert sind...
Und, vor dem Kompiler hältst du "die anderen Adressen" geheim?
Welche Not treibt dich da?

von New2017 (Gast)


Lesenswert?

Cyblord -. schrieb:
> Nochmal überlegt und ein (uint8_t*) Cast sollte reichen. Dein Fehler war
> der Cast auf einen uint16_t* Zeiger.

Danke! Alle Warnungen behoben :-)

von Cyblord -. (cyblord)


Lesenswert?

New2017 schrieb:
> Cyblord -. schrieb:
>> Nochmal überlegt und ein (uint8_t*) Cast sollte reichen. Dein Fehler war
>> der Cast auf einen uint16_t* Zeiger.
>
> Danke! Alle Warnungen behoben :-)

Aber noch mal: Überdenke die ganze Vorgehensweise nochmal. So wie du das 
machst, ist das von großen Übel.

von batman (Gast)


Lesenswert?

Wieso, wenn man Strings variabler Länge im EEPROM ablegt, kennt der 
Compiler ja auch nicht jede Adresse.

von Einer K. (Gast)


Lesenswert?

Dynamische Speicher Verwaltung auf einem EEPROM...
Und das, mit Adressen in Defines, wie wir es hier vorgeführt bekommen 
haben!

Jau!
hört sich total logisch an.

von batman (Gast)


Lesenswert?

Hat bloß niemand von dynamisch geschrieben.

von Einer K. (Gast)


Lesenswert?

batman schrieb:
> Hat bloß niemand von dynamisch geschrieben.

Doch du:

batman schrieb:
> Strings variabler Länge


Vielleicht habe ich dich ja falsch verstanden:
Also, was meinst du mit "variabler Länge im EEPROM ablegen"?

von Cyblord -. (cyblord)


Lesenswert?

batman schrieb:
> Wieso, wenn man Strings variabler Länge im EEPROM ablegt, kennt der
> Compiler ja auch nicht jede Adresse.

Warum sollte man überhaupt Strings im EEPROM ablegen? Und dann noch in 
"variabler" Länge.

von batman (Gast)


Lesenswert?

Einer, der "Peter","Max","Karl-Heinz" und noch möglichst viele mehr 
nicht vergessen will.

von Einer K. (Gast)


Lesenswert?

batman schrieb:
> Einer, der "Peter","Max","Karl-Heinz" und noch möglichst viele
> mehr
> nicht vergessen will.

Es bleibt dabei!

Entweder Datensätze mit fixer Länge, oder dynamische Speicherverwaltung.
Ich sehe da erstmal keine Alternativen.

Und für die  dynamische Speicherverwaltung, muss sich er TE wohl noch 
intensiv mit Zeigern beschäftigen. So sehe ich da noch kein Land.

von Einer K. (Gast)


Lesenswert?

Cyblord -. schrieb:
> Warum sollte man überhaupt Strings im EEPROM ablegen?
Kann man tun...

Cyblord -. schrieb:
> Und dann noch in
> "variabler" Länge.
Ich habs jetzt begriffen, glaube ich...

Er meint bestimmt nicht "variabler Länge", sondern eher 
"unterschiedlicher Länge".
1
char EEMEM kurz[] = "kurz";
2
char EEMEM lang[] = "Eine lange Zeichenkette";

Aber auch da kann man dem Compiler ganz entspannt die Adressberechnung 
überlassen.

von Rolf M. (rmagnus)


Lesenswert?

Cyblord -. schrieb:
> Ansonsten eben einen Cast einbauen. Ist aber Pfusch. Warum ist dir
> exakte Adresse wichtig? Bei Variablen im RAM ist dir die doch auch egal.
> Benutze den EEPROM in gleicher Weise.

Mir wäre sie in der Regel wichtig, damit eine neue Version der Firmware 
bei einem Upgrade die schon enthaltenen Variablen wiederfindet.
In der Regel speichere ich Einstellungen im EEPROM. Die will ich aber 
bei einem Firmware-Upgrade nicht verlieren. Wenn man dem Linker die 
Zuordnung der Adressen überlässt, muss man bei jedem Upgrade den EEPROM 
löschen und die darin gespeicherten Einstellungen wieder neu vornehmen, 
weil nicht mehr garantiert ist, dass die Variablen noch an der selben 
Adresse wie in der Vorgänger-Version stehen.

von Einer K. (Gast)


Lesenswert?

Dann stopfe alles in eine Struktur.
Solange du die nicht veränderst, ist doch alles ok...

von batman (Gast)


Lesenswert?

Eine Struktur wird auch an einer Adresse gespeichert.

von Einer K. (Gast)


Lesenswert?

batman schrieb:
> Eine Struktur wird auch an einer Adresse gespeichert.
Das stimmt!
Und?

von Rolf M. (rmagnus)


Lesenswert?

Arduino F. schrieb:
> batman schrieb:
>> Eine Struktur wird auch an einer Adresse gespeichert.
> Das stimmt!
> Und?

Und auch deren Adresse wird dann vom Linker bei jedem Lauf neu 
zugeordnet, genau wie bei einzelnen Variablen. Man könnte sich natürlich 
darauf verlassen, dass der Linker sich immer dazu entscheiden wird, sie 
an Adresse 0 zu legen, aber garantiert ist das nicht, es sei denn man 
trägt das fest im Linkerskript so ein.

von Einer K. (Gast)


Lesenswert?

Fein!

Wenn man Angst hat, dass der Linker seinen Default Wert würfelt, passt 
man das make File an.

Dann ist das Thema mit "Adressen selbst merken" ja erledigt.

von batman (Gast)


Lesenswert?

Das Thema war aber "Adressen selbst festlegen".

von Einer K. (Gast)


Lesenswert?

batman schrieb:
> Das Thema war aber "Adressen selbst festlegen".
Und dafür muss man den Umgang mit Pointern erst mal lernen...

Tipp:
Gehe davon aus, dass sich viele Fragen erst daraus ergeben, dass der 
Fragesteller auf einem falschen Ast sitzt.

Soll man ihn auf seinem falschen Weg bestärken?


Und hier sieht man das daran, dass Adressen "reserviert" sind, ohne dass 
Compiler und Linker benachrichtigt werden.

Meine Vermutung:
Hier wird ein wunderschöner Automatismus ignoriert, weil er gar nicht 
bekannt ist.

von Rolf M. (rmagnus)


Lesenswert?

Arduino F. schrieb:
> Meine Vermutung:
> Hier wird ein wunderschöner Automatismus ignoriert, weil er gar nicht
> bekannt ist.

Nun gut, mag sein. Ich wollte auch nur zu verstehen geben, dass "weil er 
gar nicht bekannt ist" nicht der einzige Grund sein muss, warum man den 
Automatismus nicht nutzt.

von Cyblord -. (cyblord)


Lesenswert?

Rolf M. schrieb:

> Und auch deren Adresse wird dann vom Linker bei jedem Lauf neu
> zugeordnet, genau wie bei einzelnen Variablen. Man könnte sich natürlich
> darauf verlassen, dass der Linker sich immer dazu entscheiden wird, sie
> an Adresse 0 zu legen, aber garantiert ist das nicht, es sei denn man
> trägt das fest im Linkerskript so ein.

Wenn es wichtig ist, trägt man es halt ein. Macht man andernorts ja auch 
so. Da kommt auch niemand auf die Idee plötzlich im Programm mit 
Adressen zu hantieren anstatt mit Variablen, nur weil er einen bestimmte 
Rambereich definieren möchte. Man sagt es dem Linker und ist fertig.

Aber es ist wie immer, Speziallösungen mögen bei Experten ok sein, bei 
Anfängern deuten sie auf Unwissenheit hin und sind meist nicht nötig.

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.