Forum: Mikrocontroller und Digitale Elektronik Cortex M4 dynamische Listen dauerhaft speichern


von Philipp (Gast)


Lesenswert?

Moin!

Ich bin gerade an einem Projekt auf einem TI CC3200 Launchpad dran, bei 
dem ich viele "linked Lists" verwende, z.T. sogar verschachtelt. Diese 
sollen im nichtflüchtigen Speicher abgelegt werden, damit sie nach einem 
Neustart wiederverwendbar sind.

Ich steh grad auf dem Schlauch, wie ich die Rohdaten beim Neustart 
wieder in die "Listen verpackt" kriege. Nach meiner Logik muss ich da 
ziemlich viele Steuerdaten mit Adressen etc. an vordefinierten 
Speicheradressen ablegen, um nachher in einer Startup-Routine die Listen 
wieder zu erstellen und mit Daten zu füllen... das klingt für mich sehr 
komplex und aufwändig.

Hab ich mir das richtig überlegt oder gibt es einen viel einfacheren 
Weg?

Bitte nicht böse sein, falls es eine blöde frage ist - ich hab schon 
länger nicht mehr embedded programmiert :-)

Vielen Dank!

Gruss
Philipp

von pegel (Gast)


Lesenswert?

Gleich alle Listen im FRAM bearbeiten und halten?

von Benjamin S. (recycler)


Lesenswert?

Die Frage ist, ob sich die Listen zur Laufzeit ändern oder immer gleich 
sind.
-> Dann könntest du sie im Code ablegen.
Nächste Frage wäre, ob sich die Listen bei "Konfiguration" ändern.
-> Dann müssteste du dir eine Konfigurationsstruktur überlegen.

Sind sie völlig dynamisch, dann wäre ein Konfigurationsloader sinnvoll, 
der die Daten aus dem Flash einliest.
Da wäre es sinnvoll mit IDs und Header zu arbeiten, analog FAT 
Dateisystem.

Vielleicht hast du ein einfaches Beispiel, dann kann man das besser 
abschätzen.

von S. R. (svenska)


Lesenswert?

Das Stichwort lautet "Serialisieren".

Du musst deine Datenstrukturen (d.h. alle deine Listen/Bäume) irgendwie 
in einen seriellen Bytestrom umwandeln (serialisieren), den du dann 
direkt abspeichern kannst. Zum Einlesen verwandelst du diesen Bytestrom 
wieder in deine Listenstruktur (deserialisieren). Dafür gibt es fertige 
Bibliotheken, oder du baust das selbst.

Als Beispiel: Wenn du eine doppelt verkettete Liste hast, dann 
speicherst du darin mindestens zwei Zeiger plus das Datenelement. 
Abspeichern brauchst du aber nur die Anzahl der Datenelemente plus die 
Elemente selbst (die Zeiger kannst du beim Einlesen neu erzeugen, deren 
genaue Werte sind ja egal).

Speichert deine Liste aber Zeiger, dann musst du diese vorher auflösen, 
d.h. entweder das gezeigte Objekt stattdessen speichern oder eine 
Referenz darauf (z.B. ID).

von Philipp (Gast)


Lesenswert?

Hi!

Vielen Dank für die schnellen antworten, das hilft mir weiter und ich 
habe nun auch das Gefühl, dass ich ungefähr in die richtige Richtung 
überlegt habe!

Die Listen können zur Laufzeit jederzeit verändert, erweitert oder 
verkleinert werden... zudem enthalten sie Pointer auf andere Listen, was 
das genannte serialisieren schwierig machen dürfte.

Als Codebeispiel:
1
// Struct to define the order and use of the DMX-Channels for a specific fixture type
2
typedef struct fixtureChannel {
3
    char purpose[MAX_NAMING_LETTERS]; // Predefined are d = Dimmer, r = red, g = green, b = blue, w = white, a = amber, u = uv, c = cyan, m = magenta, y = yellow
4
    struct fixtureChannel * next;
5
} fixtureChannel_t;
6
7
// Struct to define the DMX protocol of a fixture
8
typedef struct fixture {
9
    int id;
10
    char name[MAX_NAMING_LETTERS];
11
    fixtureChannel_t * chanList;
12
    int chanCount;
13
    char colType; // 1 = No Color, 2 = RGB, 3 = RGBW, 4 = RGBWA, 5 = RGBWUV, 6 = RGBWAUV, 7 = CMY, 8 = Wheel
14
    char hasDimmer; // 1 = yes, 0 = no (virtual Dimmer needed)
15
    struct fixture * next;
16
    struct fixture * previous;
17
} fixture_t;

Ich habe nun so grob die Idee, die "inneren" Listen separat der äusseren 
zu serialisieren und dann in der Serialisierung der "äusseren" Listen 
auf die Anzahl und Startadresse der jeweils inneren zu speichern. Klingt 
das nach einer Idee, falls ich mich verständlich ausgedrückt habe?

Bezüglich fertiger Bibliotheken: Wenn euch gerade eine einfällt, immer 
her damit! :-)

Gruss
Philipp

von Benjamin S. (recycler)


Lesenswert?

Kleiner Tipp:
Wenn deine Listen im Speicher auch als Adressen abgebildet sind, hilft 
es, beim serialisieren diesen Nummern zu geben. die Adressen können und 
werden sich im Programm ändern.

Beispiel zum Serialisieren:
1
typedef struct fixture {
2
    int id;
3
    char name[MAX_NAMING_LETTERS];
4
    fixtureChannel_t * chanList;
5
    int chanCount;
6
    char colType; 
7
    char hasDimmer; // 1 = yes, 0 = no (virtual Dimmer needed)
8
    struct fixture * next;
9
    struct fixture * previous;
10
} fixture_t;
1
T_FIXTURE;1;test;1;1;1;1
2
T_FIXTURE;2;test2;1;1;1;1


Annahmen: *next und *previous werden berechnet
Name enthält nur ASCII Space und Zahlen und keine \0
Mit T_FIXTURE definierst du den Typ.
Als chanlist verwendest du eine ID anstatt Zeiger.

Jetzt kannst du über tokenizing die Strings zerlegen und zusammenbauen.
Dabei aufpassen, dass keiner die Strukturen zwischenzeitlich ändert.

von Benjamin S. (recycler)


Lesenswert?

1
typedef struct fixtureChannel {
2
    char purpose[MAX_NAMING_LETTERS];
3
    struct fixtureChannel * next;
4
} fixtureChannel_t;

wird dann zu:

T_CHAN;1;test1
T_CHAN;2;test2


Ich hoffe damit wird es klarer.

von Philipp (Gast)


Lesenswert?

Ich glaube, ich habs gerafft!

Danke!

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.