Hallo liebe Forumgemeinde,
da es immer mal wieder Fehler beim Lesen/Schreiben ins eeprom gab, lege
ich jede eep-variable drei mal dort ab in einem Array.
Bisher habe ich jede read/update Operation einzeln hingeschrieben. Um
Speicherplatz zu sparen soll nun eine Funktion das jeweils dreimalige
updaten/lesen übernehmen.
Dabei habe ich einige Probleme. Es gibt keine Compiler Warnungen oder
Fehler, es funktioniert aber nicht...
Kann mir jemand helfen?
Mein Code:
Hallo,
also wenn der von dir gepostete Code original ist, kann ich mir nicht
vorstellen, das es keine Warnungen/Fehler vom Compiler hagelt.
Beispielsweise:
eep3ArrayReadByte(varEEP, varRAM);
eep3ArrayUpdateByte(varEEP, varRam);
Wie heißt denn die Variable? varRam oder varRAM?
Desweiteren:
void eep3ArrayReadByte(const uint8_t *eep, uint8_t write);
eep ist also ein const Pointer, dessen Wert du mehrmals änderst. Kann
mir nicht vorstellen das dein Compiler das nicht bemängelt.
Zitat:
"Dabei habe ich einige Probleme."
Das müsstest du etwas genauer beschreiben.
Danke für die Antwort.
Selbstverständlich ist das nicht 1:1 der Code, der compiliert wird. Es
fehlen die #Includes und die Funktionen werden natürlich auch nur unter
bestimmten Bedingungen aufgerufen.
Anon schrieb:> Desweiteren:> void eep3ArrayReadByte(const uint8_t *eep, uint8_t write);> eep ist also ein const Pointer, dessen Wert du mehrmals änderst. Kann> mir nicht vorstellen das dein Compiler das nicht bemängelt.
Was ich meine, ist ein konstanter Zeiger auf eine uint_8.
Genau bei den Piontern habe ich ja meine Probleme, deshalb habe ich hier
um Hilfe gebeten. Auch ohne const funktioniert der Code nicht. Ich hatte
es auf Grund der Definition von eeprom_read_byte() so gemacht
<avr/eeprom.h>.
Wie gesagt, beschreib mal was genau nicht geht, will sagen: werden die
Werte nicht geschrieben, falsch geschrieben, oder falsch gelesen etc.?
Wenn möglich, bitte immer den original code posten, da sonst eine
Fehlersuche schwierig wird, z.B. folgende Zeile:
buf_eeprom = eeprom_read_byte(eep);
Welchen Typ hat die Variable buf_eeprom?
Das nur mal generell. Die Funktionsdefinition von eeprom_update_byte
sieht übrigens so aus:
void eeprom_update_byte(uint8_t * __p, uint8_t __value);
Das heißt du benutzt die Funktion falsch. Auf deutsch heißt die
Funktionsdeklaration sinngemäß:
void eeprom_update_byte(uint8_t * zieladresse, uint8_t wert);
Ich benutze zwar kein AVR, glaube aber nicht das varEEP deine
Zieladressen enthält.
Wie gesagt, ohne den Original Code, sind meine Tipps mit Vorsicht zu
genießen.
Hier ist der Fehler ! Auf diese Art kann niemals ein Wert aus der
Funktion eep3ArrayReadByte zurueckgegeben werden. Auch der name "write"
ist in einer read Funktion irgendwie verwirrend.
Am besten macht man so etwas mittels Rueckgabewert:
1
uint_8eep3ArrayReadByte(constuint8_t*eep)
2
{
3
uint8_tbuf_eeprom=eeprom_read_byte(eep);
4
if(buf_eeprom==0xff)//prüfen auf fehler
5
{
6
buf_eeprom=eeprom_read_byte(eep+1);
7
if(buf_eeprom==0xff)//prüfen auf fehler
8
{
9
buf_eeprom=eeprom_read_byte(eep+2);
10
}
11
}
12
returnbuf_eeprom;
13
}
Noch eine Bitte: immer Original-Code posten, mit Copy+Paste, durch das
Abtippen enstehen neue Fehler, und man weiss nicht wirklich, welche
Fehler Tippfehler sind und welche echt !
Anon schrieb:> eep ist also ein const Pointer, dessen Wert du mehrmals änderst.
Wo wird hier der Wert des Pointers veraendert ?
Ausserdem ist hier nicht der Pointer constant, sondern wohin gezeigt
wird.
Anon schrieb:> Das heißt du benutzt die Funktion falsch.
Das sieht mir OK aus. @Anon: Bist Du sicher dass Du weisst ueber was Du
hier redest ?
> Wo wird hier der Wert des Pointers veraendert ?> Ausserdem ist hier nicht der Pointer constant, sondern wohin gezeigt> wird.
Pointer enthalten als Wert Adressen im Speicher, a.k.a. "wohin gezeigt
wird". Sicherlich kann man Pointer dereferenzieren, aber das tut hier
nichts zur Sache. Wenn ich ich also ein ptr++ oder ptr + 2 habe ändere
ich den Wert, also das worauf gezeigt wird (effektiv die Adresse auf die
gezeigt wird). Setzen sechs.
> Anon schrieb:>> Das heißt du benutzt die Funktion falsch.>> Das sieht mir OK aus. @Anon: Bist Du sicher dass Du weisst ueber was Du> hier redest ?
Allerdings. Ich gehe davon aus das du von eep3ArrayReadByte sprichst,
ich spreche von void eeprom_update_byte(uint8_t * __p,uint8_t __value),
zu finden unter:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__eeprom_1ga63aee2719099e8435e8584d4b3e51991.html
Ich sagte zwar das meine Aussage mit Vorsicht zugenießen ist, da ich
kein AVR benutze, aber scheinbar hat atmel auch keine Ahnung wovon sie
rede.
Nachtrag für Kay S. :
> Wo wird hier der Wert des Pointers veraendert ?> Ausserdem ist hier nicht der Pointer constant, sondern wohin gezeigt> wird.
Was glaubst du was das hier ist (aus dem original Post):
void eep3ArrayReadByte(const uint8_t *eep, uint8_t write)
{
buf_eeprom = eeprom_read_byte(eep);
if (buf_eeprom == 0xff)//prüfen auf fehler
{
buf_eeprom = eeprom_read_byte(eep+1); <---- herp derp, speziell für
dich Kay (ja, es heisst oben tatsächlich const uint8_t *eep)
if (buf_eeprom == 0xff)prüfen auf fehler
{
buf_eeprom = eeprom_read_byte(eep+2);
}
}
write = buf_eeprom;
}
guest schrieb:> Kann mir jemand helfen?
Anstatt an den Symptomen rumzubasteln, könntest du auch einfach das
grundlegende Problem lösen. Stichwort "Brown out". Und schon gibt's im
Eeprom keine Fehler beim lesen und schreiben mehr.
Bei deinem Code solltest du nochmals über die beiden Zeilen nachdenken:
Anon schrieb:> Wenn ich ich also ein ptr++ oder ptr + 2 habe ändere> ich den Wert, also das worauf gezeigt wird (effektiv die Adresse auf die> gezeigt wird).
Du kennst den Unterschied zwischen
1
constuint8_t*ptr;
und
1
uint8_t*constptr;
? Offenbar nicht. Oder Du trollst.
Anon schrieb:> aber scheinbar hat atmel auch keine Ahnung wovon sie> rede.
So muss es sein. Ich denke auch dass man der Referenz Dokumentation von
Atmel am wenigsten trauen sollte.
[/ironie]
Hallo,
vielen Dank für die Antworten!
Da das gesamte Programm sehr umfangreich ist, habe ich hier einen
lauffähigen Ausschnitt erstellt.
Tatsächlich lag das Problem in der Zeile:
1
write=buf_eeprom;
Sie wurde ersetzt durch "return". Vielen Dank für den Hinweis mit dem
"Brown out" ich werde mich mal schlau machen.
So funktioniert es nun. Vieln Dank!
Kai S.:
Es ging mir nicht um const, sondern darum, dass er sinngemäß ptr+2
schrieb, nicht *ptr+2. Damit ändert er wohin der Zeiger zeigt.
Ob der Wert auf den er zeigt const ist oder der Zeiger, ist egal. Er
inkrementiert den Zeiger.
Aber es ist schon atemberaubend wie du versuchst mir etwas zu erklären
von dem ich gar nicht spreche.
Anon schrieb:> Ob der Wert auf den er zeigt const ist oder der Zeiger, ist egal. Er> inkrementiert den Zeiger.
Das solltest Du dir noch mal genau anschauen. Sowohl der Satz vor dem
Punkt als auch der danach ist falsch.
Anon schrieb:> Aber es ist schon atemberaubend wie du versuchst mir etwas zu erklären> von dem ich gar nicht spreche.
Mit Verlaub, Du scheinst von etwas zu sprechen, das Du nicht verstehst.
Falsche Statements lassen sich nicht durch verstärkte Inbrunst beim
Vortragen zu richtigen verwandeln...
Kai S.:
Im Original Post heißt es:
uint8_t varEEP[] EEMEM = { 60, 60, 60 };
void eep3ArrayReadByte(const uint8_t *eep, uint8_t write)
{
buf_eeprom = eeprom_read_byte(eep);
if (buf_eeprom == 0xff)//prüfen auf fehler
{
buf_eeprom = eeprom_read_byte(eep+1);
if (buf_eeprom == 0xff)prüfen auf fehler
{
Usw.
Ich denke wir sind uns einig das eep ein Zeiger ist.
Was also bewirkt ein eep + 1 und was ein *eep + 1.
Du hast sogar zusätzlich diesen Satz falsch verstanden:
Ob der Wert auf den er zeigt const ist oder der Zeiger, ist egal. Er
inkrementiert den Zeiger.
Damit meinte ich egal für die Diskussion. Ich weiß wirklich nicht warum
du immer über Dinge redest um die es nicht geht.
Anon schrieb:> Er> inkrementiert den Zeiger.
Nein, tut er nicht. Inkrementieren bedeutet im allgemeinen
Sprachverständnid, daß der Wert des Zeigers verändert würde (um eins
erhöht). Das aber passiert dort nicht. Der Wert von eep ändert sich
durch den Ausdruck eep+1 nicht.
Oliver
Paul:
Anon schrieb:
> Wenn ich ich also ein ptr++ oder ptr + 2 habe ändere> ich den Wert,
ptr++ : richtig
ptr+2 : falsch
int x[5] = {};
int *ptr = &x[0];
ptr++;
ptr += 2;
Wohin zeigt ptr?
Oliver:
Der op hat einen const uint8_t *eep. Anschließend hat er eep+1, dann
eep+2. Inkrementieren heißt erhöhen,in diesem Fall die Adresse.Wenn ich
sage Wert des Zeigers meine ich die Adresse.Etwas anderes kann eine
Zeigervariable nicht enthalten. Ich habe das Gefühl mich undeutlich
auszudrücken.
+1 heißt übersetzt eep plus sizeof(datentyp). Was heißt dann wohl +2?
Nachtrag:
+1 heißt übersetzt eep plus sizeof(datentyp). Was heißt dann wohl +2?
Soll heißen:
+1 heißt übersetzt eep plus 1 * sizeof(datentyp). Was heißt dann wohl
+2?
Ist nicht leicht ohne richtige Tastatur.
Lieber Anon,
der Zeiger zeigt immer auf das erste Element des Arrays. Über +1 bzw +2
wird das nächste bzw. übernächste Element gelesen/manipuliert. Der
Zeiger selbst jedoch nicht, also darf er auch const sein.
Vielleicht verstehst du dieses Beispiel besser:
1
constuint_8ti=1;
2
uint_8tk;
3
4
k=i+1;//k = 2
5
//i = immernoch 1
der Zeiger wird genauso wenig manipuliert, wie "i" im Beispiel.
Entschuldigt, dass ich wegen dieses (etwas dummen Fehlers ;-) ) so eine
Diskussion angezettelt habe... ;-)
Anon schrieb:> Der op hat einen const uint8_t *eep. Anschließend hat er eep+1, dann> eep+2.
Ja und? Wo ist das Problem? Warum sollte der Compiler da warnen?
eep wird nicht verändert. Das, worauf eep zeigt, wird auch nicht
verändert.
Das ist etwas völlig anderes als eep++ oder eep+=2.
Oliver
Hier wird kein Pointer verändert, eep hat nach dem Funktionsaufruf immer
noch denselben Wert. Das wär' nicht mal ein Fehler, wenn eep uint8_t *
const deklariert wäre (was nicht der Fall ist).
Oliver S. schrieb:> Anon schrieb:>>> Der op hat einen const uint8_t *eep. Anschließend hat er eep+1, dann>> eep+2.>> Ja und? Wo ist das Problem? Warum sollte der Compiler da warnen?> eep wird nicht verändert. Das, worauf eep zeigt, wird auch nicht> verändert.>> Das ist etwas völlig anderes als eep++ oder eep+=2.>> Oliver
Genau.Deswegen fragte ich ja auch immer "wohin zeigt den ptr + 2".
Markus F.:
"Deine Sturheit ist tatsächlich bewundernswert ;)".
Danke, und auch das hab ich schon gesagt, ich denke ich drücke mich
unverständlich aus (siehe zwei Zeilen weiter oben). Vielleicht klappt es
jetzt:
Der Adresswert = Adresse die die Variable ptr enthält ändert sich.
Und noch ein Nachtrag.
Wenn ich sage Pointer inkrementieren meine ich "zeige bitte nicht mehr
auf das erste Element, sondern auf das zweite, dritte...".
Anon schrieb:> jetzt:> Der Adresswert = Adresse die die Variable ptr enthält ändert sich.
Also, entweder reden wir jetzt völlig aneinander vorbei, oder du
schreibst völligen Stuß. Ich tippe ja auf letzteres, aber vielleicht
schreibst du ja doch noch mal etwas ausführlicher. Was genau du
eigentlich sagen möchtest.
Oliver
Oliver S. schrieb:> Anon schrieb:>> jetzt:>> Der Adresswert = Adresse die die Variable ptr enthält ändert sich.>> Also, entweder reden wir jetzt völlig aneinander vorbei, oder du> schreibst völligen Stuß. Ich tippe ja auf letzteres, aber vielleicht> schreibst du ja doch noch mal etwas ausführlicher. Was genau du> eigentlich sagen möchtest.>> Oliver
Ersteres, leider. Was ich meine:
Wenn eine Funktion einen Zeiger auf int als Parameter nimmt,
und ich übergebe bei Aufruf der Funktion einen Zeiger auf das erste
Element eines int Arrays mit zeiger (fiktiver Adresswert 1) , dann
übergebe ich bei einem Aufruf der Funktion mit zeiger+1 einen Adresswert
von "Adresswert den ptr enthält plus 1 * sizeof (int)", also auf das
zweite Element.
Wenn ich mich jetzt nicht verständlich ausgedrückt habe, lasst es gut
sein, dann bin ich einfach zu dumm mich zu artikulieren.
Schönen Abend noch
Äh, ja, und? Natürlich ist das so.
Und das ist ja in der vom TO oben gezeigten Funktion auch so gewollt.
Was hat das jetzt mir deinen seitenlangen Diskussionen zum Thema
"Veränderung eines const-Pointers" zu tun?
Oliver
Anon schrieb:> Wenn eine Funktion einen Zeiger auf int als Parameter nimmt,> und ich übergebe bei Aufruf der Funktion einen Zeiger auf das erste> Element eines int Arrays mit zeiger (fiktiver Adresswert 1) , dann> übergebe ich bei einem Aufruf der Funktion mit zeiger+1 einen Adresswert> von "Adresswert den ptr enthält plus 1 * sizeof (int)", also auf das> zweite Element.
Stimmt.
Und der Parameter darf dann trotzdem const sein.
Schließlich änderst Du ihn nicht, sondern übergibst eine lokale,
temporäre Kopie davon um eins erhöht. Daran gibt's nix zu meckern.
Ok, jetzt aber echt mein letzter Post ;-), dann seid ihr erlöst.
Ich zitier mich mal selbst:
"Es ging mir nicht um const, sondern darum, dass er sinngemäß ptr+2
schrieb (...)". Das findet sich gaaaaanz am Anfang.
Der Rest war, wie schon 234234345647676 mal gesagt, schlecht
formuliert.Scheinbar hab ich damit meine Probleme.
Nix für ungut. Gute Nacht.
Anon schrieb:> "Es ging mir nicht um const, sondern darum, dass er sinngemäß ptr+2> schrieb (...)". Das findet sich gaaaaanz am Anfang.
Er hätte sinngemäß auch 3+2 schreiben können. Das ist ein Ausdruck, der
den Wert 5 ergibt. Die 3 bleibt dabei das, was sie ist: Eine Konstante
mit dem Wert 3.
Wir reden nicht aneinander vorbei. Nach so vielen Beiträgen von dir, die
allesamt falsch sind, ist sicher, daß dir die absoluten Basics der
Programmiersprache fehlen.
Oliver
Anon schrieb:> schlecht formuliert.Scheinbar hab ich damit meine Probleme.
Nachdem man das Maul zu voll genommen hat zurückzurudern, ohne sich
dabei lächerlich zu machen, ist - wie man ja gerade wieder mal in der
Zeitung lesen kann - eine hohe Kunst, die nicht jedem gelingt.
Du bist nicht zufällig Bayer oder gar in der CSU?