Geht so? uint64_t Array in EEPROM

#807662
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
Gast #809345
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?
#809425
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
#809642
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
#809686
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
#809776
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
Angehängte Dateien:
#810801
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
Gast #811795
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren