Hi, ich habe hier ein kleines Embedded-Board das ohne MMU oder virtuellem Speicher daherkommt und rein bare-metal in ANSI-C programmiert wird. Der zu benutzende Speicher wird in meiner Applikation zu Beginn einmalig mit diversen malloc()s alloziiert. Jetzt habe ich folgendes Problem: Über das Linker-Command-File ist der Heap mit einer bestimmten Größe festgelegt. Wie viel Speicher durch die verschiedenen malloc()s geholt wird, kann ich mir ausrechnen und auf Basis dessen ermitteln, wie viel da tatsächlich noch übrig ist. Aber: ich hätte gerne eine Möglichkeit, um beides zu verifizieren - ob meine Heap-Definition im Linkerfile und meine angenommene Speicherbelegung richtig ist. Wie kann ich das (gerne auch nur in einer DEBUG-Version, die nicht ausgeliefert wird) am besten machen? Gibt es eine ANSI-C-Funktion, welche mir in so einem Szenario den noch verfügbaren Heap ausspuckt? Danke!
Üblicherweise laufen Stack und Heap aufeinander zu. Du vergleichst dann einfach die Adressen der lokalen Variablen mit den Pointern, die malloc() liefert. Kannst auch eine kleine Test-Funktion schreiben, die rekursive Aufrufe und mallocs() macht, bis die Grenzen erreicht sind. Normalerweise überschreibt der Stack ohne jede Warnung den Heap.
@ Donk (Gast) >zu benutzende Speicher wird in meiner Applikation zu Beginn einmalig mit >diversen malloc()s alloziiert. Dann braucht man auch kein malloc sondern kann alle Speicherbereiche statisch als globale Variablen definieren, dann sieht man auch direkt wieviel Speicher beötigt wird.
Donk schrieb: > Der > zu benutzende Speicher wird in meiner Applikation zu Beginn einmalig mit > diversen malloc()s alloziiert. Kannst du darauf nicht verzichten und die Variablen fest anlegen?
Falk B. schrieb: > Dann braucht man auch kein malloc sondern kann alle Speicherbereiche > statisch als globale Variablen definieren, dann sieht man auch direkt > wieviel Speicher beötigt wird. Es sei denn ich habe dynamisch unterschiedliche Konfigurationen, die ich erst beim Booten ermitteln kann und die jeweils andere Speichergrößen benötigen.
Das ist bei einem fest verbautem µC eher ungewöhnlich. Und auch dann kann man meist mit fixen Strukturen und Union arbeiten
U. F. schrieb: > Und auch dann kann man meist mit fixen Strukturen und Union arbeiten In diesem Fall geht es um Ringbuffer mit unterschiedlichen Größen und unterschiedlichen gepufferten Strukturen. Klar, irgendwie kann man alles immer irgendwie in Unions mit Arrays mit verschachtelten Strukturen mit eingebetteten Hühnerknochen mit gecastetem Schneckenschleim verfrickeln, aber das Ganze soll ja auch noch les- und wartbar bleiben. Und da sind ein paar mallocs() ausschließlich am Programmstart meiner Meinung nach das weitaus kleinere Übel.
Nunja.... Dein malloc() wird irgendwo eine verkettete Liste bilden. Diese sollte man auswerten können.
Noch einer schrieb: > Kannst auch eine kleine Test-Funktion schreiben, die rekursive Aufrufe > und mallocs() macht, bis die Grenzen erreicht sind. Das scheint mir auch die beste Lösung zu sein - Danke!
Ich würde auch mit malloc antesten, wie viel Speicher zu belegen kannst - allerdings in einer Schleife, nicht nicht rekursiv. Fange mit der maximalen RAM Größe minus 1/8 an. Wenn das geht, gib den Speicher wieder frei un liefere die Größe als Testergebnis zurück. Wenn es nicht geklappt hat, reduziere den Wert wieder um 1/8. So tastest du dich schrittweise an den richtigen Wert heran, wobei die Schritte immer kleiner werden. Abbruchbedingung für die Schleife: Wenn die Zahl nach dem Subtrahieren kleiner als 8 ist, breche den test ab und melde "RAM voll". Bedenke, dass das freie RAM auch fragmentiert sein kann. Mit dieser Schleife erhälst du (ungefähr) den größten Zusammenhängenden Block. Darüber hinaus könnten aber auch noch kleinere Speicherblöcke verfügbar sein. Für eine grobe Abschätzung, ob genug RAM frei ist, reicht das meistens jedoch.
Stefan U. schrieb: > Fange mit der maximalen RAM Größe minus 1/8 an. Und woher kennt man die maximale RAM Größe? Man muss das System kennen. Dann kann man aber auch für das eigentliche Problem die Systemfunktionen nehmen.
Dann kannst Du Dir Dein malloc auch ganz einfach selbst schreiben, in dem Du einen Zeiger auf den Anfang des heaps initialisiert und mit jeder Allozierung um den allozierten Speicher weiter bewegst. Die Differenz zwischen dem Zeiger und dem Ende des Heaps ist dann der noch freie Speicher. Alles andere ist nur gerate und hängt sehr stark von der Implementierung des Heaps ab.
Torsten R. schrieb: > in > dem Du einen Zeiger auf den Anfang des heaps initialisiert wie macht man das (Code)?
Dumdi D. schrieb: > Torsten R. schrieb: >> in >> dem Du einen Zeiger auf den Anfang des heaps initialisiert > > wie macht man das (Code)? in etwa so, wenn Du den heap zwischen __HEAP_START und __HEAP_END legst.
1 | #include <stdlib.h> |
2 | |
3 | extern char __HEAP_START; |
4 | extern char __HEAP_END; |
5 | |
6 | static char const * heap_end = &__HEAP_END; |
7 | static char const * heap_top = &__HEAP_START; |
8 | |
9 | void* allocate_memory( size_t s ) |
10 | {
|
11 | void* result = 0; |
12 | |
13 | if ( heap_end - heap_top >= s ) |
14 | {
|
15 | result = (void*)heap_top; |
16 | heap_top += s; |
17 | }
|
18 | |
19 | return result; |
20 | }
|
Im Fall von AVR unf svg-gcc geht das so nicht. Denn dort beginnt der Heap an einem Ende des Speichers und der Stack am anderen Ende. Wenn sie wachsen, treffen sich Heap und Stack irgendwo in der Mitte. Beide Speicherbereiche haben keine feste Größe. Siehe http://www.nongnu.org/avr-libc/user-manual/malloc.html
Stefan U. schrieb: > Im Fall von AVR unf svg-gcc geht das so nicht. Denn dort beginnt der > Heap an einem Ende des Speichers und der Stack am anderen Ende. Wenn sie > wachsen, treffen sich Heap und Stack irgendwo in der Mitte. Beide > Speicherbereiche haben keine feste Größe. Das ist bei sehr vielen Controllern so. Selbst wenn head und stack keine von Dir fest definierte Größe haben, wirst Du Dir Gedanken darüber machen wollen, wie groß Dein Stack sein muss. Und nach dem Du Dir die Gedanken gemacht hast, hält Dich auch niemand davon ab, dem Stack eine feste Größe zu geben. Der Rest ist dann statischer Speicher plus Heap.
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.