Wie erreicht man, dass Teile (members) einer Struktur aus dem Flash gelesen werden? Mischbetrieb scheint nicht möglich: error: '__flash' specified for structure field 'string' Müssen stattdessen separate Strukturen oder Arrays im Flash angelegt werden, auf die per Zeiger verwiesen wird? Oder gibt es dafür ein "Konstrukt"?
In welchem Prozessor-Universum mit welchem Compiler bewegst du dich denn? Oliver
John schrieb: > Wie erreicht man, dass Teile (members) einer Struktur aus dem Flash > gelesen werden? Durch vorheriges Nachdenken. Sonst nicht. Mein Vorschlag an dieser Stelle wäre ein void Pointer im struct, der seinerseits auf eine Variable im RAM zeigt. Aber für jede Instanz so eines Dinges eine separate Variable. Das hatte ich schon mal vor Jahren in der Lernbetty vorgeturnt, siehe Anhang. Sowas ist allerdings rein manuell ein bissel mühsam, ich hatte die Dateien (*.inc) per Script gemacht. W.S.
Sorry, ich durfte nicht antworten: Als Gast kannst du maximal ... drei Beitraege pro Stunde erstellen. AVR und GCC, also avr-gcc
W.S. schrieb: > Mein Vorschlag an dieser Stelle wäre ein void Pointer im struct Ja, das wird natürlich gehen. Aber sicherheitshalber: das ist dann keine durchgehende struct mit Inhalten aus RAM und Flash gemischt. So etwas lässt sich in C kaum basteln, weil die member einer struct durchgehend hintereinander im Speicher liegen (evtl. wegen aligning mit ein paar Byte aufgefüllte Zwischenräume). Etwas in der Art:
1 | struct gehtgarnicht |
2 | {
|
3 | int i; // das geht ins RAM |
4 | int j; // das liegt im Flash |
5 | };
|
geht nicht (es sei denn, Flash und RAM liegen direkt hintereinander im Adressbereich und man zwingt eine einzelne struct genau auf die Grenze).
Ich versuch's mit zwei Strukturen und dem Pointer, aer krieg's nicht hin. Die Struktur darf ich offenbar nicht als const __flash deklarieren. Als member schon? Aber die Initialisierung mag er nicht...
1 | struct inRAM{ |
2 | int16_t variable; |
3 | const struct inFLASH __flash * ptr; |
4 | };
|
5 | |
6 | struct inFLASH{ |
7 | const int16_t constant; |
8 | const char * string; |
9 | };
|
10 | |
11 | struct inRAM array[] = { |
12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
13 | };
|
error: initializer element is not constant warning: braces around scalar initializer etc.
John schrieb: > error: initializer element is not constant > warning: braces around scalar initializer > etc. Das ist sicher nicht der John schrieb: > etc. etc. ==
1 | <source>:12:5: warning: braces around scalar initializer |
2 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
3 | | ^ |
4 | <source>:12:5: note: (near initialization for 'array[0].ptr') |
5 | <source>:12:12: warning: initialization of 'const __flash struct inFLASH *' from 'int' makes pointer from integer without a cast [-Wint-conversion] |
6 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
7 | | ^~ |
8 | <source>:12:12: note: (near initialization for 'array[0].ptr') |
9 | <source>:12:16: error: expected expression before 'const' |
10 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
11 | | ^~~~~ |
12 | <source>:12:16: warning: excess elements in scalar initializer |
13 | <source>:12:16: note: (near initialization for 'array[0].ptr') |
14 | <source>:12:36: error: expected '}' before ')' token |
15 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
16 | | ~ ^ |
17 | <source>:12:16: warning: missing initializer for field 'ptr' of 'struct inRAM' [-Wmissing-field-initializers] |
18 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
19 | | ^~~~~ |
20 | <source>:5:36: note: 'ptr' declared here |
21 | 5 | const struct inFLASH __flash * ptr; |
22 | | ^~~ |
23 | <source>:12:36: error: expected '}' before ')' token |
24 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
25 | | ^ |
26 | <source>:11:24: note: to match this '{' |
27 | 11 | struct inRAM array[] = { |
28 | | ^ |
29 | <source>:12:36: error: expected ',' or ';' before ')' token |
30 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
31 | | ^ |
32 | <source>:12:54: error: expected identifier or '(' before '}' token |
33 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
34 | | ^ |
35 | <source>:12:55: error: expected identifier or '(' before '}' token |
36 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
37 | | ^ |
38 | <source>:12:56: error: expected identifier or '(' before ',' token |
39 | 12 | {123, {42, const __flash char[]) {"Hello world!"}}}, |
40 | | ^ |
41 | <source>:13:2: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic] |
42 | 13 | }; |
43 | | ^ |
44 | Compiler returned: 1 |
Danke für's Ausprobieren, allerdings weiß ich nicht, was du mir sagen willst. Dass im Beispiel eine Klammer beim cast fehlt? Ich würde mich freuen, wenn mir jemand eine funktionierende Deklaration und Initialisierung zeigt.
John schrieb: > allerdings weiß ich nicht, was du mir sagen willst. Huch, da ist einiges in meinem Post verloren gegangen. > Dass im Beispiel eine Klammer beim cast fehlt? Dass du offensichtlich nicht gepostest hast, was du getestet hast. > Ich würde mich freuen, wenn mir jemand eine funktionierende Deklaration > und Initialisierung zeigt. Guck dir erstmal genau an, was in deiner inRAM Struktur enthalten ist. Und womit du es initialisierst.
mh schrieb: > Guck dir erstmal genau an, was in deiner inRAM Struktur enthalten ist. > Und womit du es initialisierst. Offensichtlich falsch. Offensichtlich sehe ich es nicht. Sei so nett und verrate doch, was der Fehler ist. Mit Pointer auf separates Arrayelement geht es:
1 | #include <stdint.h> |
2 | |
3 | struct inRAM{ |
4 | int16_t variable; |
5 | const struct inFLASH __flash * ptr; |
6 | };
|
7 | |
8 | struct inFLASH{ |
9 | const int16_t constant; |
10 | const char __flash * string; |
11 | };
|
12 | |
13 | const struct inFLASH __flash farray[] = { |
14 | {42, (const __flash char[]){"Hello"}} |
15 | };
|
16 | |
17 | struct inRAM array[] = { |
18 | {123, &farray[0]}, |
19 | {-11, (const struct inFLASH __flash *){42, (const __flash char[]){"world"}}}, |
20 | };
|
Aber die direkte Initialisierung der Struktur und ihres Pointers geht nicht, oder mache ich falsch?
John schrieb: > Aber die direkte Initialisierung der Struktur und ihres Pointers geht > nicht, oder mache ich falsch? Was ist der vollständige Typ von inRAM.ptr? > Mit Pointer auf separates Arrayelement geht es: Womit genau initialisierst du in diesem Fall (was genau ist der Typ des Ausdrucks &farray[0])? Die Antworten auf diese Fragen werden einfacher, wenn du den __flash Kram erstmal weglässt, der hat nämlich nichts mit deinem aktuellen Problem zu tun. > Sei so nett und verrate doch, was der Fehler ist. Wo der Fehler ist sollte jetzt mehr als klar sein. Was der Fehler ist musst du schon selbst rausfinden.
Klaus W. schrieb: > Aber sicherheitshalber: das ist dann keine durchgehende struct mit > Inhalten aus RAM und Flash gemischt. > So etwas lässt sich in C kaum basteln, weil die member einer struct > durchgehend hintereinander im Speicher liegen (evtl. wegen aligning mit > ein paar Byte aufgefüllte Zwischenräume). Ähm, Ihr wollt da nicht zufällig einen Mikrocontroller passend zu Eurem Problem entwickeln ? Dann noch schnell den Compiler passend abändern. Wenn das Projekt mal wieder "etwas" aufwändiger wird...
Alternativ ginge natürlich Struktur in FRAM legen.
Ah, ein Didakt. Vielleicht mag es ja doch jemand erklären, ob und wie man den Compiler dazu bekommt, einen Pointer zur inneren Struktur einzubauen?
John schrieb: > Ah, ein Didakt. > Vielleicht mag es ja doch jemand erklären, ob und wie man den Compiler > dazu bekommt, einen Pointer zur inneren Struktur einzubauen? Hast du wenigstens versucht meine Fragen zu beantworten?
John schrieb: > Vielleicht mag es ja doch jemand erklären, ob und wie man den Compiler > dazu bekommt, einen Pointer zur inneren Struktur einzubauen? Vielleicht bist du ja der aus dem anderen Thread mit einer verwandten Frage. Auch hier: in C++ könnte man sowas bauen, in C nicht. Da müsste man es von Hand machen vor Verwendung der struct.
Ja danke, meine Frage blieb unbeantwortet, daher präzisiert im anderen Thread. John schrieb: > die direkte Initialisierung der Struktur und ihres Pointers geht nicht, > oder mache ich falsch?
mh schrieb: > Hast du wenigstens versucht meine Fragen zu beantworten? Dito. Die struct soll den Pointer haben, sonst macht das Ganze ja überhaupt keinen Sinn. Das Probem ist die unmögliche anonyme Initialisierung.
Klaus W. schrieb: > So etwas lässt sich in C kaum basteln,... Naja, es läßt sich machen, aber nicht genau so, wie man es ohne nachzudenken anfangen würde. Eines ist klar, verschiedene Einträge in einem Struct können nicht einfach auf verschiedene Speichervolumina verteilt werden. Wenn man so etwas konstruieren will, dann ist etwas gründlicheres Nachdenken nötig als bloß verschiedene Attribute wie 'const' usw. mal probehalber davorzuschreiben und dann zu schauen, was der Compiler dazu meint. Einen Punkt möchte ich hier aber mal dediziert ansprechen: Die Neigung von C Programmierern, alles mögliche zusammenzuziehen. Ich empfinde das als ausgesprochen schlechten Stil. Mit einer Typdeklaration wie z.B. struct... kreiert man sich einen zusammengesetzten Datentyp, aber noch keine Variable oder typisierte Konstante dieses Typs (eben noch keine Instantiierung). Sowas muß separat von der Typdeklaration erfolgen und eigentlich separat davon dann die Zuweisung von Inhalten. Dann wird auch klar, daß es für jede Instantiierung so einer Struktur im Flash eine separate Instantiierung des zugehörigen variablen Teils im RAM geben muß. So etwas kann C nicht von selbst leisten. In dem oben geposteten Beispiel hatte ich das per Programm (bzw. Script) generieren lassen, so daß eindeutig zugeordnete Variablen im RAM dabei entstanden und der jeweils konstante Teil im Flash angeordnet werden konnte. W.S.
John schrieb: > struct inFLASH{ > const int16_t constant; > const char __flash * string; > }; Damit eine Struktur const sein kann, muss ihr Inhalt const sein. const TYPE * ptr; ist ein Pointer auf etwas Konstantes. Der Pointer selbst ist aber variabel. Das kann also nicht im Flash liegen. const TYPE * const ptr; ist ein konstanter Pointer auf etwas Konstantes. Das kann im Flash liegen. Allerdings kenne ich mich mit AVR GCC nicht aus. Vielleicht gibt es da noch mehr zu beachten.
John schrieb: > struct inRAM array[] = { > {123, {42, const __flash char[]) {"Hello world!"}}}, Das ist C++. avr-g++ kennt allerdings __flash nicht, das gibts nur für den C-Compiler. Der Ansatz klappt so also eh nicht. Oliver
Darth Moan schrieb: > Damit eine Struktur const sein kann, muss ihr Inhalt const sein. Es sollte reichen, wenn es ein const struct inFLASH ist. Damit sollte es in jedem Fall illegal sein ein Member der struct zu ändern auch wenn der Member kein eigenes const hat.
John schrieb: > Das Probem ist die unmögliche anonyme Initialisierung. Ja, aber was ist daran das Problem? Leg halt ein struct mit den Werten im Flash an, und nimm darauf den Pointer. Oliver
John schrieb: > Das Probem ist die unmögliche anonyme Initialisierung. Ist doch möglich: Beitrag "Re: C Construct an unnamed object in-place?"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.