avr-gcc: Format für Flash-String-Ausgabe?

Gast #6561471
Lesenswert?
• ▲
▼
Das hilft leider nicht weiter.

Was ich suche, ist ein Format-Präfix für %s, das dafür sorgt dass 
*printf den betreffenden Parameter aus dem Flash holt – ich will mir 
damit einen zweiten Puffer ersparen, in den ich den String aus dem Flash 
kopieren müsste, wenn er mit dem normalen %s ausgegeben wird.

Die *printf_P-Funktionen leisten das nicht.
Gast #6561525
Lesenswert?
• ▲
▼
Hm, so einfach scheint es doch nicht zu sein:
1
const char __flash *getstring();
2

3
sprintf(pBuf, "%S", getstring());
4
               ^
5
warning: format ‘%S’ expects argument of type ‘wchar_t *’, but argument 9 has type ‘const __flash char *’ [-Wformat=]

wchar_t auf einem 328?
#6561540
Lesenswert?
• ▲
▼
Taucher schrieb:
> Hm, so einfach scheint es doch nicht zu sein:
> const char __flash *getstring();
> sprintf(pBuf, "%S", getstring());

Was macht denn deine Funktion getstring()? Liefert die WIRKLICH einen 
Pointer auf einen String im Flash? Ich glaube außerdem, daß __flash 
zwingend vor char stehen muss.

const __flash char *getstring();

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Flash_mit_flash_und_Embedded-C

Ich bin mir nicht sicher, ob das mit __flash funktioniert. Probier mal 
lieber so.

const char *getstring();

Oder teste mal einfach so.

sprintf(pBuf, "%S", PSTR("Hello World"));

Außerdem bietet sich sprintf_P an, damit sparst du RAM, denn der 
Formatstring ist ja konstant.

> warning: format ‘%S’ expects argument of type ‘wchar_t *’, but argument
> 9 has type ‘const __flash char *’ [-Wformat=]
>
> wchar_t auf einem 328?

Was für einen IDE bzw. Compiler nutzt du?
Gast #6561544
Lesenswert?
• ▲
▼
Das ist ein Problem beim gcc - der hat fest eingebaute Regeln für die 
Formatstringüberprüfung (%S ist alias für %ls ist wchar-string) und die 
stimmen nicht mit denen der avr-libc überein.  Ignorieren oder 
abschalten (-Wno-format).
Gast #6561559
Lesenswert?
• ▲
▼
@Falk: hier eine lauffähige Version der getstring. Die heißt hier 
getTaskName_P und hat einen Parameter, aber der ändert am Prinzip 
nichts:
1
    typedef struct {
2
        const void                  *taskAddr;
3
        const char const __flash    *name;
4
    } Name;
5

6
    #define N(name)       { name, FSTR(#name) }
7
    static const Name __flash NameTable[] = {
8
        N(onClockTick),
9
        N(readSensors),
10
        N(initSensors),
11
        N(powerBankTriggered),
12
        N(powerBankKeepAlive)
13
    };
14
    #undef N
15

16

17
    const char __flash *getTaskName_P(void *pTask) {
18
        for (uint8_t i = 0; i < ELEMENTS(NameTable); i++)
19
            if (pTask == NameTable[i].taskAddr)
20
                return NameTable[i].name;
21

22
        return PSTR("***");
23
    }
#6561588
Lesenswert?
• ▲
▼
Taucher schrieb:
> const char __flash *getTaskName_P(void *pTask) {
>         for (uint8_t i = 0; i < ELEMENTS(NameTable); i++)
>             if (pTask == NameTable[i].taskAddr)
>                 return NameTable[i].name;
>         return PSTR("***");
>     }

Tststs, solche Sachen würde ich GANZ schnell bleiben lassen! for() 
Schleifen ohne Klammern sind nicht gut, sondern eine SEHR gute Chance, 
sich ins Knie zu schießen. Spätestesn dann, wenn man mal eas erweitern 
will. Das Gleiche bei if(). Die Klammern lasse ich nur weg, wenn es 
WIRKLICH eine einfach Anweisung ist, die in die gleiche Zeile wie das 
if() paßt, ansonsten IMMER mit Klammern.

Just my 2 cents.
Gast #6561611
Lesenswert?
• ▲
▼
Falk B. schrieb:
> Die Klammern lasse ich nur weg, wenn es
> WIRKLICH eine einfach Anweisung ist, die in die gleiche Zeile wie das
> if() paßt, ansonsten IMMER mit Klammern.

Der Turm macht aber genau das, was er soll und das auf Anhieb… Er stammt 
aus der Bibliothek im Kopf, da muss ich nicht mehr viel nachdenken.

Es gibt schwierigere Konstrukte in C.

Viel lästiger finde ich dass der Compiler Konstrukte, wie die NameTable 
in meinem Beispiel nicht in Funktionen erlaubt. Hält man sich nicht 
daran, kommt eine völlig irreführenden Fehlermeldung.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.