Forum: Mikrocontroller und Digitale Elektronik EEPROM beschreiben bei Spannungsausfall


von Dirk F (Gast)


Lesenswert?

Hallo,
wir haben eine Anwendung mit PIC18 mit internen EEPROM.
Hier sind Kalibrierdaten und ein 32 Bit Zähler gespeichert.
Wenn die Maschine einen Zyklus beendet hat, was ca. 3 Sekunden dauert, 
wird im RAM ein Zähler erhöht.
Wenn der RAM Zähler einen glatten Hunderter Stand erreicht, dann wird 
dieser Zählerstand ins EEPROM kopiert.
Wenn die Spannung mal ausfällt, dann fehlen u.U bis zu 100 
Maschinenzyklen, das ist aber egal.
Nach dem Einschalten wird der EEPROM Zähler geladen und ins RAM kopiert.

Problem:
Zeitweise kommt es vor, dass die Inhalte im EEPROM falsch sind. Sowohl 
Kalibrierwerte als auch der Zähler.

Ich vermute, dass es daher kommt, dass während einem Schreibvorgang die 
Spannung ausfällt.
Leider ist in der Hardware keine Schaltung verbaut, die erkennt wenn die 
Netzspannung ausfällt.

Was könnte man machen ?
3-fach im EEPROM abspeichern und dann beim Laden eine Prüfung 
durchführen ?

LG Dirk

Beitrag #5698219 wurde vom Autor gelöscht.
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Dirk F schrieb:
> Was könnte man machen ?

Ich würde erstmal den Brownout Reset aktivieren, damit der Chip bei 
Unterspannung ruhig ist und nicht mehr probiert, am EEPROM rumzufummeln.

von HyperMario (Gast)


Lesenswert?

Dirk F schrieb:
> Ich vermute, dass es daher kommt, dass während einem Schreibvorgang die
> Spannung ausfällt.

Kannst du ja testen indem du z.B. einen Zählerwert vor und nach den 
Daten wegschreibst.

Dirk F schrieb:
> 3-fach im EEPROM abspeichern und dann beim Laden eine Prüfung
> durchführen ?

damit verdreifachst du Speicherbedarf und auch das Risiko. Würde eher 
die Daten prüfen und noch ein "Daten geprüft und Ok" Flag danach ins 
EEprom schreiben.

von r c (Gast)


Lesenswert?

HyperMario schrieb:
> Würde eher
> die Daten prüfen und noch ein "Daten geprüft und Ok" Flag danach ins
> EEprom schreiben.

... Allerdings natürlich nicht nur ein einzelnes Bit, das ist ja dann 
wieder in 50% der Fälle falsch.

von georg (Gast)


Lesenswert?

Dirk F schrieb:
> Was könnte man machen ?

Erstmal dafür sorgen, dass der letzte gute Wert im EEPROM nicht 
überschrieben wird: den Daten eine laufende Nummer und eine Prüfsumme 
anfügen und mindestens in 2 Speicherbereiche abwechselnd schreiben. Wird 
beim Schreiben ein Datensatz durch Absturz oder Stromausfall 
zerknatscht, kann man noch den anderen nehmen.

Sind mal beide kaputt hast du ein anderes und viel ernsteres Problem.

Georg

von Dirk F (Gast)


Lesenswert?

Matthias S. schrieb:
> Ich würde erstmal den Brownout Reset aktivieren, damit der Chip bei
> Unterspannung ruhig ist und nicht mehr probiert, am EEPROM rumzufummeln.

Habe den Brownout aktiviert.
Der PIC wird normal mit 3,3 V versorgt.
BOR steht auf 1,8 V.  Andere Einstellmöglichkeiten sind 2.2V, 2.7V und 
3.0V.
Sollte ich hier den Wert erhöhen ?

Den Tip mit Prüfsumme und auf 2 Stellen speichern finde ich gut.

von Joachim B. (jar)


Lesenswert?

