2 Stimmen

Speichern von Strukturen in EEPROM unter Verwendung einer Art von Dateizuordnungstabelle

Ich habe ein Problem mit dem Speichern von Daten in einem EEPROM auf einem 16-Bit-Mikrocontroller von Fujitsu. Das Schreiben von Bytes in das EEPROM ist nicht das Problem, ich kann Daten byteweise schreiben und lesen, ohne Probleme zu haben.

Wir verwenden ein enum von dword's, um verschiedene Variablen im EEPROM zu speichern, und sie sind alle 4 Bytes lang. Für jede Variable möchten wir bis zu diesen 4 Bytes Speicherplatz speichern. Das ist ziemlich schlecht, denn wenn ich nur eine Flagge (ein Bit) oder eine Variable, die nur ein Byte lang ist, speichern möchte, werden dennoch vier Bytes verwendet.

Der Grund, warum wir diese Vier-Byte-Technik verwenden, ist, damit wir wissen, auf welcher Adresse die Variable gespeichert ist, auf die ich zugreifen möchte. Das funktioniert in Ordnung, hat aber einige Nachteile.

Einer davon ist der verschwendete Platz, und ein weiteres Problem entsteht, wenn ich mit Strukturen arbeite.

Zum Beispiel habe ich eine Struktur wie

typedef struct {
    attenuator_whichone_t attenuator;
    char*                 attenuatorname;
    servo_whichone_t     associated_servo;
    ad_ad7683_whichone_t associated_adconverter;
    word                 item_control;
    word                 item_mode;
    word                 item_position;

} attenuator_info_t;

und initialisiere sie wie:

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

Mit dem Code, den wir derzeit verwenden, müssten wir jeden Wert einzeln speichern, wodurch die Struktur aufgebrochen wird. Ich möchte diese Struktur wirklich so speichern, wie sie ist (und einige mehr, die wir im Code haben).

Nach meinem Verständnis bräuchte ich dafür ein Dateisystem. Eine Google-Suche gab mir einige Beispiele wie das microFAT und so weiter. Das ist meiner Meinung nach zu übertrieben.

Das Speichern der Struktur mit sizeof und das Durchlaufen aller Bytes wären in Ordnung, aber wie gehe ich mit dem Problem um, zu wissen, wo sich die Strukturen im EEPROM befinden? Daher ist wahrscheinlich ein Dateisystem erforderlich. Gibt es nicht etwas Kleineres? Oder einen Trick? Die Variablen haben sowieso eine feste Länge. Deshalb frage ich mich, ob es einen einfachen Weg gibt, diese Strukturen zu speichern.

Ich hoffe, ich konnte mein Problem ausreichend erläutern.

1voto

Potatoswatter Punkte 130562

Von meinem Verständnis her bräuchte ich dafür ein Dateisystem. Eine Google-Suche hat mir einige Beispiele wie das MicroFAT und so gegeben. Das ist meiner Meinung nach übertrieben.

Nein, ein Dateisystem hat nichts mit der von Ihnen beschriebenen Aufgabe zu tun. Ein Dateisystem definiert eine Zuordnung zwischen Dateinamen und Dateien, die willkürlich erstellt, zugegriffen, gelöscht und vergrößert werden können. Sie haben keine Namen oder Anforderungen für Änderungen zur Laufzeit genannt. Es scheint übertrieben, weil die essenziellen Dienste, die ein Dateisystem definieren, Dinge sind, die Sie nicht benötigen.

Wir verwenden ein Enum von dword's, um verschiedene Variablen im EEPROM zu speichern und sie sind alle 4 Byte lang.

Ich glaube, Sie meinen ein Array von dword's.

Wenn dies ein Problem verursacht, warum versuchen Sie nicht, es zu ändern?

Es scheint, als ob Sie nur wissen, wie man das EEPROM mit einer Definition der Form initialisiert

static attenuator_info_t constinfo[_NUM_ATTENUATOR_WHICHONE_] = {...}

Es gibt keine technische Einschränkung des EEPROMs, die es erforderlich macht, dass es so gemacht wird. Ein struct ist eine Sequenz von Bytes, genauso wie ein array. Die meisten Embedded-Compiler ermöglichen es auch, eine Sequenz von struct, Array- und sonstigen Definitionen als eine Sequenz von Bytes zu behandeln, indem sie diese mit einem entsprechenden #pragma umgeben.

