Zeiger im FLASH Initialisieren

Gast #182220
Lesenswert?
• ▲
▼
Abend zusammen,

Ich habe folgendes Problem.
Ich programmiere einen Menübaum für meinen Mega16. Dabei deklariere ich
eine Struktur des Typs „Knoten“ mit Zeigern auf  alle Nachbarknoten.
Die Initialisierung aller Datenfelder der Struktur muss nach der
Deklaration aller Knoten erfolgen, da sonst bei der Initialisierung
während der Deklaration die Adressen von Nachbarknoten noch nicht
bekannt sind.
Soweit funktioniert das Programm ohne Probleme (siehe Beispiel).
Nur, wenn ich jetzt das Programm für den Mega16 optimiere und dabei
alle Menüknoten als FLASH-Konstanten deklarieren möchte, tritt das
Problem auf, alle Zeiger zu initialisieren.

Da es sich um Konstanten handelt, müssen sie sofort (bei der
Deklaration) initialisiert werden. Aber wie kann ich sie initialisieren
wenn die Adressen noch nicht bekannt sind?

Ich hab versucht, Deklaration und Initialisierung zu trennen:

struct Knoten
{
  uint8_t     v1;
  uint16_t     v2;
  const char  *s;
  struct Knoten *vater;
};

const struct Knoten myknoten1 PROGMEM;
const struct Knoten myknoten2 PROGMEM;

const struct TableEntry myknoten1 PROGMEM = { 1,2,
STRING1,&myknoten2};
const struct TableEntry myknoten2 PROGMEM = { 3,4, STRING2,
&myknoten1};


Der Compiler mekerte aber:
main.c:33: warning: only initialized variables can be placed into
program memory area

Was meint Ihr, gibt es dafür eine intelligente Lösung?
Angehängte Dateien:
Gast #182221
Lesenswert?
• ▲
▼
> Ich hab versucht, Deklaration und Initialisierung zu trennen:

Deklaration und Definition sind die Stichworte, und das hast du nicht
getrennt. Ich weiß nicht, ob es so funktioniert, aber für eine reine
Deklaration (einer globalen Variable o. Konstante) musst du extern
davor schreiben.
Gast #182224
Lesenswert?
• ▲
▼
> extern: lokale Deklaration von globalen Variablen, initialisiert mit
> 0.

Das widerspricht sich ja selbst. Bei einer reinen Deklaration kann eine
Variable nicht initialisiert werden. Dann wäre würde die Deklaration
eine Definition beinhalten.

Mit:
extern const int i;
deklarierst du eine globale Variable namens i, definierst sie aber noch
nicht. Das heißt, der Compiler hat ihr noch keinen Speicher zugewiesen,
sondern weiß nur, dass es sie gibt (eine reine Deklaration).
Irgendwo später musst du die Variable noch definieren, indem du
schreibst:
const int i = 0;
Hier fehlt das extern, daher geht der Compiler von einer Definition aus
und reserviert Speicher für die Variable. Ohne diese Zeile würde sich
spätestens der Linker beschweren (der die ganzen Symbole
zusammenpfriemeln darf).

In C++ darf man übrigens "const int i = 0" in einen Header schreiben,
da so eine Konstante dort eine spezielle Art der Bindung hat ("internal
linkage"). In C darf man das meines Wissens nach aber nicht, da der
Linker sich dann über mehrfache Definitionen beschweren würde.
Gast #182225
Lesenswert?
• ▲
▼
scheint zu funktionieren, es kommt nur eine Warnung in der Zeile mit
Initiaklisierung:

main.c:119: warning: initialization discards qualifiers from pointer
target type

mir fehlt noch ein Befehl, der komplett eine Struktur aus dem Flash
liest und eine einfache Zuweisung macht:

akt_Knoten = Knoten23;

für EEPROM gibts einen, mit dem man blockweise lesen kann, aber nicht
für den Programmspeicher.
Gast #182226
Lesenswert?
• ▲
▼
> main.c:119: warning: initialization discards qualifiers from
> pointer target type

qualifier sind in C "const" und "volatile". Vielleicht hast du
irgendwo eines der beiden vergessen.

> für EEPROM gibts einen, mit dem man blockweise lesen kann, aber
> nicht für den Programmspeicher.
Gibt es auch für Flash, die heißt nur anders: memcpy_P().

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.