Dirk F schrieb:
> BOR steht auf 1,8 V.  Andere Einstellmöglichkeiten sind 2.2V, 2.7V und
> 3.0V.
> Sollte ich hier den Wert erhöhen ?

steht im DB unter EEPROM schreiben

von Dirk F (Gast)


Lesenswert?

Joachim B. schrieb:
> steht im DB unter EEPROM schreiben

PIC18F46K20:
Da steht 1.8V (Min)  und 3.6 V (Max)

von Joachim B. (jar)


Lesenswert?

Dirk F schrieb:
> Der PIC wird normal mit 3,3 V versorgt.
> BOR steht auf 1,8 V.

1,8V ist ja nicht garantiert, wenns nicht klappt also erhöhen

min 1,8V kann man so & so verstehen und

Using EECON to read/write

beachten, was immer das heissen mag, kenne PIC nicht.

von Dirk F (Gast)


Lesenswert?

Joachim B. schrieb:
> 1,8V ist ja nicht garantiert,

Wieso, wenns im Datenblatt steht, dann ist es garantiert.

> Using EECON to read/write

Das ist die normale Art, das interne EEPROM währen dem Betrieb 
anzusprechhen, also nicht übers Programmiergerät.

von Joachim B. (jar)


Lesenswert?

Dirk F schrieb:
> Wieso, wenns im Datenblatt steht, dann ist es garantiert.

na denn....... :)))

(ich hatte zwar schon öfter falsche Datenblattangaben, aber glauben darf 
man alles hier im Lande, es gibt ja Religionsfreiheit)

von Matthias X. (current_user)


Lesenswert?

Schreibst du auch die Kalibrierwerte wenn du deinen Zähler schreibst?
Wenn nicht, dann bedeutet das, dass auch Bytes beschädigt werden auf die 
nicht zu gegriffen wurde. Das passiert z.B. wenn die der Eeprom intern 
Page basierend arbeitet. D.h. auch wenn du nur ein Byte änderst wird 
intern die gesamte Pages (z.B. 128 Bytes) neu geschrieben.
Wenn das so ist, dann wird es dir auch nichts helfen wenn du den Zähler 
an mehreren benachbarten Positionen speicherst. Im Fehlerfall wäre die 
gesamte Page reiner Zufall. In dem Fall müsstest du den Zähler auf 
mehrere Pages verteilen und auch die Kalibrierdaten müssen auf eine 
separate Page.

Hast du die Möglichkeit die Versorgungsspannung z.B. durch einen 
Komparator zu überwachen? Dann würde ich bei 3,0V ein Interrupt auslösen 
und den Prozessor in den Sleep legen. So verringerst du den Strombedarf 
des Prozessors wodurch im Fehlerfall die Spannung langsamer 
zusammenbricht. Das gibt die vielleicht ein paar Millisekunden sodass 
der Eepromzugriff intern noch beendet werden kann.

von Joachim B. (jar)


Lesenswert?


von Dirk F (Gast)


Lesenswert?

Matthias X. schrieb:
> Schreibst du auch die Kalibrierwerte wenn du deinen Zähler schreibst?

Hallo. Im Normalbetrieb wird nur der Zähler geschrieben.
Kalibrierdaten nur einmalig im Werk.

Das mit den Pages ist ist ne Idee.
Aber ist das nicht nur im Flash Speicher so, dass die gesamte page 
gelöscht wird ?
IM EEPROM kann man doch byteweise löschen und dann schreiben ?

von fchk (Gast)


Lesenswert?

Dirk F schrieb:
> Matthias X. schrieb:
>> Schreibst du auch die Kalibrierwerte wenn du deinen Zähler schreibst?
>
> Hallo. Im Normalbetrieb wird nur der Zähler geschrieben.
> Kalibrierdaten nur einmalig im Werk.
>
> Das mit den Pages ist ist ne Idee.
> Aber ist das nicht nur im Flash Speicher so, dass die gesamte page
> gelöscht wird ?
> IM EEPROM kann man doch byteweise löschen und dann schreiben ?

