Überprüfen des Speicherbedarfs in Arduino

7

Ich arbeite mit meinem Arduino an einem einfachen Projekt. Vor kurzem musste ich eine meiner Variablen in eine lange anstelle einer int konvertieren, und um die Dinge einfach zu halten, habe ich einfach alle Zahlen verschoben, mit denen sie interagiert (damit ich mich nicht um typübergreifende Vergleiche und Gedanken kümmern muss andere Mathematik). Das scheint verschwenderisch, aber es ist nur eine Uhr für mich, und es ist mir egal.

Ich habe mich jedoch gefragt, wie viel Speicher ich verwende. Ich bezweifle, dass es sich um ein Problem handelt, aber mir wurde klar, dass ich keine Möglichkeit zur Überprüfung kenne.

Gibt es eine Möglichkeit, die von einem Arduino verwendete Speichermenge zu überprüfen?

Im Idealfall möchte ich den aktuellen Speicher / die Gesamtsumme ausdrucken, die über die serielle Verbindung verfügbar ist.

MrGlass
quelle
Übrigens habe ich dies früher bei stackoverflow gefragt ( stackoverflow.com/q/8649174/502816 ) und die einzige Empfehlung, die ich erhalten habe, war, hier zu fragen
MrGlass

Antworten:

8

Ein Großteil des Arduino-Materials wird darunter gehandhabt. Sie werden sehen, wie viel FLASH-Speicher eine Skizze (Programm) beim Kompilieren benötigt, nicht jedoch die Größe des SRAM-Speichers. Ich musste das kürzlich auch entdecken, und so habe ich es gemacht.

Im Arduino IDE-Verzeichnis befindet sich der avr-gcc-Compiler. Es enthält auch ein Tool namens "avr-size". Gehen Sie zu Hardware / Tools / avr / bin / und es sollte dort sein.

Beim Kompilieren erstellt die IDE ein temporäres Verzeichnis in Ihrem temporären Verzeichnis und kopiert alle C (++) - Dateien in dieses Verzeichnis. Es kompiliert die Bibliotheken, Ihre Skizze (es fügt auch die erforderlichen Dinge hinzu, um sie funktionsfähig zu machen) und erstellt eine Hex- und Elf-Datei. Sie müssen lediglich Ihre Skizze kompilieren (indem Sie entweder auf Hochladen oder auf Überprüfen klicken) und in Ihrem temporären Ordner nach einem Build-Verzeichnis [Hash-Tag] suchen. Sie müssen avr-size.exe ausführen und die Elf-Datei übergeben.

Es ist eine ziemlich mühsame Konsolenarbeit, aber ich navigiere normalerweise zum Ordner bin, führe avr-size.exe aus und gebe den Pfad zu meinem temporären Ordner ein. Dies ist C: \ Benutzer [Ihr Benutzername] \ AppData \ Local \ Temp \ build [zufälliges Tag] [Skizzenname] .cpp.elf (Windows 7)

Sie könnten wahrscheinlich ein (Batch-) Skript dafür erstellen, aber da der Build-Ordner bei jeder Arduino-Sitzung konstant bleibt, stört mich das nicht.

Die Ausgabe von avr-size sieht dem sehr ähnlich (ich habe ein Xbee-Beispielprogramm kompiliert). Konsolenausgabe

Wo:

  • Text - Flash-Daten, die für Code verwendet werden
  • Daten - Speicher mit initialisierten Daten (der Anfangswert muss auch in FLASH gespeichert werden!)
  • bss - Speicher, der mit Nullen initialisiert wird (der Compiler fügt Code hinzu, damit Daten & bss initialisiert werden).
  • dec & hex sind eine dezimale und hexadezimale Anzeige der kombinierten RAM- und FLASH-Größe Ihres Programms.

Die Arduino IDE, die mir gemeldet wurde, dass dieses Programm 3956 Bytes groß ist (FLASH). Dies bezieht sich auf 3924 (Code-Flash) + 32 (anfängliche RAM-Werte) = 3956 Byte FLASH. Die RAM-Nutzung ist Daten + BSS kombiniert (!) = 32 + 320 = 352 Byte SRAM-Nutzung.

