Pointer String mit PROGMEM?!

OP #4803222
Lesenswert?

Hallo,

Gibt es eine einfache Möglichkeit die ganzen Pointer Strings mit PROGMEM 
zu versehen?
1
/*
2
*  Strings for LCD Display
3
*/
4
typedef struct
5
{
6
  char *PrjName;
7
  char *SWV;
8
  char *HWV;
9
  char *SetTime;
10
  char *SetDate;
11
  char *SetIllumination;
12
  char *Time[10];  
13
  char *SwitchTimeEnable;
14
  char *ToggleTriac;
15
  char *ManuelMode;
16
  char *TriacOn;
17
  char *TriacOff;  
18
  char *SubmenueTime[5];
19
  char *SubmenueExit;
20
  char *hours;
21
  char *minutes;
22
  char *seconds;
23
}AppStrings_t;
Persönliche Seite #4803300
Lesenswert?

Frank M. schrieb:
>    const char * const PROGMEM PrjName;

Das sollte einen Fehler geben.
1
const __flash char PrjName[] = "Hallo";
2
const __flash char SWV[] = "Welt";
3
...
4

5
typedef struct
6
{
7
   const __flash char *PrjName;
8
   const __flash char *SWV;
9
   ...
10
}AppStrings_t;
11

12
AppStrings_t mystrings = // mystrings im RAM
13
{
14
    PrjName,
15
    SWV,
16
    ...
17
};
18

19
const __flash AppStrings_t mystrings = // mystrings im Flash
20
{
21
    PrjName,
22
    SWV,
23
    ...
24
};

Analog mit PROGMEM, nur dass man dann noch #include avr/pgmspace.h und 
pgm_read_xxx braucht (mit __flash genügt "normales" C).
Moderator Persönliche Seite #4803329
Lesenswert?

Johann L. schrieb:
>>    const char * const PROGMEM PrjName;
>
> Das sollte einen Fehler geben.

Nö. Ich hatte das vorher getestet. Der avr-gcc nimmt das anstandslos.

> const __flash AppStrings_t mystrings = // mystrings im Flash
> {

Die adäquate Version mit PROGMEM - falls eine ältere avr-gcc-Version 
benutzt wird, die noch kein __flash versteht:

const AppStrings_t mystrings PROGMEM =
{
#4803339
Lesenswert?

Eigentlich macht man ja eine Struct, damit man nicht für jedes Element 
einen extra Pointer braucht, sondern nur einen Pointer auf die Struct, 
um schnell und codesparend mit Displacement auf die einzelnen Elemente 
zugreifen zu können.

Insbesondere die Pointer in den Flash zu legen, hieße ja, die Adressen 
sind zur Compilezeit bekannt. Wozu also die Umstände mit Pointern?
#4803361
Lesenswert?

Peter D. schrieb:
> Eigentlich macht man ja eine Struct, damit man nicht für jedes Element
> einen extra Pointer braucht, sondern nur einen Pointer auf die Struct,
> um schnell und codesparend mit Displacement auf die einzelnen Elemente
> zugreifen zu können.
>
> Insbesondere die Pointer in den Flash zu legen, hieße ja, die Adressen
> sind zur Compilezeit bekannt. Wozu also die Umstände mit Pointern?

Ich gebe dir Recht, aber wie baut man sich diese Struktur zusammen? Wenn 
ich nicht die Pointer sondern die Texte direkt im struct ablegen will, 
muss ich ja die Arraygrößen bzw die länder der Texten mitangeben:
1
const __flash struct {
2
  char helloWorld[14];
3
  char swVersion[6];
4
} flashTexts = {
5
  "Hello, World!",
6
  "v0.01"
7
};
Geht, ist aber ziemlich fehleranfällig.
#4803412
Lesenswert?

hmm...

1) Definiere alle Texte mit einem Makro
1
// flashtexts.inc
2

3
// define all flash texts here
4
// TEXT(name, value)
5
TEXT(helloWorld, "Hello, World!")
6
TEXT(swVersion,  "0.01beta")
7
TEXT(breakfast, "Continental")

2) Header-file zum inkludieren wo man die Text(e) benutzen möchte:
1
// flashtexts.h
2
#ifndef FLASHTEXTS_H
3
#define FLASHTEXTS_H
4

5
#undef  TEXT
6
#define TEXT(NAME,VALUE) NAME[ sizeof(VALUE) ];
7

8
extern const __flash struct {
9
#include "flashtexts.inc"
10
} texts;
11

12
#endif

3) C Modul worin die Texte angelegt werden:
1
// flashtexts.c
2
#include "flashtexts.h"
3

4

5
#undef  TEXT
6
#define TEXT(NAME,VALUE) VALUE,
7

8
texts = {
9
#include "flashtexts.inc"
10
};

4) Benutzen:
1
#include "flashtexts.h"
2

3
int main()
4
{
5
  printf(texts.helloWorld);
6
}
Persönliche Seite #4803458
Lesenswert?

Frank M. schrieb:
> Johann L. schrieb:
>>>    const char * const PROGMEM PrjName;
>>
>> Das sollte einen Fehler geben.
>
> Nö. Ich hatte das vorher getestet. Der avr-gcc nimmt das anstandslos.

Sonderlich sinnvoll ist so ein Code aber nicht.  Es ist ungefähr so 
sinnvoll, wie unterschiedliche Komponenten eines Struct in 
unterschiedliche Sections legen zu wollen.

Immerhin bekomme ich eine Warnung, dass progmem ignoriert wird -- 
vorausgesetzt, es steht nach dem "PrjName".
Persönliche Seite #4803502
Lesenswert?

Peter D. schrieb:
> Ich hab auch festgestellt, daß die pgmspace.h leider nicht abwärts
> kompatibel ist.
> Wenn man ältere Projekte aus WINAVR 2010 mit neueren AVR-GCC compiliert,
> gibt es Fehlermeldungen (und umgekehrt).

Es gibt Fehler, wenn man versucht, nicht-const Objekte ins Flash zu 
legen.  Das ist dann aber ein Problem des Project-Codes, nicht von 
pgmspace.h.

Dass avr-gcc nicht-const Daten im Flash ablehnt, ist auch den Release 
Notes entnehmbar; wenn man also asbach uralt Projekte übersetzten will, 
sollte man auch eine asbach uralt Toolchain verwenden.

Und hast du ein Beispiel, dass Code, der mit einer aktuellen Toolchain 
übersetzt, dass mit einem WinAVR-20100110 nicht mehr tut (abgesehen von 
damals noch nicht unterstützten Devices, Optionen, Qualifiern, etc).
Persönliche Seite #4803558
Lesenswert?

Frank M. schrieb:
> Johann L. schrieb:
>> Dass avr-gcc nicht-const Daten im Flash ablehnt, ist auch den Release
>> Notes entnehmbar; wenn man also asbach uralt Projekte übersetzten will,
>> sollte man auch eine asbach uralt Toolchain verwenden.
>
> Braucht man nicht. Dann schreibt man const davor und schon läuft es mit
> der alten und mit der neuen Toolchain.

Ja, ich weiß.  Hilft aber zunächst nicht weiter, wenn jemand ein Projekt 
mit einer neuen Toolchain generieren will und dann Fehler bekommt. 
Beispiel ist USBasp

http://www.fischl.de/usbasp/

Da kannst dann erst mal auf die Suche gehen, wo das const hin muss...

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