Forum: Compiler & IDEs Strings in Flash: only initialized variables can be placed into program memory area


von ●● pit ●. (Gast)


Lesenswert?

Hallo,

kann mir bitte jemand helfen und erklären, warum mein C++ code nicht 
klappt?
1
const char menu0[] PROGMEM = "aaa";
2
const char menu1[] PROGMEM = "bbb";
3
const char menu2[] PROGMEM = "ccc";
4
const char menu3[] PROGMEM = "ddd";
5
const char menu4[] PROGMEM = "ddd";
6
7
const char * const menu[5] PROGMEM = 
8
{
9
  menu0,
10
  menu1,
11
  menu2,
12
  menu3,
13
  menu4
14
};

Ich bekomme
1
warning: only initialized variables can be placed into program memory area
und Garbage am Display, obwohl mein LCD-Code mit
1
lcd_p(PSTR("foo"))
einwandfrei klappt, nicht aber mit
1
lcd_p(menu[0]); /* oder */ lcd_p(&menu[0])


Danke für Tipps,

pit

von Clemens M. (panko)


Lesenswert?

Wenn du das Menu nicht ins rom packst sondern ins ram, also nicht const, 
sollte das klappen.

Wenn das menu auch im rom liegen soll, musst du die Adresse erst mit 
pgm_read_word() holen. Analog dazu wie du die eigentlichen Strings 
einliest.

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=38003&start=all&postdays=0&postorder=asc

hier ist das sicherlich leichter verständlich dargestellt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von ●● pit ●. (Gast)


Lesenswert?

Danke & danke.

Mit Euren beiden antworten scheint es nun ohne warning zu kompilieren.
werd ich morgen mal zuhause flashen und sehen ob es klappt.

Greetings,

pit
1
// ----------------------------------------------------------- 
2
// To avoid g++'s warnings, place data in program memory into 
3
// a custom code section prefixed my ".progmem." 
4
//
5
#define CxxPSTR __attribute((section(".progmem.menudata")))
6
7
const char Menu0[] CxxPSTR = "Settings";
8
const char Menu1[] CxxPSTR = "Calibrate Hi";
9
const char Menu2[] CxxPSTR = "Calibrate Lo";
10
const char Menu3[] CxxPSTR = "°C to Shutdown";
11
const char Menu4[] CxxPSTR = "°C to Start Fan";
12
13
const char * const MainMenu[5] CxxPSTR = 
14
{
15
  Menu0,
16
  Menu1,
17
  Menu2,
18
  Menu3,
19
  Menu4
20
};
21
22
const uint8_t menuMax = 4;
23
24
// Usage:
25
lcd_text_p(1, 1, DEFAULT_FONT, (const char *)pgm_read_word(&MainMenu[menuCursor]));

von Rolf P. (rolfp)


Lesenswert?

pit p. schrieb:
> Mit Euren beiden antworten scheint es nun ohne warning zu kompilieren.
> werd ich morgen mal zuhause flashen und sehen ob es klappt.
>

Und, hat es geklappt?

> // -----------------------------------------------------------
> // To avoid g++'s warnings, place data in program memory into
> // a custom code section prefixed my ".progmem."
> //
> #define CxxPSTR __attribute((section(".progmem.menudata")))
>

Leider verstehe ich das nicht. Wie macht man denn so eine Section?
Hast du vielleicht noch das gesamte Programm?

Mich nerven die vielen Warnungen inzwischen auch.

Rolf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf Pfister schrieb:

>> #define CxxPSTR __attribute((section(".progmem.menudata")))
>
> Leider verstehe ich das nicht. Wie macht man denn so eine Section?

Du kannst einfach
1
#include <avr/pgmspace.h>
2
3
#undef  PROGMEM
4
#define PROGMEM __attribute__((section(".progmem.data")))

> Mich nerven die vielen Warnungen inzwischen auch.

Oder du kannst auf eine supportete GCC-Version umsteigen.

Die älteste noch unterstützte GCC-Version ist die 4.6.
PR34734 ist in 4.6.2 und neueren Versionen behoben.

Wenn du die aktuelle gcc-Version verwendest geht auch __flash und man 
braucht kein pgm_read_xxx mehr.

von Rolf P. (rolfp)


Lesenswert?

Johann L. schrieb:
>
> Du kannst einfach
>
1
> #include <avr/pgmspace.h>
2
> 
3
> #undef  PROGMEM
4
> #define PROGMEM __attribute__((section(".progmem.data")))
5
>
>
Leider funktioniert das bei mir nicht. Es gibt dann solche Fehler:
error: str368 causes a section type conflict

>
> Die älteste noch unterstützte GCC-Version ist die 4.6.
> PR34734 ist in 4.6.2 und neueren Versionen behoben.
>
Dann werde ich mal versuchen so eine neue Version zu installieren.


> Wenn du die aktuelle gcc-Version verwendest geht auch __flash und man
> braucht kein pgm_read_xxx mehr.

Schau ich mir mal genauer an, wenn ich die neue Version habe.


Danke für die Hinweise
Rolf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rolf Pfister schrieb:
> Johann L. schrieb:
>> #undef  PROGMEM
>> #define PROGMEM __attribute__((section(".progmem.data")))
>>
> Leider funktioniert das bei mir nicht. Es gibt dann solche Fehler:
> error: str368 causes a section type conflict

Liegt evtl. daran, daß du Daten mit unterschiedlichen Section-Flags 
mischst, zB daten die read-only sind mit solchen die schreibbar sind.

Schreibbare Daten in progmem sind nicht wirklich sinnvoll.

Ändert sich was mit -f[no-]data-sections ?

von Rolf P. (rolfp)


Lesenswert?

Johann L. schrieb:
> Liegt evtl. daran, daß du Daten mit unterschiedlichen Section-Flags
> mischst, zB daten die read-only sind mit solchen die schreibbar sind.
>

Tatsächliche, in dieser Zeile war das zweite const verloren gegangen:
1
const char* const mgtabelle[] PROGMEM =

Da die erste Fehlermeldung schon einige Zeilen weiter oben gekommen ist,
bin ich nicht so schnell drauf gekommen.
Jetzt funktioniert es also ohne Warnungen.

Rolf

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
Noch kein Account? Hier anmelden.