Forum: Compiler & IDEs AVR-EEPROM: einfaches wear-leveling (mal wieder)


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,
ich habe einen ATmega32, bei dem ich wiederkehrend zwei 10-Bit-Werte 
speichern muß (eigentlich immer nur den letzten Stand). Die ersten 128 
Bytes des EEPROMs sind für Konfigurationsdaten reserviert, den Rest will 
ich für diese Daten nutzen. Für die Entwicklung nutze ich den AVR-GCC.

Also bietet es sich an, ein gepacktes Bitfield aus 2x10 Nutzdaten und 4 
Bit Prüfsumme oder 2x10 Nutzdaten + 8 Bit Prüfsumme zu erzeugen. 
Ersteres gibt mir 37 Wiederholungen, das zweite immerhin noch 28 
Wiederholungen. Ich kann sicherstellen, daß die Nutzdaten nie komplett 
Null sind, d.h. ich brauche kein weiteres Bit, um sicherzustellen, daß 
ein unbelegter EEPROM-Bereich als Nutzdaten gelesen wird. Für das 
EEPROM-Auslesen und Schreiben habe ich alle Zeit der Welt (fast eine 
halbe Sekunde).

Allerdings habe ich hier doch noch ein paar Fragen an die AVR-Veteranen:

 1. Es gab eine EEPROM-Operation, die keinen Verschleiß erzeugt. War es 
das auf 0x00 oder das auf 0xFF setzen? Da der "leer"-Zustand 0xFF ist, 
nehme ich letzteres an?

 2. Gibt es ein sinnvolles Prüfsummenverfahren für eine 4-Bit-Prüfsumme?

In dem Fall, das (1.) zutrifft, bietet es sich an, die Nutzdaten zu 
invertieren - in diesem Fall kann ich belegte und unbelegte Bereiche 
unterscheiden. Der "wear-leveling" Algorithmus beschränkte sich darauf, 
einfach die neuen Daten anzuhängen, wenn sie anders als der vorherige 
Inhalt sind und wenn der EEPROM voll ist, alles wieder zu löschen und 
vorn anzufangen.

Daß es eine EEPROM-Überschreib-Operation ohne Verschleiß gäbe, meine ich 
mich grob zu erinnern - kann aber die Quelle nicht mehr finden.

Viele Grüße
W.T.

von Max D. (max_d)


Lesenswert?

Das kippen der Bits von 1 auf 0 erfolgt bitweise und belastet so nur die 
einzelnen Bits. Das "zurückkippen" von 0 auf 1 erfolgt page-weise und 
belastet so jedesmal die ganze page.
Man kann beim AVR glaube ich den erase (0->1) getrennt ausführen lassen 
oder ihn automatisch in den schreibzyklus integriert lassen.

von Walter T. (nicolas)


Lesenswert?

OK, am AVR lese ich beim EEPROM im Datenblatt nichts über Paging. Heißt 
das, das Ganze EEPROM ist eine einzelne Page? Bedeutet das, daß das 
Schreiben eines einzelnen 1-Bits ins EEPROM einen ganzen 
EEPROM-Lastzuklus bedeutet?

von Peter D. (peda)


Lesenswert?

Walter T. schrieb:
> Also bietet es sich an, ein gepacktes Bitfield aus 2x10 Nutzdaten und 4
> Bit Prüfsumme oder 2x10 Nutzdaten + 8 Bit Prüfsumme zu erzeugen.
> Ersteres gibt mir 37 Wiederholungen

Also bei mir ergibt:
(1024 - 128) / 3 = 298 Datenpakete.

Nimm den Nachfolger ATmega324, da kann man getrennt löschen (0xFF) und 
schreiben. Damit kostet das als frei markieren keinen extra 
Schreibzyklus.

von Walter T. (nicolas)


Lesenswert?

Peter D. schrieb:
> Also bei mir ergibt:
> (1024 - 128) / 3 = 298 Datenpakete.

Du hast Recht. - OK, ich sollte um diese Uhrzeit keine Foren-Fragen mehr 
formulieren. Klassischer Bit-/Byte-Verwechseler.

