Servus, AVR-Studio meldet mir dass das .data Segment 288Byte groß ist. Das stimmt auch mit dem Angehängten Ausschnitt aus dem Map-File zusammen: .data start 0x60, ende 0x180. Darin sind zwei nicht mit 0 initialisierte globale Variablen, was belegt jedoch den Speicher im Bereich 0x70 bis 0x180?
Hast du Strings in deinem Programm? Die werden vom Flash ins RAM kopiert um drauf zugreifen zu koennen.
Unter anderem: *(.rodata) .rodata 0x00800070 0x35 main.o *(.rodata*) .rodata.str1.1 Vermutlich ein String oder mehrere, definiert in Zeile 42 von main.c
JOs schrieb: > was belegt > jedoch den Speicher im Bereich 0x70 bis 0x180? Irgendwelche Konstanten, wahrscheinlich auch Strings, worauf .rodata.str1.1 hindeutet.
Helmut L. schrieb: > Hast du Strings in deinem Programm? Die werden vom Flash ins RAM kopiert > um drauf zugreifen zu koennen. Unsinn.
Nop schrieb: > Unsinn. Nop schrieb: > Irgendwelche Konstanten, wahrscheinlich auch Strings, worauf > .rodata.str1.1 hindeutet. Schreibst doch selber oder gibt es zwei NOPs?
Nop schrieb: > Unsinn. Gehts auch genauer? http://www.atmel.com/webdoc/AVRLibcReferenceManual/mem_sections_1sec_dot_data.html
Helmut L. schrieb: > Schreibst doch selber oder gibt es zwei NOPs? Ah, Mißverständnis. Mit dem Auszug aus dem Handbuch:
1 | char err_str[] = "Your program has died a horrible death!"; |
Das ist korrekt, das wird ins RAM kopiert. Weil es eine vorinitialisierte Variable ist. Was ich angenommen hatte, war der direkte Gebrauch von String-Konstanten. Was weiß ich, etwas wie:
1 | send_uart("Das ist ein String"). |
Das würde nicht ins RAM kopiert werden, das meinte ich.
Wie schon geschrieben liegen in der .data Sektion im RAM Sachen wie:
1 | static int a = 5; |
oder auch
1 | char *s = "Hallo"; |
Das ist allerdings das Standardverhalten. Hast du was umgebogen?
Nop schrieb: > Was ich angenommen hatte, war der direkte Gebrauch von > String-Konstanten. Was weiß ich, etwas wie: > send_uart("Das ist ein String"). Das landet zuerst im Flash, wird aber dann erstmal ins RAM kopiert. Der AVR ist nun mal ein Harvard-Architektur.
Und der Punkt ist, daß der Speicherverbrauch hier eben nicht in der .data-Sektion auftritt, sondern in .rodata. Das erste Beispiel, was tatsächlich ins RAM kopiert würde, würde aber nicht in .rodata den Platz belegen, sondern in .data. Demzufolge muß es sich um Stringkonstanten handeln wie in meinem zweiten Beispiel, weil die in .rodata landen. Und deswegen ist es in diesem Fall Unsinn, daß die ins RAM kopiert würden. Was ins RAM kopiert wird, sind die Variablen version und weekdays, aber nicht die Strings.
Helmut L. schrieb: > Das landet zuerst im Flash, wird aber dann erstmal ins RAM kopiert. Was, das auch?! OK, dann verhält der GCC sich da in der Tat deutlich anders, als ich es von überall sonst her kenne, und somit liegt der Unsinn dann bei mir. :-)
Nop schrieb: > Was, das auch?! Troeste dich, ich bin da vor Jahren auch mal drauf reingefallen als ich das noch nicht wusste. Da wurde auch das RAM knapp.
Nop schrieb: > Und deswegen ist es in diesem Fall Unsinn, daß die ins RAM kopiert > würden. Das kann ich kaum glauben ... Die Benutzung der Flash-Read-Befehle für RO-Daten muss explizit sein ... Wenn du im Code nichts dergleichen ´ala PROGMEM angibst, passiert genau das, was andere gesagt haben ... Die RO-Daten werden vom Flash ins RAM kopiert.
Danke für die Antworten! - Ich habe tatsächlich einige Stringkonstanten im Code. Kann man davon ausgehen dass nur diese unbenannten Stringkonstanten in .rodata liegen, denn wären es irgenwelche Variablen sollte auch der Variablenname dabei stehen oder nicht? Ich sehe gerade dass version und weekdays als const deklariert sind, trotzdem liegen sie in .data und nicht in .rodata warum? Zu PROGMEM: Wie kann man einen direkt genutzten String z.B. print("Test") mit PROGMEM im Flash behalten? Oder muss ich dafür eine Variable string1 mit PROGMEM spezifizieren und dann übergeben print(string1)?
JOs schrieb: > Zu PROGMEM: Wie kann man einen direkt genutzten String z.B. > print("Test") mit PROGMEM im Flash behalten? Oder muss ich dafür eine > Variable string1 mit PROGMEM spezifizieren und dann übergeben > print(string1)? Es gibt da Stringfunktionen die mit Strings direkt aus dem Flash arbeiten koennen. Schau dir mal die Doku zur "pgmspace.h" datei an. Diese Funktionen enden alle mit _P im Funktionsnamen.
JOs schrieb: > Danke für die Antworten! - Ich habe tatsächlich einige Stringkonstanten > im Code. Je nach Optimierungslevel des Compilers kann das auch noch ungünstig werden, wenn Du die mit defines angelegt hast. Die werden ja textmäßig nach dem Präprozessor dupliziert, und ob der Compiler diese identischen Strings dann wieder zusammenfaltet, muß man gucken. Insbesondere, wenn Du die defines in einem Headerfile hast, welches Du in verschiedene C-Files einbindest, kann das haarig werden. Wenn Du das stattdessen als globale Variable anlegst, kann es sich unabhängig vom Optimierungslevel nicht aufblähen. > Kann man davon ausgehen dass nur diese unbenannten > Stringkonstanten in .rodata liegen, denn wären es irgenwelche Variablen > sollte auch der Variablenname dabei stehen oder nicht? Genau. > Ich sehe gerade dass version und weekdays als const deklariert sind, > trotzdem liegen sie in .data und nicht in .rodata warum? 1) const besagt nicht, daß etwas nach rodata gehen muß. Das kann der Compiler so machen, wenn er will, aber laut C-Standard versprichst Du damit dem Compiler lediglich, daß Du auf diese Variablen nur lesend zugreifst. 2) wenn die Daten ohnehin vor dem Gebrauch ins RAM kopiert werden müssen, wegen der Harvard-Architektur, dann ergibt es Sinn, sie nach data zu linken, genau wie vorinitialisierte nicht-const-Variablen.
Hie rnoch ein Link, der auch ein Wort zum Thema const enthält, sowie Strings und AVR: http://www.nongnu.org/avr-libc/user-manual/pgmspace.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.