Moin Zusammen,
ich hab ein Problem, was ich nicht ganz nachvollziehen kann.
Ich habe eine struct wo verschiedene Einstellungen für einen
Schrittmotor abgelegt sind. Diese sollen auch im EEPROM abgelegt werden.
1
stepperSettingstepperSetXYZ[2]={0};
2
stepperSettingeestepperSetXYZ[2]EEMEM={0};
Der einzige Zugriff auf eestepperSetXYZ[2] erfolgt mit:
Nun ist mein Problem, dass die Daten nicht geschrieben/gelesen werden.
Beim debuggen ist mir aufgefallen, dass beim Anhalten vom uC und dem
schreiben eines Wertes (egal ob data oder eeprom), der Wert sich sofort
auch in den anderen Speicher überträgt. (Siehe beigefügtes Bild, es
wurde nur eine 55 per Hand gesetzt.) Das ganze ist nicht so schön, wo
kann diese Verknüpfung herkommen?
Gruß Justus
Justus Jonas schrieb:> Diese sollen auch im EEPROM abgelegt werden.
In welchem EEPROM? Was machen die Funktionen eeprom_read_block() und
eeprom_update_block()?
Justus Jonas schrieb:> void readSetandInitStepper(){> cli();> eeprom_read_block(&stepperSetXYZ, &eestepperSetXYZ,> sizeof(stepperSetXYZ));> sei();> }> void writeStepperSettingstoEEPROM(){> cli();> eeprom_update_block(&stepperSetXYZ, &eestepperSetXYZ,> sizeof(stepperSetXYZ));> sei();> }
eehm, du sagts eeprom read aber gibts als parameter die Speicheraddresse
der normalen Variable, und nicht der "eestepperSetXYZ"
Ist das so beabsichtigt?
Justus Jonas schrieb:> Ich habe eine struct wo verschiedene Einstellungen für einen> Schrittmotor abgelegt sind. Diese sollen auch im EEPROM abgelegt werden.
Schön für dich, daß du eine struct hast.
Aber wo ist der Treiber, der den EEPROM betreibt? Und was für ein EEPROM
ist das? ein interner in deinem Controller? oder ein externer über SPI
oder I2C?
In beiden Fällen solltest du erstmal nachlesen, wie der EEPROM zu
behandeln ist. Und dem EEPROM ist es im Grunde auch egal, ob du eine
struct hast oder nicht, der funktioniert zumeist stur auf Byte-Basis.
Also Adresse angeben, beim Schreiben Byte angeben, dann Schreibfunktion
auslösen. All dieser Kleinkram ist das, was der Treiber erledigen muß.
Bei µC, die einen Teil des Programm-Flashs als EEPROM-Ersatz benutzen,
geht das zwar anders, braucht aber auch nen Treiber, der die benötigten
Lösch- und Schreibarbeiten durchführt.
W.S.
W.S. schrieb:> **Viele Worte um nichts!**
Offensichtlich ist dreht es sich hier um AVR.
Genutzt wird die beim AVR-Gcc mitgelieferte eeprom.h
(aber das kannst du ja nicht erkennen, vermutlich falsche Brille auf)
Hier ist schon mal ein fetter Bock gefunden:
Anselm schrieb:> du sagts eeprom read aber gibts als parameter die Speicheraddresse> der normalen Variable
Und ja, der Programmtext ist bis zur Untestbarkeit verstümmelt.
Schade eigentlich.....
Moin,
es handelt sich um einen Atmega2560 und die eeprom.h
Ich übergebe Speicheradresse im eeprom und die Speicheradresse im ram.
Die Anordnung ist bei read und update/Write getauscht. Also read(&src,
&dest, size)
update(&dest, &src, size).
Ich wundere mich einfach sehr, dass sich im angehaltenen Zustand des uC
der Inhalt vom eeprom ändert, wenn ich den RAM beeinflusse.
Gruß
Justus Jonas schrieb:> Ich übergebe Speicheradresse im eeprom und die Speicheradresse im ram.
Ich finde seltsam, dass beide Variablen im Debugger auf der gleichen
Adresse 0x02cb liegen. Das kann doch nicht richtig sein. Die Adressen
vom EEPROM beginnen nämlich bei 0x0000.
Kontrolliere mal, ob EEMEM überhaupt richtig gesetzt ist.
Zum Beispiel so:
1
#define XSTR(x) STR(x)
2
#define STR(x) #x
3
#pragma message "EEMEM is: " XSTR(EEMEM)
Du solltest dann beim Compilieren eine entsprechende Ausgabe erhalten.
Justus Jonas schrieb:> Die Anordnung ist bei read und update/Write getauscht.
Da hast du war!
(sieht zumindest in der Doku so aus)
Übrigens:
Ich habe die beiden Funktionen mal versucht zu testen.
Das zerrüttet offensichtlich den Speicher.
Fehlfunktionen, als ob Speicher versehentlich überschreiben wird.
Arduino kennt die äquivalenten Methoden EEPROM.put() und get().
Die funktionieren dagegen prächtig.
Gut, kann mein Bug sein.
Aber zum Ausgleich sehe ich in nicht.
Wie auch immer: Meine Tests waren unbefriedigend.
Und ein unverstümmeltes (original) Testprogramm dürfen wir/ich weiterhin
nicht erhalten
EAF schrieb:>> Die Anordnung ist bei read und update/Write getauscht.> Da hast du war! (sieht zumindest in der Doku so aus)
Sehe ich anders.
Justus Jonas schrieb:> eeprom_read_block(&stepperSetXYZ, &eestepperSetXYZ,> eeprom_update_block(&stepperSetXYZ, &eestepperSetXYZ,https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
sagt:
> eeprom_read_block (void *__dst, const void *__src, size_t __n)> eeprom_update_block (const void *__src, void *__dst, size_t __n)
Das passt doch!
EAF schrieb:> Ich habe die beiden Funktionen mal versucht zu testen.> Das zerrüttet offensichtlich den Speicher.> Fehlfunktionen, als ob Speicher versehentlich überschreiben wird.
Ich habe die Funktionen schon oft benutzt, sie haben immer funktioniert.
Es wäre auch mehr als seltsam, wenn so ein Bug in weit über 10 Jahren
nicht behoben worden wäre.
Hi,
>Ich finde seltsam, dass beide Variablen im Debugger auf der gleichen>Adresse 0x02cb liegen. Das kann doch nicht richtig sein. Die Adressen>vom EEPROM beginnen nämlich bei 0x0000.
die Adresse ist zwar etwas ungewöhnlich, mache ich aber auch manchmal
wenn ich Ram zum EEProm spiegle. Dann aber meistens ab $60 oder $100 je
nach dem wo Ram beginnt. Die Adresse ist dann einfach die selbe.
viel Erfolg, Uwe
Stefan F. schrieb:> Sehe ich anders.Stefan F. schrieb:> Das passt doch!
Du widersprichst dich selber.
src und dest sind in der Signatur vertauscht.
Aber alles gut, das wird schon wieder...
Uwe schrieb:> die Adresse ist zwar etwas ungewöhnlich, mache ich aber auch manchmal> wenn ich Ram zum EEProm spiegle.
Da war das Absicht. Hier hat er das aber nicht so programmiert, sondern
lässt die Adresse von der Toolchain vorgeben. Und die beginnt bei
0x0000.
Test:
Ich habe da ein paar Kommentare eingefügt.
Interessanterweise hat er die drei Variablen im EEPROM in rückwärts
Reihenfolge angelegt. Aber was ich hier eigentlich zeigen wollte sieht
man sehr gut: Dass er den Anfang des EEPROM belegt hat, nicht irgendwo
die Mitte an Adresse 0x02cb wie beim TO.
Moin,
Stefan F. schrieb:> Ich finde seltsam, dass beide Variablen im Debugger auf der gleichen> Adresse 0x02cb liegen. Das kann doch nicht richtig sein. Die Adressen> vom EEPROM beginnen nämlich bei 0x0000.
Siehe Bilder
Ich habe jetzt mal vor dem write und dahinter angehalten.
Vor dem Write ist die EEPROM Adresse 0x0000 und danach wird sie neu
gesetzt, in meinem Kopf ist gerade nur die Frage: "Was geschieht denn
hier?"
Habt ihr noch eine Idee?
Justus Jonas schrieb:> Siehe Bilder
Ich kappiere nicht, wieso sich die Adressen der Speicherplätze während
des Programmablaufes ändern. Achte auf die Adressen hinter dem @
Zeichen. Das bedeutet doch "Adresse", oder nicht?
Kann es sein, dass der Debugger einen Bug hat?
Moin,
nein es funktioniert ja auch nicht, daher debugge ich überhaupt.
Ich habe noch ein Array aus ints welches ich auf die gleiche Art
wegspeichere mit update und read block. Da funktioniert alles super.
Vllt kommt die Funktion mit der struct nicht klar...
Gruß Hannes
Ach ich habs! Du musst die & Zeichen weg nehmen. Das sind Arrays, und
Namen von Arrays sind bereits Zeiger auf den Beginn der Daten!
Was du der eeprom_update_block() Funktion hier effektiv übergibst sind
Zeiger auf Zeiger auf Daten. Dafür sind die Funktionen nicht ausgelegt.
Sie braucht Zeiger auf Daten (also deren Adressen).
Auch ohne die & besteht das Problem weiterhin leider.
Kann der Inhalt der struct ein Problem sein?
Ich habe 2 float variablen in der struct.
Gruß Jonas
Moin,
ich verstehe es immer weniger.
Bild Nr. 3:
eestepperSetXYZ wird 3 mal im Projekt genutzt. Einmal beim deklarieren
und zweimal beim update/read.
Bild Nr. 4: Beim initialisieren von Werten sollte nichts passieren
Bild Nr. 5: Zack in *eestepperSetXYZ[0].maxCurrentx100mA wird eine 173
reingeschrieben???
Warum wird plötzlich was in den EEPROM Speicher Bereich geschrieben?
Verstehe die Welt nicht mehr.
Gruß Hannes
Justus Jonas schrieb:> Warum wird plötzlich was in den EEPROM Speicher Bereich geschrieben?
Weil du die & Zeichen entfernt hast und damit der eeprom Funktion nun
korrekte Adressen auf die Speicherbereiche übergibst.
Die Sternchen in den anderen Screenshot sind genau so falsch wie vorher
die & Zeichen.
Schalte alle Warnungen des Compilers ein (Option-Wall), der compiliert
deinen Code dann bestimmt nicht ohne entsprechende Hinweise. Eigentlich
hätte auch der Editor deiner IDE Warnmeldungen anzeigen müssen. Was ist
denn das für eine dumme IDE?
Liest dich ein, wie man in C auf Arrays zugreift und wie man sie an
Funktionen übergibt, und wie man Zeiger verwendet.
https://openbook.rheinwerk-verlag.de/c_von_a_bis_z/011_c_arrays_001.htmhttps://openbook.rheinwerk-verlag.de/c_von_a_bis_z/012_c_zeiger_001.htm
Justus Jonas schrieb:> Das scheint schon mal nicht so gut zu funktionieren.
Natürlich nicht, wohin zeigen die Pointer denn? Wo ist der Code, der für
die Daten Speicherplatz reserviert und die Pointer darauf zeigen lässt?
> Aber die Seiteneffekte kann ich mir trotzdem überhaupt nicht herleiten.
Wenn du über nicht initialisierte Pointer auf irgendwelchen
undefinierten Speicher zugreifst, kann alles passieren. Über das mal
lieber gründlich auf einem PC. Meistens werden solche Programme mit
einem Speicherzugriffsfehler (Segmentation fault) abgebrochen.
Mikrocontroller haben diese Kontrolle jedoch nicht. Die machen dann
einfach etwas unerwartetes.
In Screenshot 4.png und 5.png stimmen die Kommentare nicht mit den
Werten überein. Irreführende Kommentare sind schlimmer als gar keine!
Dein if/else hat so keinen Sinn weil in beiden Fällen das gleiche
passiert.
Justus Jonas schrieb:> Meine struct besteht hauptsächlich aus Pointern
Es ist meist eine dumme Idee, Pointer im EEPROM zu speichern.
Denn die könne bei/nach jedem Kompilieren woanders hin zeigen.
OKOK, ich bin jetzt raus.
Stefan F. schrieb:> In Screenshot 4.png und 5.png stimmen die Kommentare nicht mit den> Werten überein. Irreführende Kommentare sind schlimmer als gar keine!>> Dein if/else hat so keinen Sinn weil in beiden Fällen das gleiche> passiert.
Ich habe aktuell 0,4 Ohm und einen 5,5A Motor an dem Con Stepper, das
ist aber nicht die Serienbestückung. Das passt schon.
Stefan F. schrieb:> Justus Jonas schrieb:>> Das scheint schon mal nicht so gut zu funktionieren.>> Natürlich nicht, wohin zeigen die Pointer denn? Wo ist der Code, der für> die Daten Speicherplatz reserviert und die Pointer darauf zeigen lässt?>>> Aber die Seiteneffekte kann ich mir trotzdem überhaupt nicht herleiten.>> Wenn du über nicht initialisierte Pointer auf irgendwelchen> undefinierten Speicher zugreifst, kann alles passieren. Über das mal> lieber gründlich auf einem PC. Meistens werden solche Programme mit> einem Speicherzugriffsfehler (Segmentation fault) abgebrochen.> Mikrocontroller haben diese Kontrolle jedoch nicht. Die machen dann> einfach etwas unerwartetes.
Die Pointer sind alle auf einen Buffer gemappt und das funktioniert
auch. Die Werte werden alle initialisiert. Es funktioniert nur die
Speicherung im EEPROM nicht und dadurch auch das einlesen dieser Werte.
Wirklich!
Mir ist noch aufgefallen, dass die Adresse von stepperSetXYZ 0x02fb
lautet, die Daten aber alle davor liegen. Aber das erste Struct Element
liegt bei 0x0281 also vor der Adresse. Irgendwie unschön oder?
Justus Jonas schrieb:> Die Pointer sind alle auf einen Buffer gemappt und das funktioniert> auch. Die Werte werden alle initialisiert. Es funktioniert nur die> Speicherung im EEPROM nicht und dadurch auch das einlesen dieser Werte.> Wirklich!
Logisch. Du Speicherst Zeiger ins EEPROM, die auf Daten im RAM zeigen.
Was passiert wohl mit den Daten im RAM, wenn man neu startet?
Dieser wilde Misch-Masch aus Zeigern tut nicht einmal ansatzweise das,
was es vermutlich tun soll. Und was es tun soll ist auch nicht klar
erkennbar, so falsch sind die Fragmente des gezeigten Quelltextes.