Beachten Sie, dass der ATMEGA328 nur 2 KB SRAM hat und Probleme bereits auftreten können, wenn Sie darunter liegen (ich hatte unerwartetes Verhalten bei 1700 Bytes von 2048). Der ATMEGA168 verfügt über 1 KB SRAM. Alle Arduino-Megas haben 8 KB SRAM.

Als zusätzliche Anmerkung. Es gibt auch den Code "Free Memory Indicators". Sie versuchen, so viel Speicher wie möglich zuzuweisen, zu zählen, wie groß er war, und ihn freizugeben (malloc () & free ()). Wenn Sie malloc anfangs noch nicht verwendet haben, wird Ihrem Programm mehr Code hinzugefügt, für den Sie manchmal keinen Platz haben. Dies ist nicht ideal und ich habe auch nicht festgestellt, dass es stabile Ergebnisse liefert. In meinem eigenen Projekt hatte ich Ethernet + xbee + SD-Karte + eigenen Bibliothekscode auf einem Atmega328. Es war einfach nicht genug SRAM verfügbar und FLASH wurde ebenfalls knapp.

Und last but not least berücksichtigt dieser Indikator nicht den mit malloc () zugewiesenen Speicher.

Hans
quelle
Das ist also die theoretische RAM-Zuordnung, die die kompilierte App haben wird? interessant. Ich hoffe immer noch, dass es eine Methode gibt, um den zugewiesenen RAM einfach in eine Skizze zu ziehen.
MrGlass
2
Dies ist eine gute Antwort für feste RAM-Zuweisungen. Es ist jedoch wichtig zu wissen, dass der von automatischen Variablen lokal für eine Funktion oder einen Block verwendete RAM nicht gezählt wird, die zu Beginn der Ausführung dieser Funktion auf dem Stapel zugewiesen und am freigegeben werden Ende. Dies kann nur durch Ausführen (oder Simulieren) eines bestimmten Pfads durch das Programm festgestellt werden. Mit Rekursions- oder Funktionszeigern kann eine pathologische Situation verschachtelter Funktionsaufrufe erstellt werden, bei der der Speicherverbrauch von externen Eingaben abhängt und möglicherweise unbegrenzt ist.
Chris Stratton
Ich habe gerade einige zusätzliche Kommentare zu Programmen hinzugefügt, die malloc verwenden, um herauszufinden, wie viel Speicher verwendet wird. Ich vertraue diesen nicht wirklich und ich denke, für einen ATMEGA328 sollten Sie auch keinen Malloc (kleinen Chip) verwenden.
Hans
1
@Hans - Ich habe nicht einmal über Malloc gesprochen (obwohl das natürlich auch ein Problem sein kann). Wenn Sie eine lokale Variable in einer Funktion erstellen, wird sie zur Laufzeit und nicht zur Kompilierungszeit auf dem Stapel zugewiesen. Wenn die Funktion zurückgibt, wird der Speicher freigegeben, aber wenn die Funktion sich selbst aufruft, muss noch eine weitere Kopie zugewiesen werden. Es ist möglich, einige Programme zu analysieren und Grenzen zu setzen, aber für andere Programme, bei denen der Aufrufpfad von den Laufzeiteingaben abhängt, ist er möglicherweise unbegrenzt und kann nicht ohne Kenntnis der Eingaben bestimmt werden. Dies kann zu einem Stapelüberlauf führen.
Chris Stratton
2
@Hans - Ja, feste Zuordnungen befreien Sie von Überraschungen. Sie bedeuten jedoch, dass Sie diesen Speicher nicht für einen anderen Zweck in einer anderen Funktion wiederverwenden können, es sei denn, Sie tun dies ausdrücklich manuell. Wenn Sie dies tun, gelangen Sie in das Gebiet, in dem der Bare-Metal-Wunsch nach Handoptimierung und der CS-Wunsch nach einer sauberen Hierarchie in Konflikt geraten. Die übliche Auflösung scheint darin zu bestehen, Chips mit mehr als 2 KB RAM zu kaufen, wenn die Aufgabe die einfachen und deterministischen Aufgaben überschreitet, und die Bemühungen, High-Level-Funktionen aus eingeschränkten Chips herauszuholen, als Programmierversion für Extremsportarten zu betrachten.
Chris Stratton
1

Versuchen Sie es mit der MemoryFree- Bibliothek. Das hat bisher bei mir gut funktioniert.

Amicitas
quelle