Forum: Mikrocontroller und Digitale Elektronik STM32 - wo landen Konstanten


von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Arbeite mich gerade mit dem VL Discovery Board ein auf die STM32 und 
komme von den AVRs. Bei denen musste man ja PROGMEM benutzen um 
konstante Arrays, Strings usw. im Flash zu plazieren, und dann mit 
read_pgm_byte() usw. sich den Wert wieder zu holen.
Wie läuft das nun bei den ARMs ? Kann darüber nichts finden und bin 
natürlich dran interessiert, den RAM zu sparen, da ich den für bessere 
Sachen brauchen kann. Reicht es, mit
const u8 myArray[SIZE] = {werte,werte,werte};

die Sächelchen als Konstanten zu definieren ? Leider zeigt die Atollic 
IDE den Verbrauch an RAM und Flash nicht an.

von fdssd (Gast)


Lesenswert?

bei den ARMs  wurde das soweit ich weiß korrigiert ..
der M3 is glaube immernoch  harvard (?)   aber genau das wurde glaube 
angepasst

sobald also ein
1
const ....
steht sollte es auch im flash landen

von Oliver R. (sourcebox)


Lesenswert?

Es ist vom Linkerskript abhängig. Wenn dort z.B. Folgendes eingetragen 
ist (Auszug), landen sie in der Section .text und folglich im Flash:

  .text :
  {
    *(.rodata)
    *(.rodata*)
  } >FLASH

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Schau ich mal nach, danke  !

von Oliver R. (sourcebox)


Lesenswert?

Für den Code gibt es eigene Einträge, ich hatte nur den relevanten 
Ausschnitt für die Konstanten gepostet. Am besten schaust du dir mal die 
Linkerskripte genauer an, die der Firmware Library beiliegen (unter 
CMSIS).

von Roland H. (batchman)


Lesenswert?

Matthias Sch. schrieb:
> komme von den AVRs. Bei denen musste man ja PROGMEM benutzen

Alle anderen mir bekannten Archtiekturen (MSP430, PIC32 bzw. MIPS, ARMs) 
benötigen das nicht. Ein const genügt (wenn das "linker script" so 
ist, wie es Oliver beschrieben hat). Und das ist auch gut so :-) PROGMEM 
und GCC machen einem das Leben nicht einfach: Schreibarbeit, manche 
Funktionen müssen doppelt ausgelegt werden usw.

Es gibt m. W. andere Compiler, die das PROGMEM implizit machen. Der GCC 
tut sich damit schwer bzw. das ist nicht seine Ausrichtung.

Es gibt - neben der Vereinfachung - beim GCC noch einen Vorteil. Im 
Gegensatz zu PROGMEM Strings kann der GCC die "normalen" const Strings 
optimieren. D. h. gleiche Strings sind nur 1x im Flash, und Teilstrings 
ebenso: "Hallo, Welt" und "Welt" belegt nur den Platz, den "Hallo, Welt" 
benötigt. Hängt vom Optimierungslevel ab.

Das führt bei mir regelmäßig dazu, dass das gleiche Programm locker in 
einen ARM mit 32K passt, während es im AVR zum Überlauf kommt.

von (prx) A. K. (prx)


Lesenswert?

fdssd schrieb:

> bei den ARMs  wurde das soweit ich weiß korrigiert ..
> der M3 is glaube immernoch  harvard (?)

Wenn man an dieser Stelle mit Havard und Von Neumann argumentiert, dann 
sollte man sich entscheiden, ob damit Busse oder Adressräume gemeint 
sind. Anno Harvard Mark 1 was das noch gleichbedeutend, aber heutzutage 
ist es das längst nicht mehr. Denn alle ARMs (und x86, wenn man vom 
I/O-Adressraum absieht) haben einen einzigen einheitlichen Adressraum, 
unabhängig davon mit wievielen internen und externen Bussen der Core 
implementiert ist.

PROGMEM hängt damit zusammen, dass AVRs 3 völlig getrennte Adressräume 
haben (Flash, EEPROM, RAM) und GCC nicht wie manche 8051er Compiler 
adressraumübergreifende softwarekontrollierte und damit langsame Pointer 
implementiert. Also muss man die Adressräume explizit angeben und 
erwischt da nicht die stärkste Seite von GCC.

Hat man nur einen einzigen Adressraum, dann löst sich das Problem in 
Luft auf und Konstanten können problemlos im Flash landen, ohne dass man 
irdendwie besonders damit umgehen müsste.