Ohne etwas über das EEPROM zu wissen, oder ob sich constinfo ändert, nachdem Sie das Programm erstellt haben, kann ich Ihnen nicht sagen, wie Sie darauf schreiben können. Aber es sieht wirklich so aus, als ob Sie eine Menge benannter Variablen einer Sequenz von Bytes zuordnen möchten. Das könnte ein Dateiformat erfordern, aber kein Dateisystem.

Wenn das EEPROM memory-mapped ist, dann können Sie einfach Zeiger darauf kompilieren:

extern struct foo_info_type foo_info;
extern struct bar_info_type bar_info;

/* EEPROM Inhaltsverzeichnis */
struct foo_info_type *foo_ptr = & foo_info;
struct bar_info_type *bar_ptr = & bar_info;
/* ... mehr Zeiger ... */

/* Tatsächliche Daten im EEPROM, auf die die Zeiger zeigen */
struct foo_info_type foo_info;
struct bar_info_type bar_info;

1voto

bta Punkte 41611

Wenn Sie ein Array von Strukturen haben, sollten Sie in der Lage sein, die Daten einfach in einem EEPROM zu schreiben und sie später problemlos auszulesen. Der Schlüssel liegt darin, genau zu wissen, wo die Daten im EEPROM gespeichert sind.

Sie können dies auf verschiedene Arten tun. Für einfache Projekte können Sie einfach eine Konstante definieren, die die Startadresse des Speicherbereichs darstellt, in dem Ihre Tabelle gespeichert ist:

#define ATTENUATOR_INFO_START 0x0100 // Zeigt an, dass die Tabelle bei Adresse 256 beginnt
#define ATTENUATOR_INFO_SIZE (sizeof(constinfo)/sizeof(*constinfo))

// Tabelle im EEPROM speichern
memcpy(EEPROM_START + ATTENUATOR_INFO_START, constinfo, ATTENUATOR_INFO_SIZE);

// Tabelle aus dem EEPROM laden
memcpy(constinfo, EEPROM_START + ATTENUATOR_INFO_START, ATTENUATOR_INFO_SIZE);

Das obige setzt voraus, dass das EEPROM im Speicher abgebildet ist und die Konstante EEPROM_START die Speicheradresse darstellt, die auf den EEPROM-Offset null abgebildet ist. Wenn Ihr Projekt kein EEPROM im Speicher abgebildet hat, wird Ihr Verfahren etwas anders sein, aber die allgemeine Idee ist die gleiche.

Wenn Sie die Tabelle nicht an einem festen Offset speichern möchten, eine Alternative besteht darin, den Offset der Tabelle im EEPROM ebenfalls zu speichern. Der Prozess ist im Allgemeinen der gleiche:

// Offset/Längeninformationen werden in den ersten Bytes des EEPROM gespeichert
#define TABLE_INFO_LOCATION 0x0000

struct table_info {
    unsigned int offset;
    unsigned int num_entries;
} table_info;

// Tabellenoffset abrufen
memcpy(&table_info, EEPROM_START + TABLE_INFO_LOCATION, sizeof(table_info));

// Tabelle aus dem EEPROM laden
memcpy(constinfo,
       EEPROM_START + table_info.offset,
       table_info.num_entries * sizeof(*constinfo));

Diese Methode ermöglicht mehr Flexibilität, da die Tabelle überall im EEPROM platziert werden kann, erfordert aber immer noch einen bekannten Speicherort, um die Tabelleninformationen zu speichern.

Wenn Sie nichts an einem vorbestimmten Offset speichern können, können Sie eine Kopf-/Fußzeichenatur erstellen, um die Datenstruktur zu umschließen. Die meisten Speichergeräte verwenden standardmäßig 0x00 oder 0xFF für ungenutzte Bytes. Sie könnten 32 Bytes des Musters 0xBE (für "vorher") unmittelbar vor Ihrer Tabelle schreiben und dann 32 Bytes des Musters 0xAF (für "nachher") unmittelbar nach Ihrer Tabelle schreiben. Auf diese Weise können Sie durch den Speicher des EEPROMs suchen und den Anfang und das Ende Ihrer Tabelle finden, wo immer sie sich befinden mögen. Der Nachteil besteht darin, dass Sie an die falsche Stelle springen könnten, wenn dieses Speichermuster irgendwo anders im EEPROM erscheint, also wählen Sie Ihre Kopf-/Fußmuster und -größen mit Bedacht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X