Moin,
ich habe ein Programm für einen ATmega16 geschrieben (AVR-GCC & AVR
Studio4 4.18). Nach einem Build erhalte ich unten stehende Meldung.
Mein Programm läuft scheinbar einwandfrei.
Aber wie kann es sein, das der Datenspeicher zu 127.1% voll ist? Oder
wie muss diese Info verstehen?
Gruß
Matthias
----------------
Device: atmega16
Program: 14124 bytes (86.2% Full)
(.text + .data + .bootloader)
Data: 1302 bytes (127.1% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...
---------------
Im Datenblatt steht:
Nonvolatile Program and Data Memories
– 16K Bytes of In-System Self-Programmable Flash
Endurance: 10,000 Write/Erase Cycles
– Optional Boot Code Section with Independent Lock Bits
In-System Programming by On-chip Boot Program
True Read-While-Write Operation
– 512 Bytes EEPROM
Endurance: 100,000 Write/Erase Cycles
– 1K Byte Internal SRAM
– Programming Lock for Software Security
Hi
>Mein Programm läuft scheinbar einwandfrei.
Wie du schon schreibst, scheinbar. Bei dieser Auslastung ist z.B. kein
Platz mehr für den Stack, d. H. die Variablen, die in diesem Bereich
sind, enthalten entweder Rücksprungadressen oder irgendwann springt dein
Programm nicht nehr an die vorgesehene Adresse zurück, weil das
Beschreiben der Variablen den Stack verändert. Du solltest dich von
einigen Daten trennen oder einen anderen Speicher ansprechen.
Gruß oldmax
>1K ist wohl 1024 Bytes also sind 1302 127% davon.
dessen bin ich mir durchaus bewusst. Ich frage mich nur, wie ich 127%
Daten in 100% Speicher bekommen???
Hätte erwartet, dass der Compiler zumindest eine Warnung ausgibt.
oldmax schrieb:> Hi>>Mein Programm läuft scheinbar einwandfrei.> Wie du schon schreibst, scheinbar. Bei dieser Auslastung ist z.B. kein> Platz mehr für den Stack, d. H. die Variablen, die in diesem Bereich> sind, enthalten entweder Rücksprungadressen oder irgendwann springt dein> Programm nicht mehr an die vorgesehene Adresse zurück, weil das> Beschreiben der Variablen den Stack verändert. Du solltest dich von> einigen Daten trennen oder einen anderen Speicher ansprechen.> Gruß oldmax
So etwas in der Art habe ich vermutet. Mit Anderen Worten: Das Programm
läuft 100 mal und beim 101 mal wundere ich mich, finde den Fehler nicht,
weil der C-Code richtig ist, aber im Speicher etwas undefiniertes
passiert ist.
Gruß
Matthias
Matthias R. schrieb:> So etwas in der Art habe ich vermutet. Mit Anderen Worten: Das Programm> läuft 100 mal und beim 101 mal wundere ich mich,
Wenns nur so einfach wäre.
Es ist eher so, dass dein Programm in manchen Funktionalitäten ganz gut
funktioniert, während andere Funktionalitäten manchmal überhaupt nicht
funktionieren. Dazu kommen unerklärliche Abstürze etc.
Matthias R. schrieb:>>1K ist wohl 1024 Bytes also sind 1302 127% davon.> dessen bin ich mir durchaus bewusst. Ich frage mich nur, wie ich 127%> Daten in 100% Speicher bekommen???> Hätte erwartet, dass der Compiler zumindest eine Warnung ausgibt.
Woher soll der Compiler denn das wissen?
Der sieht doch das komplette Programm überhaupt nicht.
Wenn schon, dann könnte das der Linker machen, denn der baut das
Programm zusammen.
Aber zum Schluss kommt doch die Speicherstatistik raus, in der sieht man
es ohnehin. Als Programmierer hat man eben auch ein wenig Verantwortung
sich selber um Dinge zu kümmern.
hm, gibt zwar immer besondere Fälle, die mehr RAM brauch als üblich,
aber normalerweise komme ich mit dem Verhältnis ROM/RAM gut zurecht.
Typischer Anfängerfehler: Variable alle global anlegen. Die verbrauchen
dann den entsprechenden Speicherplatz dauerhaft. Lokale Variable
(solange sie nicht static sind) sparen RAM, da deren Speicherplatz nach
Verlassen der Funktion wieder freigegeben wird und für andere benutzt
werden kann, also Mehrfachnutzung.
Kommt auch auf den Compiler an: lokale Variable werden oft in einem Teil
der Register untergebracht, braucht dann gar keinen RAM und schneller
ist es auch noch.
Karl heinz Buchegger schrieb:> Wenn schon, dann könnte das der Linker machen, denn der baut das> Programm zusammen.
1:0 für dich ;-) der Compiler kann es wirklich nicht wissen.
> Als Programmierer hat man eben auch ein wenig Verantwortung> sich selber um Dinge zu kümmern.
Seit wann denn das? Ich bin immer davon ausgegangen, dass mein Computer
erahnt, was ich mir denke, und mein Programm dahin optimiert.
**KneifAugeZuUndGrinseEinWenigIronisch**
H.joachim Seifert schrieb:> Kommt auch auf den Compiler an: lokale Variable werden oft in einem Teil> der Register untergebracht, braucht dann gar keinen RAM und schneller> ist es auch noch.
Wie der Compiler was im einzelnen macht, muss ich (da
Gelegenheitsprogrammierer) jetzt gar nicht bis ins einzelne wissen.
Es ist aber so, dass ich mit dem jetzigen Programm ein nicht zu
unterschätzendes Problem erzeugt habe. Ich werde also die
Speicherauslastung unter die 100% "drücken".
Danke allen für die Infos
Gruß
Matthias
Matthias R. schrieb:>> Als Programmierer hat man eben auch ein wenig Verantwortung>> sich selber um Dinge zu kümmern.> Seit wann denn das? Ich bin immer davon ausgegangen, dass mein Computer> erahnt, was ich mir denke, und mein Programm dahin optimiert.> **KneifAugeZuUndGrinseEinWenigIronisch**
Den 'Do what I mean'-Modus gibts erst in der übernächsten
Windows-Version :-)
Bis dahin werden die 'Profis' auch weiterhin den Inhalt dieser kleinen
bunten Fensterchen lesen, bei denen Normalsterbliche einfach auf OK
drücken, weil sie Computer ja sowieso nicht verstehen ("Ja, da war so
eine Fehlermeldung, ich hab die einfach weggedrückt - Nein, was da
gestanden hat weiß ich nicht mehr, hab ich auch gar nicht gelesen" -
Grrrrr)
:-)
> Es ist aber so, dass ich mit dem jetzigen Programm ein nicht zu> unterschätzendes Problem erzeugt habe. Ich werde also die> Speicherauslastung unter die 100% "drücken".
Hast du viele konstante Texte?
Da ist meistens hohes Potential vorhanden, mit dem man ziemlich schnell
und einfach massig SRAM-Speicher sparen kann.
> Speicherauslastung unter die 100% "drücken".
Die solltest Du deutlich(!) unter 100% drücken. Denn in der vom Linker
angegebenen Größe ist der Stack nicht drinnen. Und dort liegen alle
dynamischen Variablen. Da können auch mal 80% schon zuviel sein.
Peter
Karl heinz Buchegger schrieb:> Hast du viele konstante Texte?
Ja, meine ganzen Debug-Infos laufen über konstante Texte in Klartext z.B
"neuer String empfangen".
Ich kann die Debug-Infos über ein Debug-Flag ein/ausschalten.
1
if(Flags&DebugFlag){// Schleife für Debugging durch Flag aktivieren
2
uart_puts("neuer String empfangen");
3
...// Variablenwert ausgeben
4
}
Ich bau das gerade so um, das ich die Debug-Info über
1
#if (DEBUGFLAG == 1)
2
{
3
....
4
}
5
#endif
ein/ausschalten kann.
Dann habe ich jeweils nur den Teil Code im Programm, den ich per define
aktiviere.
1
#define DEBUGFLAG 0 // 0: keine Debug-Info, 1: Debug-Info
In der Release Software ist dann alle Debug-Info aus.
Ist doch richtig, oder? (Habe #if / #endif noch nie verwendet.)
Gruß
Matthias
Matthias R. schrieb:> In der Release Software ist dann alle Debug-Info aus.> Ist doch richtig, oder? (Habe #if / #endif noch nie verwendet.)
Schon.
Aber du zäumst das Pferd von der falschen Seite auf.
Lass die Texte alle im Flash, dort sind sie sowieso schon, und bau dir
eine Ausgabefunktion, die die Texte aus dem Flash laden kann, anstelle
von aus dem SRAM.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29
Und schon brauchst du da nicht mehr mit #ifdefs rumspielen.
Kannst du natürlich machen, weil man in der Regel ja nicht alle
Debug-Infos braucht. Aber zum Speichersparen ist das unnötig.
if(Flags&DebugFlag){// Schleife für Debugging durch Flag aktivieren
4
uart_puts_p(PSTR("neuer String empfangen"));
5
...// Variablenwert ausgeben
6
}
und der Text "neuer String empfangen" belegt dir keinen Speicher im SRAM
mehr.
richtig schön wird das dann noch mit einem Makro
1
#define uart_puts_P(s) uart_puts_p(PSTR(s))
denn dann brauchst du nur noch in
1
uart_puts("neuer String empfangen");
den Funktionsaufruf ändern zu
1
uart_puts_P("neuer String empfangen");
und der String bleibt im Flash und wird auch von dort ausgegeben.
Und wieder 23 Bytes SRAM gespart. Bei 10 Strings in dieser Größenordnung
sind das immerhin rund 230 Bytes oder ca. 20% vom SRAM. Und das alles
ohne Einbussen. Das lohnt also!
Karl heinz Buchegger schrieb:> und bau dir eine Ausgabefunktion, die die Texte aus dem Flash> laden kann, anstelle von aus dem SRAM.> void uart_puts_p( const char* text )
Ich benutze ja die lib von Peter Fleury - da ist doch eine uart_puts_p
Funktion enthalten.
Ich benutze also für Konstante Texte uart_puts_p und wenn ich zB. den
Inhalt einer Variablen ausgebe uart_puts (nach Konvertierung in einen
String) bzw. uart_putc (für 8Bit Variablen).
Und mit der #if Variante habe ich nur die Texte von dem Programmteil im
Flash, an dem ich gerade "rumspiele".
Danke für die Hilfe.
Gruß
Matthias
Matthias R. schrieb:> Karl heinz Buchegger schrieb:>> und bau dir eine Ausgabefunktion, die die Texte aus dem Flash>> laden kann, anstelle von aus dem SRAM.>> void uart_puts_p( const char* text )> Ich benutze ja die lib von Peter Fleury - da ist doch eine uart_puts_p> Funktion enthalten.
Na was willst du mehr?
Die Fleury Lib hat m.W. auch das Makro zur einfachen Verwendung bereits
fertig mit.
Es lag also nur daran, dass man sich eine ins Projekt geholte Lib auch
mal genauer ansehen sollte und zumindest die Header File durchstöbern
:-)
> Ich benutze also für Konstante Texte uart_puts_p und wenn ich zB. den> Inhalt einer Variablen ausgebe uart_puts (nach Konvertierung in einen> String) bzw. uart_putc (für 8Bit Variablen).
Yep.
> Und mit der #if Variante habe ich nur die Texte von dem Programmteil im> Flash, an dem ich gerade "rumspiele".
Yep.
Allrdings: Flash hast du normalerweise genug. SRAM wird meistens eher
knapp als Flash. Aber in Zukunft wird sich das drehen :-)
Karl heinz Buchegger schrieb:> Allerdings: Flash hast du normalerweise genug. SRAM wird meistens eher> knapp als Flash. Aber in Zukunft wird sich das drehen :-)
Wie cool ist das denn. Nur durch ein paar "_P" an die uart_puts und
lcd_puts angehängt, bin ich von 127.1% auf 81.1%.
Da habe ich ja jetzt wieder massig Platz für globale Variablen ;-)
Danke noch mal allen für die Hilfe. Besonders Dir KhB. Ein gesegnetes
Weihnachtsfest und rutscht gut nach 2011.
Gruß
Matthias