Gibt es bei arv-gcc ein Format für die printf-Familie, mit dem man Flash-Strings ausgeben kann?
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.
foobar schrieb: > Großes S holt aus dem Flash. Steht übrigens auch in der oben verlinkten Dokumentation: "S Similar to the s format, except the pointer is expected to point to a program-memory (ROM) string instead of a RAM string."
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?
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?
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).
Ja, ich habs gerade getestet – die Warnung kann man ignorieren. sprintf tut mit dem %S wie erhofft.
@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 | }
|
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.
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.
Falk B. schrieb: > Ich glaube außerdem, daß __flash zwingend vor char stehen muss. Die Reihenfolge der Qualifier spielt keine Rolle. Taucher schrieb: > const char const __flash *name; Ein "const" kann weg; conster als const geht nicht ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.