Ich ändere derzeit einige Bibliotheken, um Flash anstelle von RAM für die Speicherung von Zeichenfolgen zu verwenden, damit mir in einem Projekt nicht der SRAM ausgeht.
Einige Zeichenfolgen in der Bibliothek werden folgendermaßen deklariert:
const char *testStringA = "ABC";
Dies unterscheidet sich davon, wie ich dies normalerweise sehe:
const char testStringB[] = "DEF";
Ich denke jedoch, dass diese beiden gleichwertig sind, wenn sie als const deklariert und in der Deklaration initialisiert werden. Beide funktionieren gut im Code.
Ich habe versucht, diese auf Flash zu verschieben:
const prog_char *testStringC PROGMEM = "GHI";
Ich stellte dann fest, dass dies nicht funktionierte. Beim Drucken wurde ein Gobbledegook produziert.
Nach dem üblicheren Muster von:
const prog_char testStringD[] PROGMEM = "JKL";
funktioniert gut.
Ich kann in der Demontage sehen:
00000068 <testStringC>:
68: 04 01 ..
0000006a <_ZL11testStringD>:
6a: 4a 4b 4c 00 JKL.
Es ist also klar, dass der Zeiger und PROGMEM dazu führen, dass der String / das Array nicht initialisiert wird.
Warum ist das?
Beispielcode:
#include <avr/pgmspace.h>
const int BUFFER_LEN = 20;
const char *testStringA = "ABC";
const char testStringB[] = "DEF";
const prog_char *testStringC PROGMEM = "GHI";
const prog_char testStringD[] PROGMEM = "JKL";
void setup()
{
Serial.begin(9600);
}
void loop()
{
char buffer[BUFFER_LEN];
Serial.println(testStringA);
Serial.println(testStringB);
strncpy_P(buffer, testStringC, BUFFER_LEN);
Serial.println(buffer);
strncpy_P(buffer, testStringD, BUFFER_LEN);
Serial.println(buffer);
delay(1000);
}
PSTR()
Makro vorgeschlagen, aberF()
vor dem Senden geändert , da Ihre Konstanten in Ihrem Q globale Konstanten sind. Daher habe ich es vorgezogen, bei der zu bleiben, die in beiden Kontexten funktionieren sollte.Was diese Zeile:
Dies bedeutet, Prologcode zu schreiben, um die Zeichen in der Zeichenfolge in den SRAM zu kopieren, und dann den in Flash gespeicherten Zeiger auf diesen SRAM-Speicherort zu initialisieren . Sie müssen den Zeiger auf normalem Wege laden und dann den Zeiger wie gewohnt dereferenzieren.
Diese Linie:
Erstellt das Array von Zeichen in Flash, sodass Sie wie erwartet darauf zugreifen können.
quelle