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.
Paul Hamacher schrieb: > 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? Siehe http://gcc.gnu.org/PR43746 verfügbar ab 4.7. Ist aber noch etwas holprig, siehe -fmerge-all-constants und http://gcc.gnu.org/PR50739 Siehe auch die 4.7 Release-Notes: http://gcc.gnu.org/gcc-4.7/changes.html
Zumindest folgendes kleines Beispiel funktioniert mit avr-gcc 4.7:
1 | #include <avr/pgmspace.h> |
2 | |
3 | const char * volatile p; |
4 | |
5 | int main (void) |
6 | {
|
7 | p = PSTR ("Hallo"); |
8 | p = PSTR ("nochmal Hallo"); |
9 | return 0; |
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:
1 | Disassembly of section .text: |
2 | |
3 | ... |
4 | |
5 | 00000026 <__c.1517>: |
6 | 26: 6e 6f 63 68 6d 61 6c 20 nochmal |
7 | |
8 | 0000002e <__c.1515>: |
9 | 2e: 48 61 6c 6c 6f 00 Hallo. |
10 | |
11 | ... |
12 | |
13 | 00000056 <main>: |
14 | 56: 8e e2 ldi r24, 0x2E ; 46 |
15 | 58: 90 e0 ldi r25, 0x00 ; 0 |
16 | 5a: 90 93 61 00 sts 0x0061, r25 |
17 | 5e: 80 93 60 00 sts 0x0060, r24 |
18 | 62: 86 e2 ldi r24, 0x26 ; 38 |
19 | 64: 90 e0 ldi r25, 0x00 ; 0 |
20 | 66: 90 93 61 00 sts 0x0061, r25 |
21 | 6a: 80 93 60 00 sts 0x0060, r24 |
22 | 6e: 80 e0 ldi r24, 0x00 ; 0 |
23 | 70: 90 e0 ldi r25, 0x00 ; 0 |
24 | 72: 08 95 ret |
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.