Hi,
ist es beim GCC irgendwie möglich, strings ähnlich komfortabel wie
gewohnt an funktionen zu übergeben, aber sie im flash zu speichern?
so à la
funktion_die_mit_flash_stringkonstanten_umgehen_kann(PROGMEM
"Stringkonstante im Flash");
wenn nein, geht dann nur folgendes:
const char PROGMEM temp[] = "Stringkonstante im Flash";
funktion_die_mit_flash_stringkonstanten_umgehen_kann(temp);
wenn ich an einer ganz anderen Stelle im Code in einem ganz anderen
Block irgendwo nochmal die gleiche Stringkonstante nutze:
const char PROGMEM temp[] = "Stringkonstante im Flash";
andere_funktion(temp);
wird das dann wie gewohnt vom Compiler optimiert oder legt der das dann
doppelt im Flash ab? Ansonsten müsste ich ganz am Anfang eine Tabelle
mit sämtlichen Stringkonstanten anlegen und könnte auf diese dann nur
noch über z.B. Tabelle[3] zugreifen, wodurch ich im Code überhaupt nicht
mehr sehe, was da in der Tabelle an der entsprechenden Stelle nun
drinsteht.. ziemlich unkomfortabel.
Die Stringkonstanten sind übrigens für ein LCD gedacht.
lg PoWl
Ah danke das ist ja genau das, was ich gesucht habe.
Leider optimiert der Compiler das nicht so, dass gleiche Strings
zusammengefasst werden sondern doppelt im Flash abgelegt werden.
Gibts da einen Workaround?
Paul Hamacher schrieb:> Leider optimiert der Compiler das nicht so, dass gleiche Strings> zusammengefasst werden sondern doppelt im Flash abgelegt werden.
Wieso machst Du das überhaupt so?
Es reicht doch den String einmal zu definieren und in Deinen anderen
c-Files über extern bekannt zu machen.
Ich bin jetzt nicht sooo der C-Guru, kannst du mir das erläutern? ;)
übrigens handelt es sich um eine einzige C-File. Falls du meinst, dass
ich die Stringkonstante einmal irgendwo definiere und dann fortan über
ihre Variable darauf zugreife: das will ich ja gerade durch Benutzung
von PSTR vermeiden
Ich habe für mein LCD eine State-Machine mit Menüstrukturen. Hin und
wieder kommt es halt vor, dass da identische Textzeilen ausgegeben
werden sollen und wenn es möglich ist, soll der Compiler das erkennen
und hierfür einen gemeinsamen Speicherplatz im Flash benutzen anstatt
die Strings doppel im Flash abzulegen.
Ist halt komfortabler für mich beim Programmieren und da es sich sowieso
um Konstanten handelt das einzig richtige.
Zumindest folgendes kleines Beispiel funktioniert mit avr-gcc 4.7:
1
#include<avr/pgmspace.h>
2
3
constchar*volatilep;
4
5
intmain(void)
6
{
7
p=PSTR("Hallo");
8
p=PSTR("nochmal Hallo");
9
return0;
10
}
mit -Os -fmerge-all-constants wird daraus:
1
main:
2
ldi r24,lo8(__c.1515)
3
ldi r25,hi8(__c.1515)
4
sts p+1,r25
5
sts p,r24
6
ldi r24,lo8(__c.1517)
7
ldi r25,hi8(__c.1517)
8
sts p+1,r25
9
sts p,r24
10
ldi r24,0
11
ldi r25,0
12
ret
13
14
.section .progmem.data.str1.1,"aMS",@progbits,1
15
__c.1515:
16
.string "Hallo"
17
__c.1517:
18
.string "nochmal Hallo"
Die beiden String-Literale liegen in der gleichen Section und haben das
gleiche Alignment. Zusätzlich ist das erste Literal Suffix des zweiten;
sie könne also gemergt werden.
objdump zeigt das:
Ooooookay ich verstehe noch nicht so ganz wie ich den GCC 4.7
installieren kann bzw wo ich ihn überhaupt herbekomme. Kann mir da
jemand auf die Sprünge helfen?
GCC ist ein Open Source Projekt, d.h. es werden die Quellen releast, für
GCC 4.7.1 zB
http://gcc.gnu.org/ml/gcc/2012-06/msg00198.html
ftp://ftp.gnu.org/gnu/gcc/gcc-4.7.1/
Daraus generiert ma sich dann passende Executables für die gewünschten
Sprachen (C, C++, Ada, Java, Fortran, ...) das gewünschte OS (Wondows,
Linus, hp-ux, Mac OS, Solaris, ...) und die gewünschte Zielarchitektur
(AVr, ARM, PowerPC, x86, ...)
Weil das vielen zu komplizier ist, gibt's auch fertige Toolchains, und
mit etwas Glück findest du eine wo alle Parameter zu deinen
Anforderungen passen.
avr-gcc-4.7.1 für Windows zB da verlnks und erklärt:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=963192#963192
Und immer auch die Release-Notes lesen!
http://gcc.gnu.org/gcc-4.7/changes.html