Es ist also völlig irrelevant, ob der ARM Core nur einen Bus hat (ARM7) 
oder gleich drei (ARM9). Ob er also im auf die Busse bezogenen Sinn 
Harvard ist oder Von Neumann.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Wenn man in einer Funktion eine const Variable habt, so erzeugt der GCC 
einen Code für die Initialisierung der const Variable.

Wenn hingegen die const Variable außerhalb der Funktion deklariert, dann 
landet die ohne Umwege im Flash.

von (prx) A. K. (prx)


Lesenswert?

Markus Müller schrieb:

> Wenn man in einer Funktion eine const Variable habt, so erzeugt der GCC
> einen Code für die Initialisierung der const Variable.

Ausser man verziert diese Variable mit "static".

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Vielen Dank nochmal für die ausführlichen Infos. Ich habe bisher eben 
nur mit 8051, TMS320C25 , AVRs und 8048 gearbeitet, alles MC/DSP mit 
getrennten Adressräumen, wobei ich die TMS,51er und 48er nur in 
Assembler bearbeitet habe. C bisher nur auf Linux, Windows und AVRs. Bei 
Linux und Windows nimmt man ja dann eh 'const' , die haben aber kein 
Flash, hehe.
Schön, das es so einfach ist, was ja auch bedeutet, das Zugriffe auf 
solche Konstanten oder eben Variablen im RAM gar keine Kunstgriffe 
brauchen.

von (prx) A. K. (prx)


Lesenswert?

Matthias Sch. schrieb:

> Linux und Windows nimmt man ja dann eh 'const' , die haben aber kein
> Flash, hehe.

Aber sie haben ggf. RAM-Bereiche, die von der Anwendung nicht 
beschrieben werden können. Was ungefähr aufs Gleiche rausläuft.

von Peter II (Gast)


Lesenswert?

Roland H. schrieb:
> Im
> Gegensatz zu PROGMEM Strings kann der GCC die "normalen" const Strings
> optimieren. D. h. gleiche Strings sind nur 1x im Flash, und Teilstrings
> ebenso: "Hallo, Welt" und "Welt" belegt nur den Platz, den "Hallo, Welt"
> benötigt. Hängt vom Optimierungslevel ab.
wie soll das denn gehen? In C sind muss doch ein 0 byte am ende stehen, 
sonst kommt keine stringfunktion damit klar.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Beim Beispiel "Hallo, Welt\0" und "Welt\0" geht das ja auch, was nicht 
geht, ist ein separates "Hallo\0".

von Peter II (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Beim Beispiel "Hallo, Welt\0" und "Welt\0" geht das ja auch, was nicht
> geht, ist ein separates "Hallo\0".
ok, hatte irgendwie gelesen das "Hallo" einzeln steht. Anders rum macht 
es schon mehr sinn.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

A. K. schrieb:
> Markus Müller schrieb:
>
>> Wenn man in einer Funktion eine const Variable habt, so erzeugt der GCC
>> einen Code für die Initialisierung der const Variable.
>
> Ausser man verziert diese Variable mit "static".

Nee, ging auch nicht nicht.

Ich hatte ein Array mit 10KB, der Compiller machte daraus 50KB mehr 
Flash-Verbrauch.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Markus Müller schrieb:
> Wenn man in einer Funktion eine const Variable habt, so erzeugt der GCC
> einen Code für die Initialisierung der const Variable.

Das kapier ich ja nun gar nicht. Also entweder hast du sowas hier :
1
void printword(const u16 data)
2
{
3
  printbyte(data >> 8);
4
  printbyte((u8)data);
5
}
Was der Funktion ja nur sagt, das sie an der Variable 'data' nichts 
verändern soll, oder sowas:
1
int hex2int(char * hexcode)
2
{
3
const char hextable[18] = "0123456789ABCDEF";
4
unsigned char i,b;
5
int c;
6
char *k;
7
b = strlen(hexcode);
8
c = 0;
9
for (i = 0; i < b; i++){
10
  k = strchr(hextable,hexcode[i]);
11
  if (!k) return 0;
12
// wild pointer arithmetics . Note that this might only work in GCC
13
  c += (pow16(b-i-1) * (k - hextable));
14
  }
15
return c;
16
}
Wo ich halt nur möchte, das 'hextable' im Flash landet. ( Was es 
übrigens tut, ich hab mir die Atollic Linkerskripts angeschaut).
In beiden Fällen sollte der Compiler nix initialisieren dürfen/müssen.

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
Noch kein Account? Hier anmelden.