Forum: Mikrocontroller und Digitale Elektronik STM32F4 Variable nicht initialisieren


von Frank (Gast)


Lesenswert?

Hallo zusammen

Ich verwende das STM32F4 Discovery.
Nach dem Reset will ich dass eine Variable nicht initialisiert wird.
Kann mir jemand sagen wie das geht.

Gruß´Frank

von icke (Gast)


Lesenswert?

Du willst also, dass der Wert vor und nach dem Reset einer Variable 
gleich ist?
Dann schreib ihn in den nicht flüchtigen Speicher und les ihm beim 
starten ein.

von Roland (Gast)


Lesenswert?

Schau mal in die Doku zum Kern/Kompiler. Da gibt es sicher einen 
Schlüssel (wie "noinit") mit welchem man die Initialisierung der 
entsprechenden Variablen restriktiv unterbinden kann.

Normalerweise erzeugt (nur Global) ein
 int Variable;
eine nicht initialisierte Variable. Um sie mit '0' zu initialisieren 
muss man
 int Variable=0;
definieren.

Lokale Variablen sind immer nicht initialisiert.

von Frank (Gast)


Lesenswert?

und wie mach ich das

von Frank (Gast)


Lesenswert?

>Schau mal in die Doku zum Kern/Kompiler. Da gibt es sicher einen
>Schlüssel (wie "noinit") mit welchem man die Initialisierung der
>entsprechenden Variablen restriktiv unterbinden kann.

hab ich versucht aber ich kenn di syntax nicht und google will auch net.

volatile double MyValue__attribute__((section(".noinit")));

von Arne (Gast)


Lesenswert?

Roland schrieb:

> Normalerweise erzeugt (nur Global) ein
>  int Variable;
> eine nicht initialisierte Variable.

Das ist ja wohl absoluter Blödsinn!

http://home.htw-berlin.de/~junghans/cref/SYNTAX/glo_int_vars.html
http://www.tutorials.at/c/02-variablen-konstanten-zuweisung.html

Zum TO: der STM32F1xx hat ein paar Byte NVRAM, der STM32F4xx sicher 
auch, oder?

von (prx) A. K. (prx)


Lesenswert?

Arne schrieb:
> Zum TO: der STM32F1xx hat ein paar Byte NVRAM, der STM32F4xx sicher
> auch, oder?

Genauer: RAM, das zusammen mit der RTC separat versorgt werden kann.

Frank schrieb:
> Nach dem Reset will ich dass eine Variable nicht initialisiert wird.
> Kann mir jemand sagen wie das geht.

GCC: Variable in eine separate Section legen (siehe GCC Attributes) und 
die im Linker-Script ausserhalb der initialisierten Daten platzieren.

von Frank (Gast)


Lesenswert?

Danke für die Info hat leider mein ziel noch nicht erreicht.
Ich verwende CooCox IDE.

von ♪Geist (Gast)


Lesenswert?

Geht ganz einfach, check mal beim Hochfahren der Firmware ob zuvor ein 
Reset ausgelöst wurde oder nicht. Wenn ja, initialisiert die Variable 
nicht. Stichwörter für dich: RCC_CSR Register + PINRSTF Flag

von Frank (Gast)


Lesenswert?

Mein Problem ist dass die Variable beim Reset immer initialisiert wird.

Grund: Wenn der Watchdog anspricht muss das Programm an der Stelle 
weiterlaufen wo es gestoppt wurde. Also will ich einen Definierten wert 
in der Rutine haben während sie durchlaufen wird. Ähnlich dem Warmstart 
von Windows.

von (prx) A. K. (prx)


Lesenswert?

Dann wirfst du mal eine Blick in die Referenz und findest dort:
- getrennt vom normalen SRAM noch 4KB Backup-SRAM,
- getrennt davon nochmal 80 Byte Backup-Register in der RTC.
Diese beiden Speicher werden vom Startup in Frieden gelassen.

von Frank (Gast)


Lesenswert?

Und wie leg ich die Variable dorthin?.

von (prx) A. K. (prx)


Lesenswert?

Wie greifst du auf ein Timer-Register zu? Mit den Backup-Registern geht 
es genauso. In irgendeinem Include-File stegt ein Name dazu. Evtl. gibts 
auch was in der Lib, aber die ist nicht meine Baustelle.

Beachte, dass Zugriff auf die Backup-Domain nach Reset u.U. erst 
freigeschaltet werden muss.

: Bearbeitet durch User
von Karl (Gast)


Lesenswert?

Das ist kein Thema des Controllers und dessen Peripherie, und auch 
keines der verwendeten Toolchain oder IDE, sondern des Startup-Codes. 
Initialisieren und nicht-Initialisieren ist Aufgabe des Programmierers 
(auch, wenn das eine nicht sonderlich bekannte Tatsache zu sein 
scheint). Es gibt keine allgemeingültige Lösung.

Bei den Cortex-M muss man dazu noch nicht einmal eine einzige Zeile 
Assembler schreiben. Geht alles in C.

von (prx) A. K. (prx)


Lesenswert?

Karl schrieb:
> Das ist kein Thema des Controllers und dessen Peripherie,

Es gibt mehrere Wege nach ROM. Man kann das mit diesen Backup-Registern 
oder -SRAM machen...

> sondern des Startup-Codes.

...ohne sich mit nicht so ganz anfängertauglichen Spitzfindigkeiten der 
Entwicklungumgebung rumärgern zu müssen. Jedem wie es ihm pläsiert.

von Jürgen (jliegner)


Lesenswert?

Du kannst auch einfach im Linkerscript den RAM-Anfang nach hinten 
schieben.
Beispiel für STM32F103xx

MEMORY
{
  /* Define each memory region */
  Flash (rx) : ORIGIN = 0x08000000, LENGTH = 0x00020000
  Ram  (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00002000
}

ändern in:

MEMORY
{
  /* Define each memory region */
  Flash (rx) : ORIGIN = 0x08000000, LENGTH = 0x00020000
  Ram  (rwx) : ORIGIN = 0x20000000+0x10, LENGTH = 0x00002000-0x10
}


Damit sollten ersten 16 Byte von der Initialisierung durch den 
Startup-Code ausgeschlossen sein.
Im Code kannst du dann einen Pointer anlegen um auf die Daten 
zuzugreifen.

uint8_t *pUi=(uint8_t *)0x20000000;

uint8_t u0=pUi[0];
...

Was der Controller selbst beim Reset mit dem RAM macht weiss ich jetzt 
nicht genau. Ich gehe mal davon aus, dass der den lässt wie er ist. Auf 
einem LPC1769 habe ich das mal mit Erfolg probiert.

Natürlich ist die Zuweisung eines eigenen Segmentes für diesen Zweck die 
bessere weil sauberere Lösung, das Verschieben der RAM-Grenzen ist aber 
am Anfang Überschaubarer. Vor allem wenn das Linkerscript als 
Eierlegendewollmilchsau von einer Entwicklungsumgebung stammt.

von Roland (Gast)


Lesenswert?

Den Linker-Script zu ändern ist bestenfalls ein "Würgaround". Besser ist 
es Compiler-Pragmas zu verwenden, um den Init-Script von dem gewünschten 
Variablen fern zu halten.
Leider ist die Webseite der vom OP verwendeten Suite eher was für 
Augenkrebs, als für Informationen. Ein Kompiler-Handbuch war dort nicht 
zu finden.

@Arne: So sehr "absoluter Blödsinn" ist die von mir beschriebene 
Initialisierung von Variablen wohl doch nicht:
http://public.beuth-hochschule.de/~kempfer/skript_c/Kap03.html

Mal ganz davon abgesehen, dass ich programmieren damals nach MISRA 
gelernt habe. Da stellen sich solche Diskussionen gleich gar nicht. Da 
wird jede Variable von Hand initialisiert. Wenn die Initialisierung 
redunant zum Boot-Script ist, optimiert der Kompiler es eh weg.

von Steffen R. (steffen_rose)


Lesenswert?

CooCox ist Eclipse mit gcc für einfachere Benutzung aufbereitet.

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.