Problem: in einem kleinen RAM sollen stückweise EEPROM-Elemente
gelesen/geschrieben werden. Die Struktur des EEPROMs ist grösser
als das was im RAM gehalten werden kann. Somit ergibt sich das
Problem den Offset eines Struktur-Elements zu bestimmen ohne
eine komplette Instanz einer Struktur angelegt zu haben.
Soweit ich aus Suchanfragen entnommen habe funktioniert
<offsetof> nur mit Bezug auf eine existierende Struktur - so
werden die Beispiele formuliert. Ich würde aber gerne die
Funktionalität von <offsetof> auf eine Struktur-Definition
bezogen, also nicht auf eine existierende Struktur haben.
Wie geht das bitte?
(hier im Code ohne Anwendung von <offsetof>)
1
voidstruct_test(void)
2
{
3
uint32_toffsC;// zu berechnender Offset
4
5
typedefstruct// Struktur Definition
6
{
7
uint16_tvarA;
8
uint32_tvarB;
9
uint8_tvarC;
10
}mystruct_def;
11
12
mystruct_defsample;// eine Instanz der Struktur
13
14
// so geht's z.B. mit angelegter Struktur-Variable
Oliver S. schrieb:> Das C-Makro offsetof() benötigt den Typ, keine Instanz. Das reicht für> den Compiler ja völlig aus, die offsets zu berechnen.
Dann schreibe doch bitte eine funktionierende Zeile hin die
zu meinem Beispiel-Code passt.
Ich habe nur Beispiele gesehen in denen das Argument von <offsetof>
eine existierende Struktur ist, keine Struktur-Definition.
Wastl schrieb:> Ich denke ich hab es gerade selbst gefunden.
Funktioniert leider nicht bei ineinandergeschachtelten
Structs. Es sei denn ich habe noch nicht herausgefunden wie
man das formuliert ....
Wastl schrieb:> Wastl schrieb:>> Ich denke ich hab es gerade selbst gefunden.>> Funktioniert leider nicht bei ineinandergeschachtelten> Structs.
Klar geht das.
Daniel A. schrieb:> Klar geht das.
Stimmt, jetzt wo du es schreibst .... Danke für den Schubser ...
Hier ein Beispiel in meiner Ausführung mit separat
definierter Struktur und Sub-Struktur.
1
uint32_tcalc_offs(void)
2
{
3
uint32_toffs_val;// zu berechnender Offset
4
5
typedefstruct// untergeordnete Struktur Definition
6
{
7
uint32_tvarA;
8
uint16_tvarB;
9
uint8_tvarC;
10
}smallstruct_def;
11
12
typedefstruct// uebergeordnete Struktur Definition
Wastl schrieb:> Somit ergibt sich das> Problem den Offset eines Struktur-Elements zu bestimmen
Warum der Offset gebraucht werden soll, erschließt sich nicht aus der
Problembeschreibung. Wenn du mal das Pronlemm besser beschreibst , dann
zeige ich, wie das OHNE den Offset geht. Hier wird nur rumgespielt mit
struct anstatt mit Sinn verwendet.
... vom smallstruct_def anstatt smallstruct_t bekommt man
Bauchschmerzen!
Also zeige Beispiele wie du den offsetof() Wert verwenden willst ...
Apollo M. schrieb:> ... vom smallstruct_def anstatt smallstruct_t bekommt man> Bauchschmerzen!
Ok, ich tu dir was Gutes und verwende in Zukunft in der
Öffentlichkeit und privat immer *_t Strukturdefinitionen
anstat von *_def. Das kann ich nicht verantworten dass du
im Anblick meiner Veröffentlichungen Bauchschmerzen bekommst.
Apollo M. schrieb:> Warum der Offset gebraucht werden soll, erschließt sich nicht aus der> Problembeschreibung.
Im Übrigen hat keiner Derjenigen die sich zu Wort gemeldet
haben eine Frage nach dem Sinn meines Tuns gestellt. Damit
nehme ich an dass es bisher alle verstanden haben und auch
einen Sinn darin erkannt haben.
Weitere Auführungen erspare ich mir, ich kann jetzt genau das
machen was ich vorhabe.
Wastl schrieb:> Im Übrigen hat keiner Derjenigen die sich zu Wort gemeldet> haben eine Frage nach dem Sinn meines Tuns gestellt. Damit> nehme ich an dass es bisher alle verstanden haben und auch> einen Sinn darin erkannt haben.
Aua, das tut weh!
Wenn du glücklich bist, weil du denkst alles zu können, dann ist alles
perfekt!
Sehr überzeugend zu denken, dass zwei pro und eine contra Wortmeldung
eine sichere Selbstbestätigung sind.
Wastl schrieb:> Ok, ich tu dir was Gutes und verwende in Zukunft in der> Öffentlichkeit und privat immer *_t Strukturdefinitionen> anstat von *_def.
Mep, nicht machen.
Alle _t Typen sind für Posix reserviert. Wenn Du selbst einen Typ mit _t
anlegst riskierst Du bei jedem Standard Update einen Typenkonflikt.
Das betrifft noch ein paar andere Namen. GCC hat netterweise eine Liste:
https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
Apollo M. schrieb:> Aua, das tut weh
Apollo, der TO hat ein typisches Problem, dass auch erfahrene
Programmierer mit offsetof lösen und zur ersten Verwendung eine Frage,
die schnell und sachlich beantwortet wurde
Jetzt kommst Du, mäkelst an seinen Bezeichnern und versprichst eine
alternative Lösung, wenn er sich komplett auszieht.
Vermutlich wird Deine Lösung nur dann funktionieren, wenn er die
Programmiersprache wechselt, die Architektur umschmeißt oder 2
Statements da nutz, wo vorher eines war.
Wenn Du eine anfängertaugliche alternative zu offsetof kennst, in plain
C, für den Anwendungsfall hier (einzelne Elemente im eeprom spiegeln,
dann sttelle das in deinem Thread vor oder ins Wiki.
Wastl schrieb:> Im Übrigen hat keiner Derjenigen die sich zu Wort gemeldet> haben eine Frage nach dem Sinn meines Tuns gestellt. Damit> nehme ich an dass es bisher alle verstanden haben und auch> einen Sinn darin erkannt haben.
Nein, aber den Kommentar, daß deine nur sehr rudimentären C-Kentnisse
auch darauf schließen lassen, daß du da nach einer Lösung für ein
klassisches xy-Problem suchst, hatte ich mir verkniffen. Aber bitte,
wurde nachgeliefert.
Oliver
Wastl schrieb:> Problem: in einem kleinen RAM sollen stückweise EEPROM-Elemente> gelesen/geschrieben werden. Die Struktur des EEPROMs ist grösser> als das was im RAM gehalten werden kann.
Ich muss gestehen, dass ich das Problem auch nicht wirklich verstehe,
Johann L. schrieb:> Ich muss gestehen, dass ich das Problem auch nicht wirklich verstehe,
in deiner Lösung gehst du aber davon aus dass es sich a) um einen Atmel
handelt und b) die Verwendung von eeprom.h gewünscht ist.
Ich muss gestehen, ich verstehe die Frage des TE und halte das Vorgehen
für sinnvoll.
Du kannst dir dein Eeprom-Layout einfach per typedef struct vom Compiler
erzeugen lassen und dir mit offsetof die Adressen für die read- und
write-Funktionen berechnen lassen.
Dazu braucht es keine Instanz im RAM.
Apollo M. schrieb:> Warum der Offset gebraucht werden soll, erschließt sich nicht aus der> Problembeschreibung. Wenn du mal das Pronlemm besser beschreibst , dann> zeige ich, wie das OHNE den Offset geht. Hier wird nur rumgespielt mit> struct anstatt mit Sinn verwendet.gähn
Der Nachste der meint, besser zu wissen was der TE braucht und was
nicht.
Ich verstehe seine Frage, seinen Lösungsansatz und kann bezeugen dass
dieser Ansatz durchaus auch im Professionellem eingesetzt wird.
Folgere doch bitte von deinem Horizont nicht auf Andere.
Le X. schrieb:> Johann L. schrieb:>> Ich muss gestehen, dass ich das Problem auch nicht wirklich verstehe,>> in deiner Lösung gehst du aber davon aus dass es sich a) um einen Atmel> handelt und b) die Verwendung von eeprom.h gewünscht ist.
Das wird verwendet zum Lokatieren im EEprom und zum Zugriff; ist jetzt
nicht sooo exotisch.
> Du kannst dir dein Eeprom-Layout einfach per typedef struct vom Compiler> erzeugen lassen und dir mit offsetof die Adressen für die read- und> write-Funktionen berechnen lassen.
In meinem Beispiel (Teil2) wird das EEprom auch als Struct modelliert.
Um sich die Adresse z.B. einer Komponente des Structs zu besorgen gibt's
doch den &-Operator in C/C++, und wieviel Bytes zu lesen sind erhält man
mit sizeof.
> Dazu braucht es keine Instanz im RAM.
In meinem Beispiel auch nicht. Das Beispiel zeigt nur die Verwendung.
Um die Adressen und Größen der Komponenten zu erhalten genügt der
Typedef für den Struct und (eine externe Referenz) auf das EEprom
Object.
Und die Adresse des EEprom-Objects braucht mam mit sizeof ja auch. (und
wenn man die Adresse als 0x0 hart codiert, brauch man auch im meinem
Beispiel KEINE Referenz des Objects).
Johann L. schrieb:> Um sich die Adresse z.B. einer Komponente des Structs zu besorgen gibt's> doch den &-Operator in C/C++, und wieviel Bytes zu lesen sind erhält man> mit sizeof.
Der TO ist ein Anfänger, der das Define für offsetof nicht kannte und
auch nicht den Cast des Nullpointers zur Adressbestimmung.
Mit 100%iger Sicherheit ist sein Code nicht optimal. Ja und? Er hat
jetzt einen Ansatz mit dem er arbeiten und Erfahrungen sammeln kann.
Wenn ich ein fremdes Auto erstmals fahre, möchte ich nicht noch, dass
jemand zuschaut und Tips gibt.
Hier haben wir einen Fahranfänger mit 100 Experten (Mitleser) auf dem
Beifahrersitz, die sehen wollen, ob er früh genug blinkt. Ohne dass ein
Crash uns den Versicherungsrabatt kostet.
Lassen wir Compiler und HW zeigen, ob er richtig fährt. Er kann
jederzeit fragen, wenn er dauernd crashed.
Wenn man seine Sachen sauber definiert gibt es keinen Grund für
offsetof(). Welches im Prinzip sowieso nur mit Pointern spielt. Je nach
Compiler etwas grenzwertig mit einem Null-Pointer.
Wenn man voraus denkt:
Man legt die gemeinsamen Daten einfach an den Anfang, d.h. Offest 0.
1
// Data that happens to be stored in RAM or EEPROM
2
typedefstruct{
3
intcom1;
4
intcom2;
5
}common_data;
6
7
// Data that happens to be stored in EEPROM
8
typedefstruct{
9
common_datacommon;
10
intep1;
11
intep2;
12
}eeprom_data;
13
14
common_dataram_destination;
15
// Ignore details of eeprom access mechanisms for demonstration purposes
Man muss halt vorher nur mal für fünf Cent nachdenken wie man seine
Datenstruktur ins EEPROM legen möchte.
Man kann das ganze auch noch komplizierter machen wenn man es
symmetrischer haben möchte:
1
// Data that happens to be stored in RAM or EEPROM
2
typedefstruct{
3
intcom1;
4
intcom2;
5
}common_data;
6
7
// Data stored in RAM
8
typedefstruct{
9
common_datacommon;
10
}ram_data;
11
12
// Data that happens to be stored in EEPROM
13
typedefstruct{
14
common_datacommon;
15
intep1;
16
intep2;
17
}eeprom_data;
Und wenn man es doch versaut hat:
1
// Data that happens to be stored in RAM or EEPROM
2
typedefstruct{
3
intcom1;
4
intcom2;
5
}common_data;
6
7
// Data that happens to be stored in EEPROM
8
// screwed-up layout
9
typedefstruct{
10
intep1;
11
common_datacommon;
12
intep2;
13
}eeprom_data;
14
15
common_dataram_destination;
16
// Ignore details of eeprom access mechanisms for demonstration purposes
Hannes J. schrieb:> Wenn man seine Sachen sauber definiert gibt es keinen Grund für> offsetof(). Welches im Prinzip sowieso nur mit Pointern spielt. Je nach> Compiler etwas grenzwertig mit einem Null-Pointer.
Nein, da ist nichts grenzwertig. offsetof() ist ein Standard-Makro. Wie
der Compiler das umsetzt, ist seine Sache, aber es muss entsprechend der
Spezifikation funktionieren.
Hannes J. schrieb:> Man muss halt vorher nur mal für fünf Cent nachdenken wie man seine> Datenstruktur ins EEPROM legen möchte.
Und wie kommt man dann darauf, zwei typedefs zu verwenden?
Kein Vorteil, aber doppelter Pflegeaufwand und fehleranfällig.
Hannes J. schrieb:> copy_from_eeprom_to_ram(&ram_destination, &(eeprom_source->common),> sizeof(common_data));
und mit offsetof hätte die Zeile als zweiten Parameter offsetof (statt
&), dass den meist notwendigen Cast nach size_t schon enthält.