RAM Speicher schonender programmieren

Hallo zusammen,

ich optimieren gerade meinen Quellcode um noch mehr RAM Speicher zu haben.

Benutze einen MEGA 2560 und verwende bei jedem Aufruf von der Function print (ln) schon die F() Function. Anstatt der string Klasse habe ich alle auf char umgeschrieben das funktioniert soweit auch super :-)

Ich verwende oft z.B. solche Aufrufe

sendXMLFile("micro/msg/login/NOTON.txt");

Hier wird ja ein const char array der Function übergeben und somit gleich beim Start des Sketches im RAM reserviert.

Kann man das vielleicht RAM sparsamer gestaltet?

Grüße speedy

speedy1982:
Ich verwende oft z.B. solche Aufrufe

sendXMLFile("micro/msg/login/NOTON.txt");

Hier wird ja ein const char array der Function übergeben und somit gleich beim Start des Sketches im RAM reserviert.

Kann man das vielleicht RAM sparsamer gestaltet?

Zum Sparen von RAM-Speicher mußt Du versuchen, möglichst viele String-Konstanten im PROGMEM abzulegen.

Bei selbstgeschriebenen Funktionen, denen eine Stringkonstante als Parameter übergeben werden soll, kannst Du beispielsweise anstelle eines char-Pointers einen PSTR übergeben. Allerdings mußt Du den Inhalt dann erst aus dem Programmspeicher ziehen, bevor Du ihn verwenden kannst.

Anbei mal ein Beispiel, bei dem ein übergebener PSTR einmal zeichenweise per “pgm_read_byte” ausgelesen und ausgegeben wird, und danach gleich nochmal, nachdem vorher der gesamte String in ein char Array innerhalb des RAM umkopiert worden ist.

void sendXMLfile(PGM_P name)
{
  // einmal zeichenweise aus PROGMEM auslesen und ausgeben
  for (int i=0;i<strlen_P(name);i++)
    Serial.print((char)pgm_read_byte(name+i));
  Serial.println();  
  // und nochmal komplett in einen Puffer im RAM umkopieren und ausgeben
  char buf[41];
  memcpy_P(buf,name,strlen_P(name)+1);
  Serial.print(F("Aus Puffer: "));
  Serial.println(buf);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (int i=0;i<10;i++)
    sendXMLfile(PSTR("micro/msg/login/NOTON.txt"));
}

void loop() {
}

HI,

char buf[41];
memcpy_P(buf,name,strlen_P(name)+1);

Wird hier nicht auch der char array vorab im RAM reserviert?

for (int i=0;i<strlen_P(name);i++)
Serial.print((char)pgm_read_byte(name+i));

Das funktinoert prima wenn ich die Daten per Serial ausgeben will, doch wie mache ich das wenn ich z.

SD.open(....)

in der Function sendXMLFile(…) aufrufen will?

Danke schon einmal vorab.

Gruß
speedy

speedy1982: char buf[41]; memcpy_P(buf,name,strlen_P(name)+1);

Wird hier nicht auch der char array vorab im RAM reserviert?

Nein, nicht "vorab" für die gesamte Laufzeit des Programms, sondern als lokale Variable der Funktion belegt dieses char-Arrray nur "zur Laufzeit" der Funktion RAM-Speicher.

speedy1982: Das funktinoert prima wenn ich die Daten per Serial ausgeben will, doch wie mache ich das wenn ich z.

SD.open(....)

in der Function sendXMLFile(...) aufrufen will?

Dann nimmst Du die Variante, bei der der PSTR insgesamt in ein char-Array im RAM umkopiert wird.

Das aufnehmende char-Array innerhalb der Funktion muss groß genug sein, um den längsten übergebenen String aufzunehmen, aber auch wenn Du im Progrmam nacheinander 100 Dateinamen verwendest, wird in der Funktion nur einmal RAM-Speicher für das char-Array verbraucht. Und dies auch nur, während die Funktion läuft, d.h. nach der Beendigung der Funktion steht der dann nicht mehr existierende RAM-Speicher des char-Arrays schon wieder für etwas anderes zur Verfügung und kann in anderen Funktionen Deines Programms verbraten werden.

RAM sparen und "sendXMLFile" ??? In dem Moment wo XML mit im Spiel ist würde ich auf eine stärkere Platform wechseln. Raspi und Freunde sind nicht so teuer. Klar geht das auch irgendwie mit einem Arduino. Aber man schraubt auch an einen Smart normalerweise keine Anhängerkupplung obwohl sowas technisch irgendwie möglich ist ;)

Hallo Udo,

danke für deine Worte ;), doch genau das ist mein Ziel, und muss sagen bis heute bin ich ganz zufrieden, dank der Community konnte ich schon sehr viel RAM sparen :) und es kann weitergehen.

Genau das macht es doch aus, wenn man ein Ziel im Kopf hat, es dann auch umzusetzen kann und auch noch alles so klappt wie vorgestellt :grin:

Gruss speedy

In dem Moment wo XML mit im Spiel ist würde ich auf eine stärkere Platform wechseln

Wenn es dir nicht nur drum geht, den Dateinamen der xml Datei in einem char Array zu übergeben, solltest du schon berücksichtigen, das XML vom Konzept her nicht so gut zum sehr begrenzten RAM eines µC passt. Da hat Udo schon recht. ( Beliebige Schachteltiefe von Elementen und Attributen, jedes Element enthält alle seine Unter-Elemente ... )

Aber das war, wenn man den Thread nochmal liest, ja nicht dein Problem: SD.open( ) braucht schon den Dateinamen im RAM, aber dieser RAM wäre sofort wieder frei, sobald die Datei geöffnet ist. ( Dann hast du ganz andere RAM Anforderungen )

Du kannst dir eine Funktion schreiben, die den Dateinamen aus dem Flash in eine lokale Variale liest und gleichzeitig die Pfadstruktur abarbeitet ( braucht dafür (8.3) 13 byte auf dem Stack + den aktuellen Sektor der Dateiverwaltung), am Ende die Datei öffnet und nur das File Objekt zurückliefert.