STM32F4 Variable nicht initialisieren

Gast #3357229
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.
Gast #3357235
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")));
#3357582
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.
Gast #3357793
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
Gast #3357856
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.
#3357897
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.
Gast #3357915
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.
#3357924
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.
#3357971
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.
Gast #3365890
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.

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