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
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.
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.
>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")));
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?
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.
Danke für die Info hat leider mein ziel noch nicht erreicht. Ich verwende CooCox IDE.
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
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.
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.
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
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.