Vermutlich ist es ein lächerliches Anfängerproblem (AVRGCC und ATmega8): Ich habe ein globales eindimensionales array aus uint8_t in dem ich Zeichen ablegen will. Irgendwie habe ich den Verdacht, daß der Inhalt des arrays (und eines weiteren, lokalen) von irgendwo sinnfrei verändert wird. ganz so als würde da eine andere Variable im gleichen Speicherbereich liegen. Das erste: warum bekomme ich bei volatile die Warnung "warning: passing arg 1 of `strncmp' discards qualifiers from pointer target type" etc. Dann: Wieso wird der nach dem compilieren angezeigte Speicherplatzbedarf nicht verändert, wenn ich das array größer dimensioniere? Wie kann ich dann wissen, wie groß mein belegter Speicher ist, denn ich gehe ganz eng an das limit: AVR Memory Usage: ----------------- Device: atmega8 Program: 7984 bytes (97.5% Full) (.text + .data + .bootloader) Data: 782 bytes (76.4% Full) (.data + .bss + .noinit) Ist irgendwas falsch daran, global uint8_t buffer[200] zu schreiben und dann lokal buffer[x]='a' oder so zu machen?
> Das erste: warum bekomme ich bei volatile die Warnung "warning: passing > arg 1 of `strncmp' discards qualifiers from pointer target type" etc. Wahrscheinlich wird char* erwartet und ein pointer auf unsigned char/uint8_t uebergeben. > Dann: Wieso wird der nach dem compilieren angezeigte Speicherplatzbedarf > nicht verändert, wenn ich das array größer dimensioniere? Wie kann ich > dann wissen, wie groß mein belegter Speicher ist, denn ich gehe ganz eng > an das limit: > ... > Ist irgendwas falsch daran, global > uint8_t buffer[200] > zu schreiben und dann lokal > buffer[x]='a' > oder so zu machen? Nachgeschaut, ob buffer mglw. wegoptimiert wird, da vielleicht nie daraus gelesen wird? (Würde ich als bekennender lss/Disassembly Leser darin suchen). Im Zweifel könnte man volatile uint8_t test; test=buffer[0]; ausprobieren.
Ron wrote: > Das erste: warum bekomme ich bei volatile die Warnung "warning: passing > arg 1 of `strncmp' discards qualifiers from pointer target type" etc. Weil strncmp für "normale" char Arrays/Pointer definiert ist. Für volatile müsste man eigentlich eine eigene strncmp-Routine schreiben. Dadurch, dass Du das normale strncmp benutzt, umgehst Du ja die spezielle Codeerzeugung, die der Compiler sonst für volatile macht. > Dann: Wieso wird der nach dem compilieren angezeigte Speicherplatzbedarf > nicht verändert, wenn ich das array größer dimensioniere? Wie kann ich > dann wissen, wie groß mein belegter Speicher ist, denn ich gehe ganz eng > an das limit: Tja, keine Ahnung, sollte eigentlich nicht passieren. Trivialprogramm hier:
1 | char buf[7000]; |
2 | |
3 | int main(void) { return 0; } |
Liefert bei mir (laut avr-size):
1 | torsten@pulsar:~$ avr-gcc t.c |
2 | torsten@pulsar:~$ avr-size a.out |
3 | text data bss dec hex filename |
4 | 100 0 7000 7100 1bbc a.out |
Ist natürlich nicht Win-AVR, k.A., welches Tool da für diese Grössenangabe verwendet wird. Also: Mach daraus mal ein Trivialbeispiel, damit wir das reproduzieren/wiederlegen können. Gruss aus Dresden, Torsten
avr-size liefert auch unter WinAVR richtige Werte. Wenn sich die Größe des data-segments (da drin wird buffer als globale Variable angelegt) nicht ändert, stimmt was anderes nicht. Schau mal ins map-file, ob dein buffer drin auftaucht, und wie groß das Feld dort ist. Und zeig mal deinen Code. Wenn du neben den globalen Variablen auch noch große lokale Variablenfelder anlegst, gibt es Probleme. Oliver
OK, wenn ich aber da kein volatile bei einer globalen Variable angebe, kann es ja sein, daß in einer Funktion Mist bei raus kommt. Spielt es eigentlich irgendeine Rolle, ob ich unsigned char oder uint8_t benutze? Ich habe das Trivialprogramm erstellt und es liefert das erwartete Ergebnis: Die Data Speicherbelegung ändert sich - also bin ich (noch) nicht ganz Meschugge. Aber! Bei meinem eigentlichen Programm passiert das nur, wenn ich bei der globalen Variable die Größe ändere. Das habe ich wohl irgendwie bei meinen bisherigen Tests übersehen. Es ändert sich aber nicht die Data Speicherbelegung bei einem lokal in einer Funktion angelegtem array. Auch nicht, wenn ich es mit ={0, ...} initialisiere :-(
>Es ändert sich aber nicht die Data >Speicherbelegung bei einem lokal in einer Funktion angelegtem array. >Auch nicht, wenn ich es mit ={0, ...} initialisiere :-( Je nun, da die zur Laufzeit angelegt werden, weiss avr-size nichts davon. Und damit dürfte auch dein Problem erklärt sein - der Stack läuft über. Oliver
>Schau mal ins map-file, ob dein buffer drin auftaucht, und wie groß das >Feld dort ist. Wow. Was für eine schicke Datei. Noch nie reingeschaut. Aber ja, da ist mein buffer und dahinter steht 0xc8. Also genau meine 200. >Wenn du neben den globalen Variablen auch noch >große lokale Variablenfelder anlegst, gibt es Probleme. Wieso ist das so? Soll ich die lokalen großen (ab wann ist etwas groß?) arrays dann lieber auch globalisieren?
Ron wrote: >>Schau mal ins map-file, ob dein buffer drin auftaucht, und wie groß das >>Feld dort ist. > > Wow. Was für eine schicke Datei. Noch nie reingeschaut. Aber ja, da ist > mein buffer und dahinter steht 0xc8. Also genau meine 200. > >>Wenn du neben den globalen Variablen auch noch >>große lokale Variablenfelder anlegst, gibt es Probleme. > > Wieso ist das so? Soll ich die lokalen großen (ab wann ist etwas groß?) > arrays dann lieber auch globalisieren? Ein zweischneidiges Schwert. Auf der einen Seite hast du mit globalen Variablen den Vorteil, dass dir der Linker die exakte verbrauchte Speichermenge dieser Variablen ausrechnen kann und dich vor Überlauf warnen kann. Auf der anderen Seite ist aber die dynamische Speicherauslastung mit funktionslokalen Variablen besser, da sich mehrere Variablen denselben Speicher teilen können. Dafür weiß wiederum niemand im Vorfeld wieviel Speicher insgesamt verbraucht wird, weil das ja auch von der Schachtelung der Funktionsaufrufe abhängt.
Wobei >Data: 782 bytes (76.4% Full) >(.data + .bss + .noinit) mal gerade noch 254 byte SRAM für Stack (und lokale Variablen) lässt. Je nachdem, wieviele lokal in einer Funktion angelegten arrays und Variablen jetzt noch dazukommen, reicht das, oder auch nicht. >Irgendwie habe ich den Verdacht, daß der Inhalt >des arrays (und eines weiteren, lokalen) von irgendwo sinnfrei verändert >wird. ganz so als würde da eine andere Variable im gleichen >Speicherbereich liegen. Das ist normalerweise ein untrügliches Zeichen dafür, das es nicht reicht. Oliver
OliverSo wrote: >>Irgendwie habe ich den Verdacht, daß der Inhalt >>des arrays (und eines weiteren, lokalen) von irgendwo sinnfrei verändert >>wird. ganz so als würde da eine andere Variable im gleichen >>Speicherbereich liegen. > > Das ist normalerweise ein untrügliches Zeichen dafür, das es nicht > reicht. Könnte natürlich auch ein Out-of-bounds Zugriff in einem Array sein.
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.