wie kann ich eine Struktur einer Funktion übergebe?
Ziel soll es sein, dass die Funktion WriteToMemory jetzt nicht drei
Parameter für jede einzelne Struktur bekommt. Wie könnte dies mit einem Übergabeparameter realisiert werden?
wie kann ich eine Struktur einer Funktion übergebe?
Genau wie andere Typen auch, per Kopie oder per Zeiger.
Ziel soll es sein, dass die Funktion WriteToMemory jetzt nicht drei
Parameter für jede einzelne Struktur bekommt. Wie könnte dies mit einem
Übergabeparameter realisiert werden?
Das heißt, die Funktion soll alle drei Strukturen auf einmal bekommen, aber nur mit einem Parameter? Dann kannst du diese einfach in einer übergeordneten Struktur zusammenfassen.
Je nach Situation soll die entsprechende Struktur der Funktion übergeben werden. Zusammenfassen kann ich leider nicht machen.
Die Daten von der Struktur st_data1 soll nur während Produktion in das Flash geschrieben werden. Bei den anderen Strukturen entweder permanent oder ab und zu.
Deinem 'WriteToMemory' musst du eben noch mit einem weiteren Parameter mitteilen, welcher Teil vom Vorschlag von 'fop' geschrieben werden soll.
Andernfalls brauchst du drei unterschiedliche WriteToMemory-Funktionen, die du entsprechend aufrufst, weil die drei Structs ja unterschiedlich sind und du in der Funktion wissen musst, welche Parameter im Struct wie belegt sind.
Es mag noch Tricks geben, die mir aber nicht bekannt sind.
Es ist nicht so ganz klar, was du eigentlich genau willst. Wie sollen die Daten geschrieben werden? Als Binärklumpen oder serialisiert? Wohin? Woran willst du nachher beim lesen erkennen, welche der Strukturen da drin steht?
Die einfachste Art einer Schreibfunktion wäre eine, die einen void* und eine Größe als Parameter bekommt. Da kannst du schreiben, was du willst.
Die jeweiligen Daten von den Strukturen soll in ein internes Flash vom Mikrocontroller byteweise abgelegt werden.
Das mit einem void* als Übergabeparameter wäre eine gute Möglichkeit. Allerdings brauche ich da natürlich noch die Längenangabe. Dies kann ich mit sizeof(..) herausfinden.
ich glaube, er möchte immer die übergebene Struktur gespeichert werden soll.
da würde ich einen Cast auf einen Pointer auf uint8_t und die Länge der Struktur als Parameter vorsehen.
Danke für die Untersützung. Wie würde dies als Beispiel aussehen?
Wie würdest du eine Funktion schreiben, die als Parameter einen Pointer auf einen uint8_t-Typ und eine Größenangabe erwartet?
Wie ermittelst du die Adresse einer Struktur?
Wie castest du Typen?
Iwie fehlen mir Informationen um das zu beantworten?!?
Also ich fasse mal zusammen. Du kannst die 3 Structs nicht kombinieren, weil das 1. Struct konstante Werte beinhaltet. Du kannst aber auch Struct-Member konstant deklarieren. (siehe https://matt.sh/sytycc)
Dann möchtest du das Struct in einen Speicher schreiben. Was für ein Speicher das ist, ist erstmal egal. Was wichtig für mich zu wissen wäre, welche Wortbreite hat der Speicher (ich gehe jetzt mal von 8Bit=1Byte aus).
Wenn du nun das struct speichern willst, dann kannst du das indem du das struct in den Type uint8_t umcastest (hat schon ein Vorredner geschrieben). Das machst du so:
1
typedefstruct{
2
constinta;//can only be set in initialization
3
intb;//can be read and written
4
}new_type;
5
6
voidwrite_to_memory(uint8_t*ptr,unsignedintlen){
7
...
8
}
9
10
intmain(void){
11
...
12
new_typedata_a={5,2};
13
uint8_t*pointer_to_struct=(uint8_t*)&data_a;//cast pointer to struct into uint8_t*
14
unsignedintstruct_len=sizeof(data_a);
15
write_to_memory(pointer_to_struct,struct_len);
16
}
Die Länge deines Structs ist immer gleich. Es sei denn du hast dynamische Arrays in deinem Struct(wenn das geht, ich glaube aber schon). Dann musst du natürlcih wissen wie lang dein Struct war beim abspeichern und die Daten auch genau zuordnen können.
Wenn du ein statisches Struct hast, dann kann es sein dass dein Compiler Paddings um die einzelnen Variablen hinzufügt. Das sind einfach leere Bytes um z.B. eine 8Bit Variable auf die 32Bit Wortlänge des Controllers zu bringen oder sowas. Die sind aber auch immer gleich (bei statischen Structs).
Das heißt, wenn du ein Struct in den Speicher schreibst und wieder ausließt, dann kannst due die gelesenen Daten einfach deinem Struct zuweisen und deine Variablen sollten die richtigen Werte haben.
Wichtig ist heir auch die Reihenfolge. Wenn du die Bytes falsch herum deinem Struct zuweist, kommt natürlich kauderwelsch raus.
Tja, Du wolltest zwar "nur" schreiben, aber spätestens beim Wiederauslesen der Daten wirst Du das Problem haben, dass Du an der Stelle nicht (mehr) weisst, was Du da eigentlich hingeschrieben hast (liest Du nun ein st_data1, ein st_data2 oder ein st_data_3?).
Also solltest Du (zumindest) diese Info noch irgendwo hinterlegen.
eine Funktion für verschiedene Strukturen geht sowieso nicht. Wird bspw. key in der Funktion verwendet gibt es Mecker wenn eine Struktur ohne key übergeben wird.
Ich würde mich auf eine! Struktur für alle einigen, dass erleichtert vieles. Man muss die Member woanders ja nicht verwenden wenn nicht benötigt.
Es gibt noch die Möglichkeit dies per varargs-Funktion zu machen.
Ja, vielen Dank. Das war es wohl, ich hatte an die Parameterübergabe von printf gedacht, dort wird es auch mit varargs gemacht (soweit ich mich erinnere).
Das ist nichts, was ich in meinen Funktionen verwende ... 😀
Eine andere, vielleicht funktionierende Möglichkeit könnte ein union aus den drei structs sein. Ähnlich wie foo es mit dem Superstruct vorhat.
Könnte gehen, weil die beiden ersten Variablen gleichen Datentyps sind. Trotzdem muss zur Unterscheidung welcher struct übergeben wurde noch eine Information hinzugefügt werden.
Egal wie, einer WriteToMemory-Funktion muss das hier klar gemacht werden:
Coder schrieb im Beitrag #7341737:
Die Daten von der Struktur st_data1 soll nur während Produktion in das
Flash geschrieben werden. Bei den anderen Strukturen entweder permanent
oder ab und zu.
Eine andere, vielleicht funktionierende Möglichkeit könnte ein union aus
den drei structs sein.
Das ist totaler Bruch: Polymorphie-für-Arme.
Da man in C nun mal Funktionen nicht überladen kann, schreibt man 3 Funktionen mit unterschiedlichen Namen zum Serialisieren. Intern rufen die dann eine vierte auf, die eine byte-weise Serialisierung durchführt.
Wenn das Zeugs an unterscheidlichen Stellen im Flash/EEprom liegt, ist das Deserialisieren ja auch keine Thema. Andernfalls benötigt man ein Typ-Marker.
Da man in C nun mal Funktionen nicht überladen kann, schreibt man 3
Funktionen mit unterschiedlichen Namen zum Serialisieren. Intern rufen
die dann eine vierte auf, die eine byte-weise Serialisierung durchführt.
ich Funktion braucht keine Adresse. Es handelt sich um eine spezielle Lib die den non volatile memory managed. Ich brauche aber noch einen weiteren Parameter der die Nummer des Objekte übergeben soll.
ich Funktion braucht keine Adresse. Es handelt sich um eine spezielle
Lib die den non volatile memory managed. Ich brauche aber noch einen
weiteren Parameter der die Nummer des Objekte übergeben soll.
schreib einfach was Du hast, was Du brauchst und wie Du es Dir vorstellst. Wir kennen weder Deine Lib noch Deine Objekte oder Deine Vorstellungen.