mikrocontroller.net

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


Autor: Wolfgang Birner (logox2)
Datum:

Bewertung
0 lesenswert
nicht 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

#include <avr/io.h>
#include <avr/eeprom.h>

#ifndef EEMEM
#define EEMEM  __attribute__ ((section (".eeprom")))
#endif

#define MAX_EEPROM 512

uint64_t eellArray[MAX_EEPROM] EEMEM;

uint8_t write_eeprom(uint16_t index, uint64_t data);

uint64_t read_eeprom(uint16_t index);

void main(void) {
  uint64_t readout = 0;
  write_eeprom(1, 0xABCDEF01ABCDEF01);
  readout = read_eeprom(1);
}

uint8_t write_eeprom(uint16_t index, uint64_t data) {
  eeprom_write_block(data,eellArray[index],sizeof(eellArray[index]));
  return 0; 
}

uint64_t read_eeprom(uint16_t index) {
  uint64_t buffer;
  eeprom_read_block(&buffer,eellArray[index],sizeof(eellArray[index]));
  return = buffer;
}


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

Danke.
Wolfgang

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip JA, aber...

so brauchst du auch 4kB RAM!

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> so brauchst du auch 4kB RAM!

Warum?

Autor: Wolfgang Birner (logox2)
Datum:

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

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ääää.. noch mehr

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfgang Birner (logox2)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfgang Birner (logox2)
Datum:

Bewertung
0 lesenswert
nicht 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
typedef union{
  uint8_t b8[8];
  uint64_t ll;
} rfid_uid_t;
definiert.

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

Wolfgang

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wo finde ich infos zu memcmp?

memcmp ist eine Standard-C-Funktion.

> in der avrlibc finde ich nichts.

Steht unter <string.h>.

Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein Vergleich mit 64 Bit und dann als Array:

#include <io.h>
#include <string.h>


uint8_t compare_64( uint64_t a, uint64_t b )
{
  return a != b;
}


typedef uint8_t typ_id[7];


uint8_t compare_id( typ_id a, typ_id b )
{
  return memcmp( a, b, sizeof(typ_id));
}



Anbei das Listing.


Peter

Autor: Wolfgang Birner (logox2)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit ein paar kleinen Änderungen...
...

void main(void) {
  uint64_t readout = 0;
  write_eeprom(1, 0xABCDEF01ABCDEF01ULL);
  readout = read_eeprom(1);
}

uint8_t write_eeprom(uint16_t index, uint64_t data) {
  eeprom_write_block(&data,&eellArray[index],sizeof(data));
  return 0; 
}

uint64_t read_eeprom(uint16_t index) {
  uint64_t buffer;
  eeprom_read_block(&buffer,&eellArray[index],sizeof(buffer));
  return = buffer;
}

oder mit dem 64-Bit im byte-array
...
#define MAX_EEPROM (512*8)

uint8_t eellArray[MAX_EEPROM] EEMEM;

void main(void) {
  uint8_t readout[] = {0xAB,0xCD,0xEF,0x01,0xAB,0xCD,0xEF,0x01};
  write_eeprom(1, readout);
  read_eeprom(1, readout);
}

uint8_t write_eeprom(uint16_t index, uint8_t *data) {
  eeprom_write_block(data,&eellArray[8*index],8));
  return 0; 
}

void read_eeprom(uint16_t index, uint8_t *buffer) {
  eeprom_read_block(buffer,&eellArray[index*8],8);
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.