Forum: Compiler & IDEs printf_P aus Flash funktioniert scheinbar nicht


von Andreas Paulin (Gast)


Lesenswert?

@ all the Gurus in here:

Config: ATMEGA128, AVR-GCC, AVRStudio

Problem: SRAM voll, printf_P könnte Abhilfe schaffen, aber die 
printf-Ausgabestrings werden trotz printf_P anscheinend ins RAM kopiert.

Die 4K SRAM sind langsam voll, mapfile sagt:
1
"0x00800db9                PROVIDE (__bss_end, .)"

und ich bekomme seltsame Probleme-> Stackkollision liegt nahe.

Der Speicherfresser:
Im Projekt ist eine große Debug_Funktion, in einem eigenem Quellfile, 
die in main() ggfs eingebunden wird:
1
#ifdef DEBUG_DEV_PAULIN  
2
  // Testversion Paulin
3
  DebugFunc_Paulin();
4
#endif
So. In dieser Debugfunktion hats einen Haufen printf's, deren 
Format/Ausgabestrings meines Wissens beim Startup ins SRAM kopiert 
werden und dort genutzt werden. Und Speicher fressen......
Um hier SRAM zu sparen gibts die 'printf_P' Version, die aus dem Flash 
heraus arbeitet. Auch klar....
DebugFunc_Paulin() frisst aber IMMER ~ 1KSRAM, egal, ob ich die printf_P 
Versionen einsetze oder die normal printf.

Und weiter: Selbst ein auskommentieren der Funktion
1
#ifdef DEBUG_DEV_PAULIN  
2
  // Testversion Paulin
3
  //DebugFunc_Paulin();
4
#endif

hindert den Linker scheints nicht daran, sie komplett einzubinden, denn 
ich finde immer im Mapfile die kleine Zeile:
 .data          0x008005bc      0x496 DebugCode_Paulin.o

's isch aber doch auskommentiert....! heul

Nur komplettes Entfernen des Quellfiles aus dem Projekt bringts.

Wie kriege ich die printf_P richtig an den Start und 1K RAM eingespart?
Und wie kriege ich den Linker dazu, garnicht verwendete Funktionen auch 
nicht einzubinden?

von Andreas Paulin (Gast)


Lesenswert?

Oha......... Zusatz:
Die printf_P-Versionen geben nur wirres Zeug aus .....@?&&%rgfQ@@
Zurück zu printf funktionierts wieder.....

Riecht nach irgendwas ganz Grundsätzlichem....aber wo ist da jetzt der 
Kardinalfehler...?

von Johannes M. (johnny-m)


Lesenswert?

Afaik können die _P-Varianten nur die unteren 64 kB des Flash 
adressieren. Es muss also gewährleistet sein, dass die betreffenden 
Strings in den unteren 64 kB liegen.

von Andreas Paulin (Gast)


Lesenswert?

@ Johannes: OK, da ist was dran...
aber wir haben weniger als 64K. Mapfile sagt:

0x00005c5e                _etext = .
na, das sind ca 25kByte...

von Rolf Magnus (Gast)


Lesenswert?

Ohne zu sehen, was du machst, ist es schwer zu sagen, was daran falsch 
ist.

von holger (Gast)


Lesenswert?

>Die printf_P-Versionen geben nur wirres Zeug aus .....@?&&%rgfQ@@

Versuchs mal mit PSTR("Hallo !")

von holger (Gast)


Lesenswert?

Nachtrag:

printf_P(PSTR("Hallo !"));

von Andreas Paulin (Gast)


Lesenswert?

@holger: Hei, Du bist mein HELD!! Das wars :)

Ich dachte, wenn die printf_P-Version verwendet wird, wird das 
Umkopieren der Strings aus dem Flash ins SRAM automatisch unterdrückt.
Muss man auch wissen, dass die Formatstrings auch noch explizit im Flash 
festgenagelt werden müssen....... die Doku sagt da recht knapp:
"Variant of printf() that uses a fmt string that resides in program 
memory."

Aber nirgendwo der Hinweis "use PSTR"..

von Rolf Magnus (Gast)


Lesenswert?

> Ich dachte, wenn die printf_P-Version verwendet wird, wird das
> Umkopieren der Strings aus dem Flash ins SRAM automatisch unterdrückt.

Nein. Wenn der Compiler die Stringkonstante sieht, ist ihm alles andere 
erstmal egal. Wenn er den Funktionsaufruf sieht, weiß an der Stelle auch 
nur, daß printf_P einen Zeiger auf const char haben will. Daß die 
Funktion intern diesen Zeiger nutzt, um auf Flash zuzugreifen, ist dem 
Compiler dagegen nicht bekannt.

> Aber nirgendwo der Hinweis "use PSTR"..

Das ist ja auch nichts Spezielles für printf_P, sondern gilt allgemein 
für Strings, die im Flash stehen sollen.

von Andreas Paulin (Gast)


Lesenswert?

OK, danke für die Info. Ist klarer jetzt.
Um den Linker, der linkt, obwohl er nicht zu linken braucht, kümmer ich 
mich später. Hab jetzt erstmal wieder Platz im SRAM :-))

von mthomas (Gast)


Lesenswert?

1
#define myprintf(fmt, ...) printf_P(PSTR(fmt), ##__VA_ARGS__)

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.