Hallo, ich arbeite gerade an einem recht speicher-aufwändigen Projekt und hätte gern mal gewusst, ob es eine Möglichkeit den maximal benötigten Speicher eines Programms bestimmen zu lassen (evtl. auch inkl. dynamisch allokierten Speicher per malloc()). Nun gibt es ja beim Kompilieren mit dem avr-gcc die "AVR Memory Usage"-Ausgabe und da gibt mir die "Data"-Angabe Auskunft über den (statischen) Speicherverbrauch. Doch was genau bedeutet diese Angabe? Ist Sie das Maximum? Ist da schon Platz für Rücksprungadressen, Parameter, etc. mit einkalkuliert? Ich hoffe ich konnte mein Anliegen einigermaßen klar vermitteln ;) Gruß Sven
Der statische Speicherverbrauch ist der statische Speicherverbrauch. Der enthält nur die globalen und statischen Vaiablen, sonst nichts. Alles, was erst zur Laufzeit auf dem Stack oder heap angelegt wird, ist da nicht enthalten. Eine einfache rechnderische Methode, den dynamischen Speicherbedarf zu bestimmen, gibt es nicht. Da hilft nur, entweder von Hand den worst-case zu ermitteln, oder zur Laufzeit Stack und heap zu überwachen. Oliver
Gesamten speicher auf einen bestimmten wert initialisieren, programm laufen lassen und danach schaun, bis wohin der Speicher geändert wurde. Von oben müsste der Stack Daten geändert haben, von unten der Heap. Irgendwo zwischendrin gibts ungeänderte Bytes. Benedikt hat in der Codesammlung auch mal ein kleines Tool veröffentlich um den RAM-verbrauch zu berechnen. Heißt glaub ich Stack Viewer. Aber ich weiß nicht, ob das mit malloc umgehen kann, denke aber ehr nicht. Der Stack ist aber drin, solange du keine Rekursion verwendest. Sebastian
MoinMoin, ich hatte bei der Implementierung meines AVR-BASIC-Interpreters mal ein ähnliches Verlangen und wollte herausbekommen, wie so die Speicherbelegung in bestimmten Situationen ist. Nach einigem Rumsuchen im Netz ist dies entstanden (zusammenkopiert) worden:
1 | #include <avr/io.h> // RAMEND |
2 | #include "mem_check.h" |
3 | |
4 | // Mask to init SRAM and check against
|
5 | #define MASK 0xaa
|
6 | |
7 | // From linker script
|
8 | extern unsigned char __heap_start; |
9 | |
10 | unsigned int |
11 | get_mem_free (void) |
12 | {
|
13 | return SP - (uint16_t) &__heap_start; |
14 | }
|
15 | |
16 | unsigned short |
17 | get_mem_unused (void) |
18 | {
|
19 | unsigned short unused = 0; |
20 | unsigned char *p = &__heap_start; |
21 | |
22 | do
|
23 | {
|
24 | if (*p++ != MASK) |
25 | break; |
26 | |
27 | unused++; |
28 | } while (p <= (unsigned char*) RAMEND); |
29 | |
30 | return unused; |
31 | }
|
32 | |
33 | /* !!! never call this function !!! */
|
34 | void __attribute__ ((naked, section(".init3"))) init_mem (void); |
35 | void init_mem (void) |
36 | {
|
37 | __asm volatile ( |
38 | "ldi r30, lo8 (__heap_start)" "\n\t" |
39 | "ldi r31, hi8 (__heap_start)" "\n\t" |
40 | "ldi r24, %0" "\n\t" |
41 | "ldi r25, hi8 (%1)" "\n" |
42 | "0:" "\n\t" |
43 | "st Z+, r24" "\n\t" |
44 | "cpi r30, lo8 (%1)" "\n\t" |
45 | "cpc r31, r25" "\n\t" |
46 | "brlo 0b"
|
47 | :
|
48 | : "i" (MASK), "i" (RAMEND+1) |
49 | );
|
50 | }
|
Dabei liefert get_mem_free() den derzeit freien Speicher zwischen Stack und Heap. get_mem_unused() liefert die Speichergröße, die noch nicht "angerührt" wurde. Allerdings funktioniert dies dann aber nicht mehr, wenn man mal malloc() aufgerufen hat, weil dann das initialisierte Pattern am "Ram-Ende" überschrieben wird. Grüße Uwe
Besten Dank für die Antworten. Ich werde das mal ausprobieren! Gruß Sven
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.