Forum: Compiler & IDEs Geht so? uint64_t Array in EEPROM


von Wolfgang B. (logox2)


Lesenswert?

Hallo,

ich hab einen AT90CAN128 und möchte dort im EEPROM einige Werte ablegen. 
Dazu hab ich mir folgendes überlegt und aus verschiedenen Tutorials 
zusammengebaut:
4k EEPROM -> 512 mal uint64_t
1
#include <avr/io.h>
2
#include <avr/eeprom.h>
3
4
#ifndef EEMEM
5
#define EEMEM  __attribute__ ((section (".eeprom")))
6
#endif
7
8
#define MAX_EEPROM 512
9
10
uint64_t eellArray[MAX_EEPROM] EEMEM;
11
12
uint8_t write_eeprom(uint16_t index, uint64_t data);
13
14
uint64_t read_eeprom(uint16_t index);
15
16
void main(void) {
17
  uint64_t readout = 0;
18
  write_eeprom(1, 0xABCDEF01ABCDEF01);
19
  readout = read_eeprom(1);
20
}
21
22
uint8_t write_eeprom(uint16_t index, uint64_t data) {
23
  eeprom_write_block(data,eellArray[index],sizeof(eellArray[index]));
24
  return 0; 
25
}
26
27
uint64_t read_eeprom(uint16_t index) {
28
  uint64_t buffer;
29
  eeprom_read_block(&buffer,eellArray[index],sizeof(eellArray[index]));
30
  return = buffer;
31
}

Könnte dies so gehen? Oder hab ich irgendwo so einen richtigen 
Gedankenfehler drin?

Danke.
Wolfgang

von Werner B. (Gast)


Lesenswert?

Im Prinzip JA, aber...

so brauchst du auch 4kB RAM!

von Rolf Magnus (Gast)


Lesenswert?

> so brauchst du auch 4kB RAM!

Warum?

von Wolfgang B. (logox2)


Lesenswert?

Warum brauch ich hier 4k RAM? Ich lese doch immer nur einen Wert ein 
oder speichere ihn weg.

von Werner B. (Gast)


Lesenswert?

Mich hat das  sizeof(eellArray[index]) verwirrt.
NIE würde ich auf die Idee kommen das so zu kompliziert schreiben.
Würde hier sizeof(buffer) bzw. sizeof(data) schreiben.

Sorry 8-)

P.S.
Muss das nicht

eeprom_read_block(&buffer, &eellArray[index], sizeof(...
und
eeprom_write_block(data, &eellArray[index], sizeof(...

sein?

von Werner B. (Gast)


Lesenswert?

Ääää.. noch mehr

eeprom_write_block(&data, &eellArray[index], sizeof(...

von Peter D. (peda)


Lesenswert?

Du solltest erstmal die Frage klären, warum es unbedingt 64 Bit sein 
muß.

64 Bit ist im AVR-GCC grottenschlecht implementiert, ist sogar 
aufwendiger als float!

Schau Dir mal im Listing an, welche riesigen Codemonster für jede 
einzelne 64Bit-Operation erzeugt werden, da wird einem übel.


Und da der EEPROM auch nur byteweise beschrieben wird, kann man besser 
ein Bytearray übergeben.


Peter

von Wolfgang B. (logox2)


Lesenswert?

Ich baue zur Zeit an einem RFID-Reader und der soll ID's (bis zu 7 Byte) 
im EEPROM ablegen. Einzelbyte-mäßig wollte ich das nicht machen.

von Peter D. (peda)


Lesenswert?

Wolfgang Birner wrote:
> Ich baue zur Zeit an einem RFID-Reader und der soll ID's (bis zu 7 Byte)
> im EEPROM ablegen. Einzelbyte-mäßig wollte ich das nicht machen.

Ich vermute mal, der RFID-Reader gibt die IDs als Byte-Stream aus, dann 
ist es sogar sehr sinnvoll, diesen auch als Bytearray abzulegen.

Du mußt ja mit den IDs nicht rechnen (+,-,/,*).

Und zum Vergleichen von Arrays gibts memcmp.

Aber es bleibt natürlich Dir überlassen, ob Du den Code durch die 64 Bit 
Umwandlerei auf das 10-fache aufblähen willst.


Peter

von Wolfgang B. (logox2)


Lesenswert?

Das 64bit so krass sind hätte ich mir nicht gedacht, von float hätte ich 
es vermutet.

Der Reader gibt tatsächlich einen Byte-Stream aus, wobei die ID's 4 oder 
7 Byte groß sind. Das Umwandeln ist kein Problem, ich hab mir eine union 
mit
1
typedef union{
2
  uint8_t b8[8];
3
  uint64_t ll;
4
} rfid_uid_t;
definiert.

Wo finde ich infos zu memcmp? in der avrlibc finde ich nichts.

Wolfgang

von Rolf Magnus (Gast)


Lesenswert?

> Wo finde ich infos zu memcmp?

memcmp ist eine Standard-C-Funktion.

> in der avrlibc finde ich nichts.

Steht unter <string.h>.

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Hier mal ein Vergleich mit 64 Bit und dann als Array:
1
#include <io.h>
2
#include <string.h>
3
4
5
uint8_t compare_64( uint64_t a, uint64_t b )
6
{
7
  return a != b;
8
}
9
10
11
typedef uint8_t typ_id[7];
12
13
14
uint8_t compare_id( typ_id a, typ_id b )
15
{
16
  return memcmp( a, b, sizeof(typ_id));
17
}


Anbei das Listing.


Peter

von Wolfgang B. (logox2)


Lesenswert?

Okay, danke nochmals für den Hinweis.

Jetzt stellt sich mir die Frage, ob ich den Overhead durch uint64_t in 
kauf nehmen sollte, bzw. ob der Overhead durch das definieren einer 
logischen Struktur (wo dann für den Vergleich diverse Schleifen zum 
Einsatz kommen) wirklich kleiner ist.

Aber nochmal kurz zurück zu meiner Frage: würde das im ersten Beitrag 
genannte Beispiel so gehen, in Bezug auf Speichern im EEPROM, oder liegt 
da noch ein Verständnis-Problem/Fehler vor?

Wolfgang

von Werner B. (Gast)


Lesenswert?

Mit ein paar kleinen Änderungen...
1
...
2
3
void main(void) {
4
  uint64_t readout = 0;
5
  write_eeprom(1, 0xABCDEF01ABCDEF01ULL);
6
  readout = read_eeprom(1);
7
}
8
9
uint8_t write_eeprom(uint16_t index, uint64_t data) {
10
  eeprom_write_block(&data,&eellArray[index],sizeof(data));
11
  return 0; 
12
}
13
14
uint64_t read_eeprom(uint16_t index) {
15
  uint64_t buffer;
16
  eeprom_read_block(&buffer,&eellArray[index],sizeof(buffer));
17
  return = buffer;
18
}

oder mit dem 64-Bit im byte-array
1
...
2
#define MAX_EEPROM (512*8)
3
4
uint8_t eellArray[MAX_EEPROM] EEMEM;
5
6
void main(void) {
7
  uint8_t readout[] = {0xAB,0xCD,0xEF,0x01,0xAB,0xCD,0xEF,0x01};
8
  write_eeprom(1, readout);
9
  read_eeprom(1, readout);
10
}
11
12
uint8_t write_eeprom(uint16_t index, uint8_t *data) {
13
  eeprom_write_block(data,&eellArray[8*index],8));
14
  return 0; 
15
}
16
17
void read_eeprom(uint16_t index, uint8_t *buffer) {
18
  eeprom_read_block(buffer,&eellArray[index*8],8);
19
}

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.