Ja, kann man. Intern ist das EEPROM aber ebenfalls blockweise aufgebaut. 
Beim Schreiben wird ein Block (Page) in einen Puffer geladen, geändert 
und wieder zurückgeschrieben. Da geschieht viel in Hardware. Dadurch 
können bei einem Schreibfehler auch andere Bytes der gleichen Page 
beschädigt werden.

Vorschlag 1:
Kalibrierdaten in der letzten Page des Flash speichern. Damit sind diese 
Daten erstmal in Sicherheit, denn das Flash wird ja im Betrieb nicht 
geschrieben.

Vorschlag 2:
Ich gehe mal davon aus, dass Du im Flash nicht mehr als 256 Bytes 
brauchst. Dann teile Dein EEPROM in 4 256 Byte Blöcke auf, und schreibe 
reihum immer in einen anderen Block. Das verteilt die Schreibzugriffe, 
Dein EEPROM wird länger leben, und im Fehlerfall sollte nur ein Block 
betroffen sein. Jeder Block hat natürlich eine Prüfsumme, um Fehler zu 
erkennen. Beim Starten suchst Du Dir einfach den Block mit dem höchsten 
Zählerstand bei korrekter Prüfsumme aus.

Vorschlag 3:
BOR hochsetzen und nach einem Reset in RCON nachschauen, ob Reset durch 
BOR verursacht wurde. Wenn ja, dann internes RAM prüfen (Prüfsumme!) und 
EEPROM prüfen und ggf. den letzten, defekten Block löschen.

fchk

von Wolfgang (Gast)


Lesenswert?

Dirk F schrieb:
> Wenn die Spannung mal ausfällt, dann fehlen u.U bis zu 100
> Maschinenzyklen, das ist aber egal.

Warum wird der Spannungsausfall nicht detektiert, bevor er beim µC 
ankommt. Dann könnte man jegliche EEPROM-Aktivität sicher abschließen, 
bevor dem µC die Luft aus geht.

von Dirk F (Gast)


Lesenswert?

Wolfgang schrieb:
> Warum wird der Spannungsausfall nicht detektiert, bevor er beim µC
> ankommt. Dann könnte man jegliche EEPROM-Aktivität sicher abschließen,
> bevor dem µC die Luft aus geht.

Ja, aber die Hardware ist hierfür leider nicht vorhanden.
Einige 1000 Geräte schon geliefert.....

von A. S. (Gast)


Lesenswert?

Also zusammengefasst:

 * Fürs Ausschalten alle möglichen Quellen auf Tauglichkeit untersuchen 
(vielleicht messt ihr die Versorgungsspannung oder habt ein Signal, was 
indirekt darauf schließen lässt)
 * Blockgröße Deines EEPROMS kennen und beachten (Konsistenzen immer 
innerhalb von Blöcken sicherstellen)
 * 3 Blöcke zur Sicherung vorhalten:

 Block 0: Hier schreibst Du den neuen Blockinhalt rein
 Block 1: Hier schreibst Du die Nummer des zu schreibenden Blocks rein
 Block 2: Kopie von 1
 Block x: löschen
 Block x: diesen nun wie Block 0 beschreiben
 Block 2: löschen
 Block 1: löschen
 Block 0: löschen

Beim Aufstarten checkst Du, ob Block 1/2 noch ein unfertiger 
Schreibzugriff geloggt ist und beendest ihn ggf. . Block 2 ist 
notwendig, da Block 1 auch müll enthalten kann

von MWS (Gast)


Lesenswert?

Wenn bei Netzausfall die Spannung am uC nicht abrupt, sondern im Rahmen 
von z.B. 100-200ms linear abfällt, dann könnte man vor einem Schreiben 
des EEProms eine Messung per ADC machen und nur bei genügend Spannung 
den Schreibvorgang ausführen. Benötigt würde ein nicht verwendeter 
ADC-Pin den man per Pullup auf VCC zieht und mit interner Referenz 
misst.

