Hallo zusamen,
ich habe ein globales Struct, das meine Konfigurationsdaten enthält und
als globale Variable beim Start initialisiert werden soll.
"Nebenbei" will ich diesen Startzustand zur Laufzeit wiederherstellen
können. Und zwar ohne, daß ich die Einträge des globalen Structs zweimal
pflegen will.
Also ungefähr so:
1
// Default-Werte
2
#define settinginit {\
3
.z_max_default = Z_MAX_DEFAULT_DEFAULT,\
4
.t_on_min = T_ON_MIN_DEFAULT,\
5
.t_off_min = T_OFF_MIN_DEFAULT,\
6
.duty_cycle_max = DUTY_CYCLE_MAX_DEFAULT,\
7
// [...]
8
}
9
10
// Default-Werte für .data:
11
Setting_tgls_setting=settinginit;
12
13
// Default-Werte wiederherstellen
14
voidresettodefault(void)
15
{
16
gls_setting=edmsettinginit;
17
returnEXIT_SUCCESS;
18
}
"ungefähr so" deshalb, weil es nicht funktioniert (die Zuweisung in der
Funktion wird mir als "unexpected expression" angemahnt).
Gibt es eine sinnvolle Möglichkeit, das gleiche Struct in einer Funktion
und im .data zuzuweisen, ohne großartige Verdoppelungen im Quelltext zu
benötigen?
Viele Grüße
W.T.
> Gibt es eine sinnvolle Möglichkeit, das gleiche Struct in einer Funktion> und im .data zuzuweisen, ohne großartige Verdoppelungen im Quelltext zu> benötigen?
Klar, z.B. so:
Geht aber nur sinnvoll wenn Du keinen Startup-Code hast, der vor mai()
auf gls_setting zugreift. Hat dafür den Vorteil, dass man sich keine
Probleme mit einem Watchdog einhandelt.
Oder du definierst zwei Variablen vom Typ Setting_t, von denen du eine
mit den Defaultwerten initialisierst. In resettodefault weist du diese
Variable der anderen zu, welche bei Bedarf mit neuen Werten
überschrieben wird.
Johann war schneller :)
Memcpy brauchst du aber nicht unbedingt, da man in C Strukturen auch
direkt zuweisen kann.
Yalu X. schrieb:> Memcpy brauchst du aber nicht unbedingt, da man in C Strukturen auch> direkt zuweisen kann.
Stimmt. Der Compiler baut dann das memcpy selbst ein falls es keine
günstigere Möglichkeit gibt.
Yalu X. schrieb:> gls_setting = (Setting_t)settinginit;
Danke, Yalu, das war's, was mir gefehlt hat.
Damit ist die Frage für mich beantwortet und ich bin glücklich. Trotzdem
noch kurz zu den anderen Posts, deren Ansätze ja auch nicht verkehrt
sind:
g457 schrieb:> int main(void)> {> resettodefault();> // [..]> }
Das ist der vorherige Stand, von dem ich weg will, weil mein Startup
ohnehin schon immer länger wird und dummerweise der Start ungefähr so
aussieht:
Irgendwie ist es mir diese Funktion am Anfang, die eine Variable
beschreibt, die später auf jeden Fall überschrieben wird, schon lange
ein Dorn im Auge. Spätestens beim nächsten Aufräumen will ich sie mal
wieder wegmachen und suche dann nach dem Fehler im I2C-Teil.
Johann L. schrieb:> Lege eine init-Objekt an, das nicht verändert wird. Bei Bedarf wird> dieses per memcpy in die Zielstruktur kopiert.
Momentan habe ich massig Flash, aber wenig SRAM frei. Aber ich behalte
die Methode mal im Hinterkopf.
Vielen Dank und viele Grüße
W.T.
Walter Tarpan schrieb:> Johann L. schrieb:>> Lege eine init-Objekt an, das nicht verändert wird. Bei Bedarf wird>> dieses per memcpy in die Zielstruktur kopiert.>> Momentan habe ich massig Flash, aber wenig SRAM frei. Aber ich behalte> die Methode mal im Hinterkopf.
Du kannst dieses Init-Objekt ja auch in den Flash legen (bzw. im Flash
belassen).
Walter Tarpan schrieb:> Momentan habe ich massig Flash, aber wenig SRAM frei. Aber ich behalte> die Methode mal im Hinterkopf.
Geht dann so und ist ohne explizites memcpy[_P]:
Was ich (nach einer Pause und einem Kaffee) nicht verstehe:
1
gls_setting=(Setting_t)settinginit;
Ich erzeuge also ein Struct mit
1
// Text, der den Inhalt eines Structs beschreibt.
2
#define settinginit {
3
.z_max_default=Z_MAX_DEFAULT_DEFAULT,
4
.t_on_min=T_ON_MIN_DEFAULT,
5
.t_off_min=T_OFF_MIN_DEFAULT,
6
.duty_cycle_max=DUTY_CYCLE_MAX_DEFAULT,
7
// [...]
8
}
9
10
// Text wird in ein Struct gecastet und zugewiesen:
11
Settings_tS=(Settings_t)settinginit;
Also ich erzeuge aus einem Text ein Struct und caste es in ein Struct
vom Typ "Setting_t". Beide haben dieselben Feldnamen. Aber können bei
der Zuweisung die Feldnamen überhaupt berücksichtigt werden?
Oder funktioniert das nur korrekt, wenn die Reihenfolge der Feldnamen
für das im Text beschriebene und das zugewiesene Struct gleich ist und
auch alle Feldnamen vorhanden sind?
Ich bin mal wieder verwirrt.
Viele Grüße
W.T.
Walter Tarpan schrieb:> Also ich erzeuge aus einem Text ein Struct und caste es in ein Struct> vom Typ "Setting_t".
Nein, das ist kein Cast.
Das hier
1
(Settings_t){...}
ist ein "Compound Literal".
Walter Tarpan schrieb:> Aber können bei> der Zuweisung die Feldnamen überhaupt berücksichtigt werden?
Das sind keine Zuweisungen, sondern das obige "..." ist die
Initialisierung des Compound Literals.
Walter Tarpan schrieb:> Oder funktioniert das nur korrekt, wenn die Reihenfolge der Feldnamen> für das im Text beschriebene und das zugewiesene Struct gleich ist und> auch alle Feldnamen vorhanden sind?
Bei der Initialisierung einer Struktur über die Namen spielt die
Reihenfolge keine Rolle. Auch müssen nicht alle aufgeführt sein
(ungenannte werden implizit mit 0 initialisiert).
Stefan Ernst schrieb:> Das hier(Settings_t){...}ist ein "Compound Literal".
Hallo Stefan,
danke für die Antwort. Mit diesem Suchwort ließen sich alle Fragen
klären.
Viele Grüße
W.T.