Den ATmega324 finde ich bei meinen gängigen Lieferanten nicht im 
TQFP-Gehäuse. Den 644 hätte ich sogar noch in der Nähe meines 
Entlötwerkzeugs - am anderen Ende des Bundeslandes (und nein - es ist 
nicht Bremen). Also vorerst bin ich auf den ATmega32 angewiesen. Aber 
danke für den Tipp, daß die neueren Modelle da besser abschneiden.

Aber wenn ich jetzt gerade 8mal mehr Schreibzyklen habe, als ich eben 
überschlagen habe, ist ja auch eigentlich alles gut - mit dem Löschen 
als Extra-Schreibzyklus habe ich ja immer noch rund 15 Mio. 
Schreibzyklen - das reicht mir.

Bleibt nur die Frage nach einer 4-Bit-Prüfsumme.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@Walter Tarpan (nicolas)

>OK, am AVR lese ich beim EEPROM im Datenblatt nichts über Paging.

Das hat er aus Anwendersicht auch NICHT! Dort wird JEDES Byte einzeln 
gelöscht und programmiert! Bestenfalls per ISP kann man den EEPROM 
pageweise löschen und schreiben.

> Heißt
>das, das Ganze EEPROM ist eine einzelne Page? Bedeutet das, daß das
>Schreiben eines einzelnen 1-Bits ins EEPROM einen ganzen
>EEPROM-Lastzuklus bedeutet?

Nein.

> 1. Es gab eine EEPROM-Operation, die keinen Verschleiß erzeugt. War es
>das auf 0x00 oder das auf 0xFF setzen? Da der "leer"-Zustand 0xFF ist,
>nehme ich letzteres an?

Ja.

> 2. Gibt es ein sinnvolles Prüfsummenverfahren für eine 4-Bit-Prüfsumme?

XOR sollte reichen.

>In dem Fall, das (1.) zutrifft, bietet es sich an, die Nutzdaten zu
>invertieren

Halte ich für wenig sinnvoll.

>- in diesem Fall kann ich belegte und unbelegte Bereiche
>unterscheiden.

Kann man auch so, wenn deine Daten + Prüfsumme nie komplett 0xFF sind.

> Der "wear-leveling" Algorithmus beschränkte sich darauf,
>einfach die neuen Daten anzuhängen, wenn sie anders als der vorherige
>Inhalt sind und wenn der EEPROM voll ist, alles wieder zu löschen und
>vorn anzufangen.

Vollkommen OK.

von Axel S. (a-za-z0-9)


Lesenswert?

Walter T. schrieb:
> Bleibt nur die Frage nach einer 4-Bit-Prüfsumme.

Mach eine 5 Bit Prüfsumme. Deine Nutzdaten sind 2x 10 Bit = 4x 5 Bit.
Die kannst du z.B. direkt XORen und kriegst wieder 5 Bit raus.
Bei 4 Worten sollte diese einfache Summe reichen.

von Falk B. (falk)


Lesenswert?

@ Axel Schwenke (a-za-z0-9)

>Mach eine 5 Bit Prüfsumme. Deine Nutzdaten sind 2x 10 Bit = 4x 5 Bit.
>Die kannst du z.B. direkt XORen und kriegst wieder 5 Bit raus.
>Bei 4 Worten sollte diese einfache Summe reichen.

??
Bei 20 Bit Nutzdaten bietet sich eine VIER-Bit Prüsumme geradezu an!
Macht 24 Bit = 3 Byte.
1
// generate checksum (parity)
2
3
checksum = data ^ data1;
4
checksum = checksum ^ (checksum>>4);
5
checksum = checksum ^ (data2 & 0x0F);
6
data 2 = (data2 & 0x0F) | (checksum <<4);
7
8
// check checksum
9
10
checksum = data0 ^ data1 ^ data2;
11
checksum = (checksum ^ (checksum>>4)) & 0x0F;
12
13
if (checksum !=0) {
14
  // checksum error
15
}

: Bearbeitet durch User
von Walter T. (nicolas)


Lesenswert?

Früh am morgen frisch ans Werk...

Eigentlich ist ein CRC4 gar nicht so kompliziert zu implementieren. Die 
AVR-Libc-Doku enthält den Quelltext für einen 16-Bit-CRC, der sich 
leicht ummodeln ließ.

Damit sind meine Fragen beantwortet + die Info mit dem gesparten 
Schreibzyklus bei den neueren AVR.

Danke für die Diskussion!

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.