von Dirk F (Gast)


Lesenswert?

MWS schrieb:
> Wenn bei Netzausfall die Spannung am uC nicht abrupt, sondern im Rahmen
> von z.B. 100-200ms linear abfällt, dann könnte man vor einem Schreiben
> des EEProms eine Messung per ADC machen und nur bei genügend Spannung
> den Schreibvorgang ausführen. Benötigt würde ein nicht verwendeter
> ADC-Pin den man per Pullup auf VCC zieht und mit interner Referenz
> misst.

Auch hierfür muß die Hardware modifiziert werden. Scheidet erst mal aus.
Ich suche die beste Lösung per Software für ein Firmwareupdate.

fchk schrieb:
> Ja, kann man. Intern ist das EEPROM aber ebenfalls blockweise aufgebaut.
> Beim Schreiben wird ein Block (Page) in einen Puffer geladen, geändert
> und wieder zurückgeschrieben. Da geschieht viel in Hardware. Dadurch
> können bei einem Schreibfehler auch andere Bytes der gleichen Page
> beschädigt werden.

Im Datenblatt des PIC18F ist keine Blockgröße angegeben.
Also fraglich, ob bei MC die EEPROMS wirklich in Blöcke aufgeteilt sind.

von Dirk F (Gast)


Lesenswert?

fchk schrieb:
> Vorschlag 2:
> Ich gehe mal davon aus, dass Du im Flash nicht mehr als 256 Bytes
> brauchst. Dann teile Dein EEPROM in 4 256 Byte Blöcke auf, und schreibe
> reihum immer in einen anderen Block. Das verteilt die Schreibzugriffe,
> Dein EEPROM wird länger leben, und im Fehlerfall sollte nur ein Block
> betroffen sein. Jeder Block hat natürlich eine Prüfsumme, um Fehler zu
> erkennen. Beim Starten suchst Du Dir einfach den Block mit dem höchsten
> Zählerstand bei korrekter Prüfsumme aus.

Sehr guter Vorschlag.
Aktuell sind meine Daten im EEPROM wie folgt organisiert:

0-95 Kalibrierdaten
100...103 Taktzähler
...117  Sonstiges. z.B Passwort

Ab 512:
Backup von den o.g. Daten, um ein Reset zu Factory Default zu machen.

Bleibt also zu klären, ob das interne EEPROM wirklich blockweise oder 
Byteweise gelöscht wird.

Danke für bisherige Tipps.

von HyperMario (Gast)


Lesenswert?

Dirk F schrieb:
> Auch hierfür muß die Hardware modifiziert werden.

Vielleicht hilft es ja:

22.0 HIGH/LOW-VOLTAGE DETECT (HLVD)

PIC18F2XK20/4XK20 devices have a High/Low-Voltage
Detect module (HLVD). This is a programmable circuit
that allows the user to specify both a device voltage trip
point and the direction of change from that point

von Dirk F (Gast)


Lesenswert?

HyperMario schrieb:
> Vielleicht hilft es ja:
>
> 22.0 HIGH/LOW-VOLTAGE DETECT (HLVD)

Hi MArio,
sehr guter Hinweis.
So wie ich das Datenblatt verstehe,
kann man die Betriebsspannung der MCU ohne externe Beschaltung gegen 
eine interne Referenz vergleichen.
Schaltpunkt in 16 Stufen einstellbar.

Messe gleich mal mit dem Oszi, wie langsam die MCU Spannunng bei 
Netzausfall abfällt.
Ob die Zeit reicht, einen begonnen Schreibvorgang zu vollenden.

von HyperMario (Gast)


Lesenswert?

Dirk F schrieb:
> So wie ich das Datenblatt verstehe,
> kann man die Betriebsspannung der MCU ohne externe Beschaltung gegen
> eine interne Referenz vergleichen.

