STM32 - wo landen Konstanten

OP (Firma: matzetronics) #2524758
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.
#2524907
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.
#2524928
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.
OP (Firma: matzetronics) #2524948
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.
Gast #2524957
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.
OP (Firma: matzetronics) #2526527
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.

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