Gemäß der Arduino-Dokumentation verfügt der ATmega328 über 32 KB Flash-Speicher für den Bootloader + hochgeladene Skizze und nur 2 KB SRAM für Laufzeitdaten. Der ATmega2560 hat mit 256 KB bzw. 8 KB einiges mehr.
In beiden Fällen scheinen diese Grenzwerte eher gering zu sein, insbesondere im Vergleich zu Konsumgeräten ähnlicher Größe wie Smartphones.
Was können Sie tun, wenn Sie ausgehen? Ist Ihre Skizze beispielsweise zu groß oder müssen Sie zur Laufzeit viele Daten (z. B. Zeichenfolgen) verarbeiten? Gibt es eine Möglichkeit, den Flash- oder SRAM-Speicher zu erweitern?
flash
sketch-size
Peter Bloomfield
quelle
quelle
Antworten:
Optimierung Die
einfache Programmierung für eingebettete Systeme unterscheidet sich erheblich von der Programmierung für Allzweckgeräte wie Computer und Mobiltelefone. Effizienz (in Bezug auf Geschwindigkeit und Platz) ist weitaus wichtiger, da Ressourcen knapp werden. Das bedeutet, dass Sie als Erstes prüfen müssen, welche Teile Ihres Codes Sie optimieren können, wenn Ihnen der Speicherplatz ausgeht.
In Bezug auf die Reduzierung des Programmspeichers (Flash) kann es schwierig sein, die Codegröße zu optimieren, wenn Sie unerfahren sind oder wenn Sie eher daran gewöhnt sind, für Desktop-Computer zu programmieren, für die diese Fähigkeiten normalerweise nicht erforderlich sind. Leider gibt es keinen "Magic Bullet" -Ansatz, der in allen Situationen funktioniert, obwohl es hilfreich ist, wenn Sie sich ernsthaft überlegen, was Ihre Skizze wirklich braucht . Wenn eine Funktion nicht benötigt wird, nehmen Sie sie heraus.
Manchmal ist es auch hilfreich zu identifizieren, wo mehrere Teile Ihres Codes gleich (oder sehr ähnlich) sind. Möglicherweise können Sie sie zu wiederverwendbaren Funktionen zusammenfassen, die von mehreren Stellen aus aufgerufen werden können. Beachten Sie jedoch, dass der Versuch, Code zu wiederverwendbar zu machen, manchmal tatsächlich dazu führt, dass er ausführlicher wird. Es ist eine schwierige Balance, die mit Übung einhergeht. Ein Blick auf die Auswirkungen von Codeänderungen auf die Compiler-Ausgabe kann hilfreich sein.
Die Optimierung von Laufzeitdaten (Runtime Data, SRAM) ist in der Regel etwas einfacher, wenn Sie daran gewöhnt sind. Eine sehr häufige Gefahr für Programmieranfänger ist die Verwendung zu vieler globaler Daten. Alles, was im globalen Rahmen deklariert wurde, bleibt während der gesamten Lebensdauer der Skizze bestehen. Dies ist nicht immer erforderlich. Wenn eine Variable nur innerhalb einer Funktion verwendet wird und nicht zwischen den Aufrufen bestehen bleiben muss, machen Sie sie zu einer lokalen Variablen. Wenn ein Wert zwischen Funktionen geteilt werden muss, prüfen Sie, ob Sie ihn als Parameter übergeben können, anstatt ihn global zu machen. Auf diese Weise verwenden Sie SRAM nur dann für diese Variablen, wenn Sie es tatsächlich benötigen.
Ein weiterer Killer für die SRAM-Nutzung ist die Textverarbeitung (z. B. mit der
String
Klasse). Im Allgemeinen sollten Sie Zeichenfolgenoperationen nach Möglichkeit vermeiden. Sie sind massive Erinnerungsfresser. Wenn Sie beispielsweise viel Text seriell ausgeben, verwenden Sie mehrere Aufrufe,Serial.print()
anstatt die Zeichenfolgenverkettung zu verwenden. Versuchen Sie außerdem, die Anzahl der Zeichenfolgenliterale in Ihrem Code zu verringern, wenn dies möglich ist.Vermeiden Sie nach Möglichkeit auch eine Rekursion. Jedes Mal, wenn ein rekursiver Aufruf erfolgt, wird der Stapel um eine Stufe tiefer gelegt. Korrigieren Sie Ihre rekursiven Funktionen so, dass sie stattdessen iterativ sind.
EEPROM verwenden
EEPROM wird zur langfristigen Speicherung von Dingen verwendet, die sich nur gelegentlich ändern. Wenn Sie große Listen oder Nachschlagetabellen mit festen Daten verwenden müssen, sollten Sie diese im Voraus im EEPROM speichern und nur dann herausziehen, wenn dies erforderlich ist.
Offensichtlich ist das EEPROM jedoch in Größe und Geschwindigkeit ziemlich begrenzt und weist eine begrenzte Anzahl von Schreibzyklen auf. Es ist keine großartige Lösung für Datenbeschränkungen, aber es könnte ausreichen, um Flash oder SRAM zu entlasten. Es ist auch durchaus möglich, eine Schnittstelle zu einem ähnlichen externen Speicher wie einer SD-Karte herzustellen.
Erweiterung
Wenn Sie alle anderen Optionen ausgeschöpft haben, ist möglicherweise eine Erweiterung möglich. Das Erweitern des Flash-Speichers zur Erhöhung des Programmspeichers ist leider nicht möglich. Es ist jedoch möglich, SRAM zu erweitern. Dies bedeutet, dass Sie Ihre Skizze möglicherweise überarbeiten können, um die Codegröße auf Kosten der Erhöhung der Datengröße zu verringern.
Es ist eigentlich ziemlich einfach, mehr SRAM zu bekommen. Eine Möglichkeit besteht darin, einen oder mehrere 23K256- Chips zu verwenden. Sie werden über SPI abgerufen, und die SpiRAM-Bibliothek hilft Ihnen bei der Verwendung. Achten Sie nur darauf, dass sie mit 3,3 V und nicht mit 5 V betrieben werden!
Wenn Sie das Mega verwenden, können Sie alternativ SRAM-Erweiterungsschilde von Lagrangian Point oder Rugged Circuits erhalten .
quelle
Wenn Sie Ihren Code auf Ihr Arduino hochladen, beispielsweise ein Uno, werden Sie darüber informiert, wie viele Bytes von den verfügbaren 32K verwendet werden. Das ist, wie viel Flash-Speicher Sie haben (denken Sie Computer-Festplatte). Während Ihr Programm ausgeführt wird, verwendet es das, was als SRAM bezeichnet wird, und es ist viel weniger davon verfügbar.
Manchmal werden Sie bemerken, dass sich Ihr Programm an einem Punkt merkwürdig verhält, den Sie eine Weile nicht mehr berührt haben. Es kann sein, dass aufgrund Ihrer letzten Änderungen nicht mehr genügend Arbeitsspeicher (SRAM) zur Verfügung steht. Hier finden Sie einige Tipps zum Freigeben von SRAM.
Speichern von Strings in Flash anstelle von SRAM.
Eines der häufigsten Dinge, die ich gesehen habe, ist, dass dem Chip der Speicherplatz ausgeht, weil zu viele lange Zeichenfolgen vorhanden sind.
Verwenden Sie die
F()
Funktion, wenn Sie Zeichenfolgen verwenden, damit diese in Flash anstelle von SRAM gespeichert werden, da Ihnen viel mehr davon zur Verfügung steht.Verwenden Sie die richtigen Datentypen
Sie können ein Byte speichern, indem Sie von einem
int
(2 Byte) zu einembyte
(1 Byte) wechseln . Ein Byte ohne Vorzeichen gibt Ihnen 0-255. Wenn Sie also Zahlen haben, die nicht höher als 255 sind, speichern Sie ein Byte!Woher weiß ich, dass mir der Speicher ausgeht?
Normalerweise beobachten Sie, wie sich Ihr Programm seltsam verhält, und fragen sich, was schief gelaufen ist. Sie haben an dem Code an der Stelle, an der er durcheinander gerät, nichts geändert. Was gibt es also? Der Speicher geht zur Neige.
Es gibt einige Funktionen, mit denen Sie feststellen können, wie viel Speicher Sie zur Verfügung haben.
Verfügbare Erinnerung
quelle
F()
Ding eine Arduino-spezifische Funktion ist oder in den AVR-Bibliotheken? Sie könnten erwägen, auch zu erwähnenPROGMEM const ...
.Zusätzlich zu dem, was andere gesagt haben (dem ich voll und ganz zustimme), würde ich raten, diesen adafruit-Artikel über das Gedächtnis zu lesen . Es ist gut geschrieben, erklärt eine Menge Dinge über das Gedächtnis und gibt Hinweise, wie es optimiert werden kann.
Am Ende der Lektüre, denke ich, würden Sie eine ziemlich vollständige Antwort auf Ihre Frage bekommen.
Zusammenfassend haben Sie 2 mögliche Optimierungsziele (je nachdem, wo sich Ihre Speicherprobleme befinden):
F()
Makro verwenden können.Es wird auch ein zusätzlicher Ansatz zur Reduzierung der SRAM-Nutzung beschrieben (der jedoch nur selten verwendet wird, da er beim Codieren etwas umfangreich und wenig effizient ist). Er besteht darin, EEPROM zum Speichern von Daten zu verwenden, die von Ihrem Programm erstellt wurden, wird jedoch unter bestimmten Bedingungen erst später verwendet auftreten, wenn Daten aus dem EEPROM zurückgeladen werden können.
quelle
Wenn der Speicherplatz knapp wird, gibt es zwei Möglichkeiten:
Es gibt viele Tipps online, wie man das erste macht (und für die allermeisten Dinge, die Leute mit dem Arduino machen, ist der eingebaute Speicher nach dem "Optimieren" mehr als genug). Also werde ich mich auf die Sekunde konzentrieren:
Es gibt 3 Dinge, die Flash oder SRAM verbrauchen. Jeder benötigt einen etwas anderen Ansatz für das Hinzufügen von Speicher:
Variable Lagerung: Wie Sachleen bereits betont hat, ist es möglich, SRAM zu erweitern. SRAM, FRAM und NVSRAM eignen sich alle für sich schnell ändernde Variablen. (Während Sie prinzipiell Flash zum Speichern von Variablen verwenden könnten, müssen Sie sich um die Abnutzung des Flashs sorgen). SPI (ein serielles Protokoll) ist die einfachste Verbindung zum Arduino. Die SpiRAM-Bibliothek arbeitet mit dem seriellen SRAM-Chip Microchip 23K256 . Der serielle FRAM- Chip Ramtron FM25W256 (jetzt im Besitz von Cypress) verwendet ebenfalls SPI. Der Cypress CY14B101 NVSRAM verwendet ebenfalls SPI. Etc.
Konstante Daten, die beim nächsten Einschalten noch vorhanden sein müssen: Dies ist fast so einfach wie das Erweitern von SRAM. Es stehen viele externe EEPROM-, FRAM-, NVSRAM- und FLASH- Speichergeräte zur Verfügung. Derzeit sind die niedrigsten Kosten pro MB SD-Flashkarten (auf die über SPI zugegriffen werden kann). Der Ramtron FM25W256 (siehe oben), der Cypress CY14B101 (siehe oben) usw. können ebenfalls konstante Daten speichern. Viele Erweiterungsschilder verfügen über einen SD-Kartensteckplatz und verschiedene Bibliotheken und Lernprogramme unterstützen das Lesen und Beschreiben von (Flash-) SD-Karten. (Wir können SRAM dafür nicht verwenden, da SRAM alles vergisst, wenn die Stromversorgung ausfällt.)
ausführbarer Code: Leider ist es nicht möglich, den Flash-Speicher eines Arduino zu erweitern, um den Programmspeicher zu vergrößern. Ein Programmierer kann jedoch jederzeit eine Skizze überarbeiten, um die Codegröße zu verringern, wobei die Datengröße erhöht und die Ausführung etwas verlangsamt wird. (Theoretisch könnten Sie so weit gehen, dass Sie Ihre gesamte Skizze in eine interpretierte Sprache übersetzen, diese Version Ihrer Skizze auf einer SD-Karte speichern und dann einen Interpreter für diese Sprache schreiben, der auf dem Arduino ausgeführt wird, um Anweisungen vom abzurufen und auszuführen SD-Karte - Weiter geht es mit Arduino , einem BASIC-Interpreter, einem Tom Napier Picaro-Interpreter, einer anwendungsspezifischen Sprache usw.).
quelle