Hab das selber nicht getestet, so ist es aber gedacht.

> Messe gleich mal mit dem Oszi, wie langsam die MCU Spannunng bei
> Netzausfall abfällt.

Würde mich interessieren, inkl, Kapazität vom (falls vorhanden) 
Siebelko.

von Dirk F (Gast)


Lesenswert?

Also habe mir eben den Code nochmal angeschaut.
Immer wenn der Zähler die 100er Grenze erreicht, dann spreichere ich den 
kompletten Datensatz (117 Byte) im EEPROM ab.
Das dauert ca. 500 ms.

Werde den Code ändern, dass nur die 4 Byte des Zählers abgespeichert 
werden.

Durch die wesentlich kürzere Speicherzeit (ca. 20 ms) ist die 
Wahrscheinlichkeit dass dann ein Spromausfall auftritt um das 32-fache 
geringer......

Als erste Maßnahme....

von chris (Gast)


Lesenswert?

Dirk F schrieb:
> Durch die wesentlich kürzere Speicherzeit (ca. 20 ms) ist die
> Wahrscheinlichkeit dass dann ein Spromausfall auftritt um das 32-fache
> geringer......

Ich habe das bei meinem Betriebsstundenzähler so gelöst, dass ich in 
einen Ringpuffer im EEPROM schreibe. Also z.B. 10x4 Byte für 10 
Datensätze.
Nach dem Starten sucht der µC dann in diesen 10 Plätzen den größten Wert 
und prüft außerdem, ob dieser Wert = Vorgängerwert + 1 ist.
Dadurch kann ein korrupter Wert verworfen werden.

von georg (Gast)


Lesenswert?

chris schrieb:
> Ich habe das bei meinem Betriebsstundenzähler so gelöst, dass ich in
> einen Ringpuffer im EEPROM schreibe

Ich habe schon in der 5. Antwort vorgeschlagen mindestens einen 
doppelten Buffer zu verwenden und die Werte abzusichern, du bist jetzt 
der dritte, wenn ich nichts übersehen habe. Wir wissen dass das 
funktioniert (mache ich seit mehr als 30 Jahren so), aber offensichtlich 
mag der TO so eine Lösung nicht. Da er nicht mal drauf eingeht hat er es 
wahrscheinlich überhaupt nicht verstanden. Da kann man halt nichts 
machen, Ende der Beteiligung.

Georg

von Willi S. (ws1955)


Lesenswert?

georg schrieb:
> chris schrieb:
>> Ich habe das bei meinem Betriebsstundenzähler so gelöst, dass ich in
>> einen Ringpuffer im EEPROM schreibe
>
> Ich habe schon in der 5. Antwort vorgeschlagen mindestens einen
> doppelten Buffer zu verwenden und die Werte abzusichern, du bist jetzt
> der dritte, wenn ich nichts übersehen habe. Wir wissen dass das
> funktioniert (mache ich seit mehr als 30 Jahren so), aber offensichtlich
> mag der TO so eine Lösung nicht. Da er nicht mal drauf eingeht hat er es
> wahrscheinlich überhaupt nicht verstanden. Da kann man halt nichts
> machen, Ende der Beteiligung.
>
> Georg

LESEN ist generell keine Stärke der Beteiligten, sonst wäre der Thread 
mindestens 4/5 kürzer. Zum Glück gibt es in unserem Portfolio kein 
einziges Modul, welches nicht mindestens die (primäre) 
Versorgungsspannung misst.

Neben Eeprom gibt es ja auch noch viele andere Erfordernisse, die einen 
geregelten Shutdown erfordern, oft auch Themen der Betriebssicherheit.

Aber richtig:
Mit einer Absicherung der Daten geht es beim Eeprom auch, nur eben mit 
höherem Software-Aufwand. Idealerweise räumt man die Schrottdaten beim 
nächsten Booten auf, damit spart man sich eine Verkomplizierung im 
anschließenden Betrieb.

