AVR PSTR mit gegebenem String nutzen

#7764827
Lesenswert?

Hallo,

ich versuche, einen einer Funktion als Parameter übergebenen String mit dem Makro PSTR aus der <avr/pgmspace.h> im Flash eines AVR Microcontrollers zu speichern.

Als Fehlermeldung bekomme ich (in Microchip Studio) "invalid initializer".

Sobald man PSTR einen String der Form "..." übergibt, funktioniert es.

Im Web konnte ich zu diesem Problem nichts finden, daher wäre ich sehr dankbar für Hilfe.

Am Ende würde ich gerne die Funktion im Anhang nutzen, um den String auf einem LCD Display auszugeben.

Beste Grüße,

Angehängte Dateien:
#7764869
Lesenswert?

Danke für die schnelle Antwort. Ich werde versuchen, das Problem genauer zu beschreiben.

Die Funktion die ich angehängt habe, versuche ich mit einem im Flash gespeicherten String aufzurufen. Während es mit lcd_writeProgString(PSTR("Test")) klappt, funktioniert es nicht, sobald ich einen bereits existierenden String übergeben zu versuche, also etwas wie

1
 void func(const char *str) {
2

3
lcd_writeProgrString(PSTR(str));
4

5
}

Die Zeilenangabe der Fehlermeldung bezieht sich genau auf die Zeile, in der lcd_writeProgString aufgerufen wird.

(Firma: Gast) #7764872
Lesenswert?

1
#include <Streaming.h> // die Lib findest du selber ;-)
2
Print &cout = Serial; // cout Emulation für "Arme"
3

4

5
const char test[] PROGMEM = "qwertzui";
6

7

8
void writeProgString(const char *string) {
9
    char c;
10
    while ((c = (char)pgm_read_byte(string++))) {
11
       //lcd_writeChar(c);
12
       cout << c;
13
    }
14
}
15

16

17
void setup() 
18
{
19
  Serial.begin(9600);
20
  cout << F("Start: ") << F(__FILE__) << endl;
21
  writeProgString(test);
22
  cout <<  endl;
23
}
24

25
void loop() 
26
{
27

28
}
#7764879
Lesenswert?

Martin schrieb:

Danke für die schnelle Antwort. Ich werde versuchen, das Problem genauer zu beschreiben.

Die Funktion die ich angehängt habe, versuche ich mit einem im Flash gespeicherten String aufzurufen.

Das geht, aber nicht so.

Während es mit lcd_writeProgString(PSTR("Test")) klappt, funktioniert es nicht, sobald ich einen bereits existierenden String übergeben zu versuche, also etwas wie

Logisch. PSTR ist für Konstanten da. Eher so. Du gibst ja nur den Zeiger auf den String im Flash an eine andere Funktion weiter.

1
void func(PGM_P str) {
2
  lcd_writeProgrString(str);
3
}
(Firma: Gast) #7765116
Lesenswert?

Martin schrieb:

ich versuche, einen einer Funktion als Parameter übergebenen String mit dem Makro PSTR aus der <avr/pgmspace.h> im Flash eines AVR Microcontrollers zu speichern.

Funktioniert nicht.

Welche Sprache? C oder C++?

Wenn C++, dann kann man Funktionen überladen. Arduino verwendet die "incomplete Class" FlashStringHelper um zwischen Flash oder RAM Strings zu unterscheiden. Hört sich teuer an, ist aber kostenlos zu haben, da das nur Pointer Konvertierungen sind, welche keine zusätzliche Rechenzeit/Code zur Laufzeit benötigen.

#7765140
Lesenswert?

Martin schrieb:

ich versuche, einen einer Funktion als Parameter übergebenen String mit dem Makro PSTR aus der <avr/pgmspace.h> im Flash eines AVR Microcontrollers zu speichern.

Der Makro PSTR wirkt bei der Übersetzung des Programms, nicht zur Laufzeit. Um zur Laufzeit einen String aus dem flüchtigen Speicher in den Flash zu programmieren müsstest du anders vorgehen. Das geht zwar, dauert aber recht lange, und macht bei häufiger Benutzung auch zügig den Flash kaputt. Das nur zu tun, weil eine Bibliotheksfunktion nur Flash-Strings akzeptiert, nicht aber solche im flüchtigen Speicher, macht wenig Sinn.

LG, Sebastian

#7765144
Lesenswert?

Martin schrieb:

ich versuche, einen einer Funktion als Parameter übergebenen String mit dem Makro PSTR aus der <avr/pgmspace.h> im Flash eines AVR Microcontrollers zu speichern.

Wirklich? Aber egal.

Dann wirst du dich mit den Funktionen aus boot.h der avrlibc befassen müssen, und dazu ausführlich mit dem Datenblatt des Prozessors.

Gehen geht das, es erfordert aber ein grundlegendes Verständnis des Prozessors und der avrlibc, was du dir halt noch erarbeiten musst.

Oliver

#7765242
Lesenswert?

Oliver S. schrieb:

Keine der _P-Funktionen schreibt ins Flash.

Das ist irgendwie richtig, aber auch ungenau. Richtig wäre:

Keine Funktion außerhalb des Bootloaders schreibt ins Flash.

Edit: Achje, dass man das so lesen kann, dass der TO das Flash als EEPROM-Ersatz mißbrauchen will, sehe ich erst jetzt. Die Beispielfunktion sah so aus, als wolle er Daten aus dem Flash ans LCD schicken.

Persönliche Seite #7765352
Lesenswert?

Walter T. schrieb:

Die Beispielfunktion sah so aus, als wolle er Daten aus dem Flash ans LCD schicken.

Mit avr-gcc dann einfach do:

1
void lcd_writeProgString (const __flash char *string)
2
{
3
    char c;
4
    while ((c = *string++))
5
    {
6
        lcd_writeChar (c);
7
    }
8
}

oder

1
void lcd_writeProgString (const __flash char *string)
2
{
3
    for (const __flash char *s = string; *s != '\0'; ++s)
4
        lcd_writeChar (*s);
5
}

AVR-GCC-Tutorial: Flash mit flash und Embedded-C

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren