Forum: Mikrocontroller und Digitale Elektronik Flash und "const"


von Robert B. (rsb89)


Lesenswert?

Wenn ich in C vor eine Variable "const" schreibe bedeutet das ja, dass 
diese nicht verändert werden darf/kann (wird quasi zu einer Konstanten). 
Wenn ich das bei der uC-Programmierung mache, so habe ich gehört, packt 
der Compiler diese Konstante in den Flash. Ist richtig?
Mein Compiler von GNU für Arm-Prozessoren (arbeite mit dem LPC1768) 
macht es, bei einigen aber nicht bei allen. Warum? Kann ich das 
irgendwie beeinflussen?

von Karl H. (kbuchegg)


Lesenswert?

R. B. schrieb:
> Wenn ich in C vor eine Variable "const" schreibe bedeutet das ja, dass
> diese nicht verändert werden darf/kann (wird quasi zu einer Konstanten).
> Wenn ich das bei der uC-Programmierung mache, so habe ich gehört, packt
> der Compiler diese Konstante in den Flash. Ist richtig?

Kommt auf den Compiler an.
Kann man so nicht allgemein sagen.

Näheres weiß die Doku zu deinem Compiler.

> Warum?
Weil C eine genormte Sprache ist, die vom µC bis zum Grossrechner mit 
seinem genormten Teilen überall gleich funktioniert. Und die ISO-Norm 
hat zum Thema Flash nichts zu sagen, weil sie nicht davon ausgehen kann, 
dass JEDER Computer über ein Flash verfügt.
Daher obliegt das deinem Compilerbauer, die Freiheiten, die ihm die Norm 
lässt, in der jeweiligen Situation auszunutzen bzw. sinnvoll 
einzusetzen. Und für den einen bedeutet das eben "const kommt ins Flash" 
und für den anderen bedeutet es das nicht.
Die Norm beschreibt lediglich, wie sich das Programm bei Verwendung des 
Schlüsselwortes 'const' zu verhalten hat, aber nicht wie das zu 
implementieren ist.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

const ist eigentlich nur dazu da, dass der Compiler ne Warnung ausgibt 
wenne doch mal schreibend darauf zugreifst.
Wie bereits gemerkt, wirds unterschiedlich behandelt.

Beim AVR-GCC zB muss man noch PROGMEM dahinter schreiben.

-> Also mal in der Doku gucken.

von Robert B. (rsb89)


Lesenswert?

Ich verwende den GCC 4.6 (nur zur Info, ich such schon die Doku ;))

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin Wende schrieb:
> Beim AVR-GCC zB muss man noch PROGMEM dahinter schreiben.

Das ist eine Spezialität, die der Harvard-Architektur des AVR geschuldet 
ist. Normale von-Neumann-Systeme brauchen so etwas nicht (und 
entsprechend auch nicht die progmem.h-Klimmzüge).

von Robert B. (rsb89)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Normale von-Neumann-Systeme brauchen so etwas nicht

Weißt du denn, wie es dann gehen könnte? Also ich möchte gern dem 
Compiler überlassen wohin er es in den Flash schreibt.

von Michael H. (michael_h45)


Lesenswert?

Martin Wende schrieb:
> const ist eigentlich nur dazu da, dass der Compiler ne Warnung ausgibt
> wenne doch mal schreibend darauf zugreifst.
käse.
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html#Function-Attributes

von Michael H. (michael_h45)


Lesenswert?

R. B. schrieb:
> Weißt du denn, wie es dann gehen könnte? Also ich möchte gern dem
> Compiler überlassen wohin er es in den Flash schreibt.
Poste doch mal ein Beispiel, wann eine const-Variable (auf deiner 
Maschine) nicht im Flash landet.

von Robert B. (rsb89)


Lesenswert?

1
typedef const struct{
2
   char sms_sent[100];
3
}log_file_t;
4
5
const   log_file_t  log_file;

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Probier mal

typedef const struct{
   const char sms_sent[100];
}log_file_t;

Mit Deiner Definition sagst Du nur, das der Pointer nihct beschrieben 
werden darf...

von Der (Gast)


Lesenswert?

Es kann Sinn machen, const Variable nicht ins Flash zu schreiben: µCs 
mit einer sehr hohen CPU Frequenz können nicht mit voller 
Geschwindigkeit aus dem Flash lesen sondern verlangsamen den Zugriff 
durch Waitstates. Eine Const-Variable im RAM kann dagegen ohne 
Waitstates gelesen werden.

von Bronco (Gast)


Lesenswert?

R. B. schrieb:
> Mein Compiler von GNU für Arm-Prozessoren (arbeite mit dem LPC1768)
> macht es, bei einigen aber nicht bei allen. Warum? Kann ich das
> irgendwie beeinflussen?

Kann damit zusammenhängen, daß manche CPUs bei Datenzugriffen schneller 
im RAM arbeiten als im Flash.
Beim TriCore ist es so, daß Datenzugriffe ins Flash deutlich mehr Zyklen 
brauchen als ins RAM, daher wird der TriCore schneller, wenn Konstanten 
im RAM liegen. Vorausgesetzt es ist genug RAM vorhanden.
Wie's bei Deinem ARM ist, weiß ich nicht.

von Johnny B. (johnnyb)


Lesenswert?

Man kann es ja einfach ausprobieren mit einem simplen "const" und dann 
im erzeugten memory map (evtl. *.map) nachschauen, wo die Konstante 
hingelegt wird.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

R. B. schrieb:
> Rufus Τ. Firefly schrieb:
>> Normale von-Neumann-Systeme brauchen so etwas nicht
>
> Weißt du denn, wie es dann gehen könnte? Also ich möchte gern dem
> Compiler überlassen wohin er es in den Flash schreibt.

Na dann überlass es dem Compiler :-)

mit const i = 3;

wird er i nach .rodata legen, zumindest bei ELF Targets, und die 
Implementierung wird .rodata in den Flash lokatieren, wenn das 
praktikabel ist.

Ausnahmen bei GCC ist const volatile, das per Default nicht nach .rodata 
gelegt wird, wo es aber je nach Anwendung hingehört.

von Robert B. (rsb89)


Lesenswert?

Das Problem ist gelöst! Der Compiler mochte es anscheinend nicht, wenn 
bei der Definition der Konstanten kein Wert festgelegt wurde.

Also so läuft es jetzt bei mir:
1
typedef const struct{
2
   const char sms_sent[100];
3
}log_file_t;
4
5
const   log_file_t  log_file={{'\0'}};

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

R. B. schrieb:
> Also so läuft es jetzt bei mir:

Und welchen Sinn hat eine Konstante mit diesem Inhalt?

Ist ja nicht so, daß Du diese Konstante ohne größeren Aufwand zur 
Laufzeit ändern könntest, ist schließlich 'ne Konstante.

Was hast Du damit vor?

von Coder (Gast)


Lesenswert?

Versuch mal den Optimierer einzuschalten.

von Robert B. (rsb89)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Was hast Du damit vor?

Also im Prinzip möchte ich damit Speicherplatz auf dem Flash reservieren 
um später mit einer CopyRAMToFlash-Fkt. darauf zu schreiben und den mit 
dem Namen ansprechen zu können. Vorher war es zum teil so, dass der 
Compiler etwas auf den Flash gelegt hat und ich über direkte 
Addressierung ebenfalls. Fand ich aber keine saubere Lösung und so 
(hoffe ich) entscheidet der Compiler wo er was hinlegt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hmm. Naja, das kann man dann tatsächlich so machen.

Allerdings hast Du dann keine Kontrolle darüber, wo im Flash das so 
erzeugte Objekt liegt, und ob es beispielsweise über eine Grenze 
zwischen zwei Flash-Segmente hinausreicht, was beim Beschreiben wiederum 
zu Problemen bzw. Mehraufwand führt.

von Robert B. (rsb89)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Hmm. Naja,...

Bin offen für andere Vorschläge =)

von Robert B. (rsb89)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Allerdings hast Du dann keine Kontrolle darüber, wo im Flash das so
> erzeugte Objekt liegt,

Brauche ich doch nicht, solange ich es über den Namen ansprechen kann.

>ob es beispielsweise über eine Grenze zwischen zwei Flash-Segmente hinausreicht,
>was beim Beschreiben wiederum zu Problemen bzw. Mehraufwand führt.

Auf dieses Problem bin ich gerade gestoßen... :-/

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich würde die letzte(n) Page(s) für sowas nutzen.  Du musst dann
halt nur drauf achten, dass deine Speicherbelegung durch das reguläre
Programm nicht größer wird als bis dahin.

von xfr (Gast)


Lesenswert?

Vielleicht kann man dem Compiler ja sagen, welchen Bereich im Flash er 
nutzen darf und welchen nicht.

Die Lösung mit der Null-Konstante ist imo Murks, zumal ja nicht mal 
garantiert ist, dass der Compiler die Konstante in den Flash legt. Er 
könnte sie sogar wegoptimieren. Da müssten dann schon noch Attribute 
dazu, die das Anlegen im Flash erzwingen. Wenn man aber eh am Compiler 
vorbei auf den Flash zugreift, kann man auch den Ort selber festlegen.

von Michael H. (michael_h45)


Lesenswert?

Hm... Wieso sollte man das so im Flash ablegen wollen?

Wenn du für den Prototypen keinen Platz hergeben willst, initalisier ihn 
als Pointer mit Array-Größe 0 und hol dir dann den Platz, den du 
wirklich brauchst mit einem malloc.

Oder wenn du Daten aus dem Flash holen willst, legst du einen Pointer 
auf die Struktur an, dessen Startadresse im Flash liegt und springst 
dann jeweils um eine Struktur-Größe weiter.
Du musst dir dann nur noch hinterlegen, wie viele Sätze du im Flash 
liegen hast.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Mittels des Linker-Scripts kann man angeben welche Teile wo landen 
sollen. Auch wird dort angegeben welche RAM und Flash Bereiche es gibt. 
So könnte man das vorhandene Flash im Linker Script dann einfach 
aufteilen in zwei Sektionen. Den zweiten Bereich verwendet man dann eben 
für diese Daten. Dadurch lässt sich genau festlegen an welcher Adresse 
dieser Bereich liegt.

Einfach mal die Doku zum Gnu ld ansehen, und in das vorhandene 
Linker-Script des eigene Projektes schauen. So müsste z.B. eine MEMORY 
Definition dort sein. Hier mal ein Beispiel:

MEMORY
{
  ram    : ORIGIN = 0x40000000, LENGTH = 64K
  flash  : ORIGIN = 0x80000000, LENGTH = 1M
}

Nun könnte man "flash" aufteilen:

MEMORY
{
  ram    : ORIGIN = 0x40000000, LENGTH = 64K
  flash  : ORIGIN = 0x80000000, LENGTH = 1000K
  sms    : ORIGIN = 0x800FA000, LENGTH = 24K
}

Unter SECTIONS könnte man dann z.B.:


.sms_data :
{
    *(.text.sms_data)
} >sms
. = ALIGN(4);

Dies sagt dem Linker das die Sachen mit dem Attribut "sms_data" dann im 
MEMORY Bereich mit dem Namen "sms" liegen.

Eigentlich könnte man dann über:

typedef const struct
{
   const char sms_sent[100];
} log_file_t;

const   log_file_t  log_file _attribute_ ((section ("sms_data")));

dem Compiler/Linker sagen das es dann auch in diese Sektion gelegt 
werden soll. Siehe auch: 
http://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Variable-Attributes.html

Somit hat man den Bereich dann sauber festgelegt. Mittels der Änderungen 
im Linker-Script wird es immer an der gleichen Adresse platziert, und da 
der Bereich dort auch explizit nur für sms_data ausgewiesen ist wird 
dort auch kein Programcode abgelegt.

Grüße,

Chris



Grüße,

Chris

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.