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"?
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.
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
structgehtgarnicht
2
{
3
inti;// das geht ins RAM
4
intj;// 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
structinRAM{
2
int16_tvariable;
3
conststructinFLASH__flash*ptr;
4
};
5
6
structinFLASH{
7
constint16_tconstant;
8
constchar*string;
9
};
10
11
structinRAMarray[]={
12
{123,{42,const__flashchar[]){"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
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:
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...
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