Hallo! Ich brauche mal ein wenig Hilfe. Es geht um folgendes: Ich möchte genau wissen wieviel Speicher mein Programm verbraucht. Bis jetzt glaube ich folgendes zu wissen: Alle meine globalen Variablen (also nicht ge- malloc'te Sachen die irgendwo in den Headern rumfliegen) müssen ja eh immer im RAM liegen, d.h. der Verbrauch ist schon zu Compile Zeit bekannt. Sehe ich das richitg, dass ich die Größe über die Werte .data 154 8388704 + .bss 44 8388858 raus bekomme? Also hier 154+44. Was ist der Unterschied zwischen .data und .bss? Die Werte sind in Byte? Jetzt kommt der kompliziertere Teil: Sachen die zur Laufzeit mit malloc allokiert werden. Ich könnte natürlich durch den Code gehen und per Hand zählen, aber da das ganze ein Laufzeitsystem mit mehreren Prozessen ist, könnte das unübersichtlch werden, daher wollte ich gerne in meinem Debug Kompilat eine memstat() Routine einbauen, die ie Größe des Heap über die serielle Schnittstelle ausgibt. Ich habe "Using malloc()" sowie die malloc() Beschreibung aus der avr-libc Doku gelesen und mit wenig Erfolg versucht Variablen wie __malloc_heap_start o.ä per sprintf zu formatieren und rauszugeben. Das ganze mit recht wenig Erfolg :( Das Ziel ist sowas wie: "Heap beginnt an Adresse xx und endet bei yyy." Geht das überhaupt mit der libc, oder müsste ich mir dazu eine eigene Speicherverwaltung schreiben bzw. malloc/free wrapper die mit zählen? So, das war lang, aber vielleicht hat jemand einen Tipp für mich! MfG Sebastian
> Was ist der Unterschied zwischen .data und .bss? Müßte eigentlich sogar in der Doku stehen: .data sind die initialisierten Daten, .bss die nichtinitialisierten Daten (genauer: die Bereiche, die beim Start ausgenullt werden sollen). Käme noch .noinit hinzu, muß explizit angefordert werden (via _attribute_), verhält sich wie .bss, wird aber gar nicht initialisiert, so daß es einen Reset des Controllers überlebt. > Die Werte sind in Byte? Ja, die GNU-Tools messen immer alles in Bytes, egal, ob die CPU 8-, 16-, 32- oder 64-bittig orientiert ist. Die Wordomanie von Atmel ist sowieso nicht zu verstehen, besonders wenn man bedenkt, daß LPM & Co. am Ende wieder byteorientiert sind. > Jetzt kommt der kompliziertere Teil: Sachen die zur Laufzeit mit > malloc allokiert werden. Noch komplizierter: den Stackverbrauch ermitteln. Außer der Methode: ,,ich beschreibe den RAM erstmal mit 42 und sehe dann regelmäßig nach, bis wohin der Stack das wieder überschrieben hat'' gibt's kaum eine Variante, wie man den Stackverbrauch so recht ausrechnen kann. Für malloc() haben auch andere Leute schon nach einem API gefragt, wie man statistische Daten zurückbekommen kann. Da muß ich mir mal was einfallen lassen... Derzeit haben die dazu benutzten Variablen `static linkage' innerhalb von malloc.c, d. h. sie sind zwar für Debugger einsehbar, nicht aber für den Rest der Applikation. Das wird sich zwar ändern, wenn ich mal dazu komme, meine realloc()- Implementierung endlich einzubringen (dann müssen die entsprechenden Variablen zwischen mehreren Bibliotheksmodulen kommunziert werden können, damit können sie keine static linkage mehr haben), aber ich möchte dennoch nicht erst einreißen lassen, daß Applikationen sich auf Interna der Bibliotheksimplementierung verlassen und stattdessen lieber ein offizielles API für diesen berechtigten Wunsch realisieren. Vorschläge, was in so ein API alles reinkommen kann, werden gern entgegengenommen. Außer der höchsten durch malloc() beanspruchten Speicheradresse kann ich mir noch vorstellen, daß die Leute an der Menge an Speicher interessiert sein könnten, der sich auf der free list angesammelt hat, um so ein Gefühl zu bekommen, wie sich die Fragmentierung über die Zeit entwickelt. Derzeit bleibt wohl als einzige Variante, daß Du Dir malloc.c aus dem Quellcode der Bibliothek rausziehst und testhalber in Deine eigene Applikation reinnimmst. Dann kannst Du die entsprechenden Variablen für Dich intern veröffentlichen. (Es ist insbesondere brkval, was Dich da interessiert.)
Hallo! Danke für die Antworten. Jetzt weiß ich zumindest, dass ich die Möglichkeit nicht übersehen habe. brkval war genau dass, was mich interessierte; ich hatte bloß keinen Erfolg ranzukommen :) Von "static linkage" hatte ich auf Grund meiner mittelprächtigen C Kenntnisse noch nix gehört... Was den Stackverbrauch angeht: Ich kann aber doch jederzeit im Programm schauen, wo der Stackpointer steht? Was die Erweiterung der malloc Implementatierung mit einem Statisktik API angeht: Das würde ich sehr begrüßen. Ich hoffe, dich packt demnächst irgendwann die Motivation :) MfG Sebastian
Hi das zyklische Prüfen des Stackpointer bringt spätestens beim Einsatz von INT's keine exakten Ergebnisse mehr. Besser ist, wie Jörg das schon schrieb, das komplette SRAM mit einem bestimmten Bitmuster zu beschreiben und irgendwann mal zu schauen bis wohin dieses Bitmuster noch existiert. Matthias
Hi! Ja, das ist klar. Das Prüfen des SP kann ja nur einen "Momentaufnahme" sein. Den Höchststand findet man so natürlich nicht. In diesem Falle ging es mir dann auch eher um eine ungefähre Vorstellung davon, bis wohin der Stack reicht und ob ich so ca. 30 Bytes oder 2 KB Luft zwischen Stack und Heap habe. Ich denke mal man bewegt sich hier irgendwann in Bereiche, wo man ohne aufwendigere Simulationen des Gesamtsystems nicht mehr weiter kommt. MfG Sebastian
Hallo, gibt es hier nach fast 1,5Jahren inzwischen neues? Wenn ich das richtig sehe ist realloc() ja inzwischen dazugekommen, aber brkval kennt der Compiler weiterhin nicht. Ich bin bisher soweit, dass SP periodisch in einem Interrupt aufgerufen wird und der minimale Wert in einer Variable gespeichert wird und bei der Displayausgabe hiervon noch __malloc_heap_start abgezogen wird. Bisherige Erkentnis: 2KB RAM reichen bei meiner Anwendung, bei 1KB RAM könnte es aber eventuell Probleme geben.
brkval heißt jetzt __brkval und ist global, damit solltest du (undokumentiert) darauf zugreifen können. Ich hätte nichts gegen ein memstat()-Interface oder sowas, allerdings müssten sich interessierte ,,Kunden'' da erstmal äußern, was da alles genau drin sein soll. Was nicht geht: die gerade belegten Speicherblöcke durchlaufen, zählen usw. Was geht: die größe des derzeitigen Heap ermitteln, die gerade freigegebenen Blöcke durchzählen usw. Die Differenz zwischen beiden wäre dann die Gesamtspeichermenge der gerade aktiven Blöcke.
__brkval kennt er bei mir nicht. Ich vermute avr-libc 1.2.3 einfach schon zu alt :-)
Doch, realloc() ist in allen 1.2er Versionen dabei. Natürlich darfst du nicht erwarten, dass __brkval irgendwo für dich deklariert wäre ;-), es gehört ja zu den Systeminterna und ist daher nicht offiziell exportiert. Wie geschrieben, ich bin für Vorschläge für ein memstat() offen (dann aber bitte auf der avr-libc-dev Liste). extern char *__brkval; ist die intern benutzte Deklaration (aber das hast du sicher im Sourcecode inzwischen selbst nachgelesen wink).
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.