: Bearbeitet durch User
von my2ct (Gast)


Lesenswert?

Dirk F schrieb:
> Ja, aber die Hardware ist hierfür leider nicht vorhanden.
> Einige 1000 Geräte schon geliefert.....

Broken by Design

von MWS (Gast)


Lesenswert?

Dirk F schrieb:
> Auch hierfür muß die Hardware modifiziert werden. Scheidet erst mal aus.

Für das Setzen eines internen Pullups und Verwendung des ADC muss keine 
Hardware geändert werden.
Falls die Versorgungsspannung intern zu messen ist, umso besser.
Aber wenigstens scheinst Du die Idee verstanden zu haben.

Dirk F schrieb:
> Durch die wesentlich kürzere Speicherzeit (ca. 20 ms) ist die
> Wahrscheinlichkeit dass dann ein Spromausfall auftritt um das 32-fache
> geringer......

Wenn Du das jetzt mit einer vorherigen Prüfung der Versorgung 
verbindest, dann hast Du tatsächlich etwas erreicht, nämlich eine 
Problemlösung, die ich Dir mit meinem Vorschlag nahelegte.

Wird jetzt noch der Spannungsverlauf oszillographiert und festgestellt, 
dass z.B. 100ms zum Schreiben bleibt, dann kannst Du sogar sicher sein, 
das nichts mehr passiert.

Dann musst Du nicht lediglich die Wahrscheinlichkeit verringern, bis 
Dein Murks ausfällt.

von Dirk F (Gast)


Angehängte Dateien:

Lesenswert?

fchk schrieb:
> Ja, kann man. Intern ist das EEPROM aber ebenfalls blockweise aufgebaut.
> Beim Schreiben wird ein Block (Page) in einen Puffer geladen, geändert
> und wieder zurückgeschrieben. Da geschieht viel in Hardware. Dadurch
> können bei einem Schreibfehler auch andere Bytes der gleichen Page
> beschädigt werden.

Habe das Problem auch mal im Microchip Forum gestellt.
Die Antwort war, dass das interne EEPROM des PIC18 nicht in Pages 
aufgeteilt ist, sondern Byteweise.

MWS schrieb:
> Wird jetzt noch der Spannungsverlauf oszillographiert und festgestellt,
> dass z.B. 100ms zum Schreiben bleibt, dann kannst Du sogar sicher sein,
> das nichts mehr passiert.

Habe ich gemacht.
600 ms nachdem die Netzspannung ausfällt passiert folgendes mit der 
Versorgungsspannung des PIC:  Anlage

Es bleiben weniger als 10 ms von Erkennung bis zum BOR übrig.
Zu wenig um das EEPROM zu beschreiben.

von Sascha W. (sascha-w)


Lesenswert?

Dirk F schrieb:
> 600 ms nachdem die Netzspannung ausfällt passiert folgendes mit der
> Versorgungsspannung des PIC:  Anlage
>
> Es bleiben weniger als 10 ms von Erkennung bis zum BOR übrig.
> Zu wenig um das EEPROM zu beschreiben.
Dann musst du die Spannung vor dem 3.3V Regler messen um den Ausfall 
rechtzeitig zu erkennen.

Tja das ist der Punkt wo auch in anderen kommerziellen Geräten mal noch 
irgendwo ein Draht reingelötet wird.

Sascha

von Dirk F (Gast)


Lesenswert?

Sascha W. schrieb:
> Dann musst du die Spannung vor dem 3.3V Regler messen um den Ausfall
> rechtzeitig zu erkennen.
>
> Tja das ist der Punkt wo auch in anderen kommerziellen Geräten mal noch
> irgendwo ein Draht reingelötet wird.

Ist leider mit einer Drahtbrücke alleine nicht getan.
Mindesetens ein Spannungsteiler aus 2 Widerständen müsste dann noch 
rein.

LG Dirk

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.