Compiliert man das Ganze als C-Code werden sämtliche Strings wie
erwartet im Flash abgelegt, als C++ Code hingegen nur die markierten.
Zudem gibt es dabei für bar und bar4 folgende Warnung:
Ein Blick ins Listing zeigt auch das nur bar und bar4 in .progmem.data
verschoben wurden, bar2 und 3 liegen noch in .data
1
71 .LBE2:
2
72 .LFE2:
3
74 .section .progmem.data,"a",@progbits
4
77 _ZL3bar:
5
78 0000 426C 7562 .string "Blub"
6
78 00
7
79 .data
8
82 _ZL4bar2:
9
83 0000 426C 6100 .string "Bla"
10
86 _ZL4bar3:
11
87 0004 4865 6C6C .string "Hello World"
12
87 6F20 576F
13
87 726C 6400
14
88 .section .progmem.data
15
91 _ZL4bar4:
16
92 0005 4861 6C6C .string "Hallo Welt"
17
92 6F20 5765
18
92 6C74 00
Hat jemand eine Idee was genau dort falsch läuft bzw. wo man ansetzen
muss um das zu beheben?
Getestet ist das mit einem GCC 4.3.3 unter Ubuntu aus dem Build-Script
von avrfreaks.net. Im Anhang ist das vollständige Test-Projekt.
Grüße
Fabian
>> Compiliert man das Ganze als C-Code werden sämtliche Strings wie> erwartet im Flash abgelegt, als C++ Code hingegen nur die markierten.> Zudem gibt es dabei für bar und bar4 folgende Warnung:>>
> Hat jemand eine Idee was genau dort falsch läuft bzw. wo man ansetzen> muss um das zu beheben?
Es werden in
./gcc/config/avr/avr.c:avr_handle_progmem_attribute()
ein paar Fälle nicht behandelt. Von dort kommt auch die Warnung.
http://gcc.gnu.org/viewcvs/trunk/gcc/config/avr/avr.c?revision=148689
Was das DECL_EXTERNAL da soll seh ich jetzt auch nicht...
Lösung:
avr-gcc debuggen und rausfinden, wie der tree genau aussieht. Den Fall
behandlen, ein Patch machen und in einer passenden gcc- oder
avr-libc-Maillingliste posten.
Johann
@A. N.
In der Tat, wenn ich die ganzen Definitionen nach diesem Schema umforme
funktioniert es ohne Warnung:
1
externconstcharbar[]PROGMEM;
2
constcharbar[]="Blub";
So richtig schön ist die Lösung aber leider auch nicht, vor allem weil
alle Variablen damit global angelegt werden müssen.
> Die Lösung dafür stand irgendwo mal bei den Freaks.
Du meinst vermutlich diesen Thread hier:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=57011
Johann L. schrieb:
> Lösung:> avr-gcc debuggen und rausfinden, wie der tree genau aussieht. Den Fall> behandlen, ein Patch machen und in einer passenden gcc- oder> avr-libc-Maillingliste posten.
Hmm, ich habe gerade mal in die avr.c rein geschaut, befürchte aber das
ich da nicht so schnell durchsteige was dort genau passiert. Dazu fehlt
mir einfach das komplette Wissen über die Interna des GCC.
Grüße
Fabian
Fabian G. schrieb:
> Johann L. schrieb:>> Lösung:>> avr-gcc debuggen und rausfinden, wie der tree genau aussieht. Den Fall>> behandlen, ein Patch machen und in einer passenden gcc- oder>> avr-libc-Maillingliste posten.>> Hmm, ich habe gerade mal in die avr.c rein geschaut, befürchte aber das> ich da nicht so schnell durchsteige was dort genau passiert. Dazu fehlt> mir einfach das komplette Wissen über die Interna des GCC.
In dem Falle macht man einen aussagekräftigen Bug-Report nachdem man
sich versichert hat, daß nicht bereits einer gemacht wurde. Da das
Problem bei den Freaks wohlbekannt ist, ist letzteres nicht
unwahrscheinlich.
Im übrigen brauch's das ganze prog_-Typ-Gerüffel garnicht. Die Lösung
mit PROGMEM funktioniert doch sowohl für extern als auch für static:
1
#include<stdint.h>
2
3
typedefstruct
4
{
5
uint8_ta,b;
6
}data_t;
7
8
externconstcharstring1[];
9
externconstdata_tdata;
10
11
// end of header
12
13
#include<avr/pgmspace.h>
14
15
constcharstring1[]PROGMEM="abc";
16
staticconstcharstring2[]PROGMEM="def";
17
18
constdata_tdataPROGMEM={1,2};
19
staticconstdata_tdata0PROGMEM={3,4};
20
21
constchar*foo(void)
22
{
23
returnstring2+pgm_read_byte(&data0.b);
24
}
Ausserdem will man eh nicht für jede Struktur/Union eigene Typen
definieren mit Ausprägungen für EEPROM, RAM und Flash.
> non sunt multiplicanda entia sine necessitate
oder wie die Angelsachsen sagen würden: avoid name space pollution ;-)
Johann
Johann L. schrieb:
> In dem Falle macht man einen aussagekräftigen Bug-Report nachdem man> sich versichert hat, daß nicht bereits einer gemacht wurde. Da das> Problem bei den Freaks wohlbekannt ist, ist letzteres nicht> unwahrscheinlich.
Es gibt zum Beispiel schon die folgenden:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40112> Im übrigen brauch's das ganze prog_-Typ-Gerüffel garnicht.
Das ist richtig, waren jetzt hier auch nur zum Testen drinnen.
> Die Lösung mit PROGMEM funktioniert doch sowohl für extern als auch für static:
Der vorgeschlagene Workaround aber leider nicht:
1
#include<avr/pgmspace.h>
2
3
externconstcharstring1[]PROGMEM;
4
constcharstring1[]="Blub";
5
6
int
7
main(void)
8
{
9
charfoo[20];
10
11
memcpy_P(foo,string1,sizeof(bar));
12
13
{
14
staticconstcharstring2[]PROGMEM="Bla";
15
16
memcpy_P(foo,string2,sizeof(bar));
17
}
18
}
Erzeugt für string2 die Warnung, für string1 aber nicht. Und man kann
string2 ja schlecht als "extern static" deklarieren.
Johann L. schrieb:
1
>#include<avr/pgmspace.h>
2
>
3
>typedefstruct
4
>{
5
>uint8_ta,b;
6
>}data_t;
7
>
8
>externconstcharstring1[];
9
>externconstdata_tdata;
10
>
11
>constcharstring1[]PROGMEM="abc";
12
>
13
>staticconstcharstring2[]PROGMEM="def";
14
>
15
>constdata_tdataPROGMEM={1,2};
16
>staticconstdata_tdata0PROGMEM={3,4};
17
>
18
>constchar*foo(void)
19
>{
20
>returnstring2+pgm_read_byte(&data0.b);
21
>}
Wenn man dies durch den avr-g++ schickt spuckt er halt die Warnung aus,
obwohl aber korrekter Code erzeugt wird.
1
Compiling C++: main.cpp
2
main.cpp:11: warning: only initialized variables can be placed into program memory area
3
main.cpp:13: warning: only initialized variables can be placed into program memory area
4
main.cpp:15: warning: only initialized variables can be placed into program memory area
5
main.cpp:16: warning: only initialized variables can be placed into program memory area
@Fabian:
Ich sammel alle Strings die thematisch zusammen passen in einer CPP
Datei + Header. Den Header includiere ich dann nur in der CPP Datei in
der die Strings gebraucht werden. Damit sind sie nicht wirklich global,
da man ja von anderen CPP Dateien nicht darauf zugreifen kann.
Aber du hast schon recht, schöner wäre es schon, wenn es auch so klappen
würde wie in C. :)
Fabian G. schrieb:
> Johann L. schrieb:>> Die Lösung mit PROGMEM funktioniert doch sowohl für extern als auch für static:>> Der vorgeschlagene Workaround aber leider nicht:>>
1
#include<avr/pgmspace.h>
2
>
3
>externconstcharstring1[]PROGMEM;
4
>constcharstring1[]="Blub";
5
>
6
>int
7
>main(void)
8
>{
9
>charfoo[20];
10
>
11
>memcpy_P(foo,string1,sizeof(bar));
12
>
13
>{
14
>staticconstcharstring2[]PROGMEM="Bla";
15
>
16
>memcpy_P(foo,string2,sizeof(bar));
17
>}
18
>}
>> Erzeugt für string2 die Warnung, für string1 aber nicht. Und man kann> string2 ja schlecht als "extern static" deklarieren.
Ich bekomme da einen Fehler:
1
error: `bar' was not declared in this scope
Wenn ich das behebe, dann wird das ohne Warnung übersetzt und der Code
ist korrekt. Sowohl für avr-g++ 3.4.6 als auch avr-g++ 4.3.2 und
zusammen mit -W -Wall.
> Johann L. schrieb: [c]>> #include <avr/pgmspace.h>>>>> [snip weil Foren-Software meckert]> Wenn man dies durch den avr-g++ schickt spuckt er halt die Warnung aus,> obwohl aber korrekter Code erzeugt wird.>>
1
Compiling C++: main.cpp
2
> main.cpp:11: warning: only initialized variables can be placed into
3
> program memory area
4
> ...
Auch diese Warnungen bekomme ich mit den genannten g++-Version nicht.
Johann
Johann L. schrieb:
> Ich bekomme da einen Fehler:>
1
error: `bar' was not declared in this scope
Ähm, ja, klassischer Copy-Paste und noch was geändert Fehler.
> Wenn ich das behebe, dann wird das ohne Warnung übersetzt und der Code> ist korrekt. Sowohl für avr-g++ 3.4.6 als auch avr-g++ 4.3.2 und> zusammen mit -W -Wall.
Hmm, ein avr-g++ 4.3.3 erzeugt bei mir die Warnungen. Könntest du mal
versuchen das Ganze mit dem Makefile aus dem ersten Beitrag zu
compilieren?
Grüße
Fabian
Fabian G. schrieb:
> Hmm, ein avr-g++ 4.3.3 erzeugt bei mir die Warnungen. Könntest du mal> versuchen das Ganze mit dem Makefile aus dem ersten Beitrag zu> compilieren?
Das compiliert mit 4.3.2 ohne Warnung, für 3.4.6 gibt es unbekannte
Optionen.
Die Warnungen kommen erst wenn .dep/main.o.d existiert
Johann